@raindrop-ai/ai-sdk 0.3.2 → 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,8 @@
1
1
  'use strict';
2
2
 
3
3
  var async_hooks = require('async_hooks');
4
+ var child_process = require('child_process');
5
+ var path = require('path');
4
6
 
5
7
  // src/index.node.ts
6
8
 
@@ -66,7 +68,574 @@ function evalScopeAttributes() {
66
68
  return { [EVAL_CORRELATION_ID_ATTRIBUTE]: scope.correlationId };
67
69
  }
68
70
 
69
- // ../core/dist/chunk-T53LQAH7.js
71
+ // ../core/dist/chunk-WJOR6M7H.js
72
+ var STATE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.replayTraceRoutingState");
73
+ function state() {
74
+ const holder = globalThis;
75
+ let current = holder[STATE_KEY];
76
+ if (!current) {
77
+ let storage = null;
78
+ try {
79
+ const Ctor = globalThis.RAINDROP_ASYNC_LOCAL_STORAGE;
80
+ if (Ctor) storage = new Ctor();
81
+ } catch (e) {
82
+ storage = null;
83
+ }
84
+ current = {
85
+ storage,
86
+ syncDestination: void 0,
87
+ spanDestinations: /* @__PURE__ */ new WeakMap()
88
+ };
89
+ holder[STATE_KEY] = current;
90
+ }
91
+ return current;
92
+ }
93
+ function currentReplayTraceDestination() {
94
+ var _a, _b;
95
+ const routing = state();
96
+ return (_b = (_a = routing.storage) == null ? void 0 : _a.getStore()) != null ? _b : routing.syncDestination;
97
+ }
98
+ function rememberReplayTraceDestination(span) {
99
+ const destination = currentReplayTraceDestination();
100
+ if (destination) state().spanDestinations.set(span, destination);
101
+ }
102
+ function copyReplayTraceDestination(source, target) {
103
+ const destination = state().spanDestinations.get(source);
104
+ if (destination) state().spanDestinations.set(target, destination);
105
+ }
106
+ function replayTraceDestinationFor(value) {
107
+ if (typeof value !== "object" && typeof value !== "function" || value === null) {
108
+ return void 0;
109
+ }
110
+ return state().spanDestinations.get(value);
111
+ }
112
+ function recordReplayExportedSpan(destination, spanId, traceId) {
113
+ var _a, _b;
114
+ if (!destination || !spanId || !traceId) return;
115
+ (_a = destination.exportedSpanIds) == null ? void 0 : _a.add(spanId);
116
+ (_b = destination.exportedTraceIds) == null ? void 0 : _b.add(traceId);
117
+ }
118
+ function replayTraceUrl(baseUrl) {
119
+ return `${baseUrl.replace(/\/+$/, "")}/v1/traces`;
120
+ }
121
+ var NOOP_SPAN = {
122
+ traceIdB64: "",
123
+ spanIdB64: "",
124
+ eventId: "",
125
+ log() {
126
+ }
127
+ };
128
+ function getAsyncLocalStorageCtor() {
129
+ return globalThis.RAINDROP_ASYNC_LOCAL_STORAGE;
130
+ }
131
+ var SynchronousContextStorage = class {
132
+ constructor() {
133
+ this._stack = [];
134
+ }
135
+ isEmpty() {
136
+ return this._stack.length === 0;
137
+ }
138
+ getStore() {
139
+ return this._stack[this._stack.length - 1];
140
+ }
141
+ run(store, callback) {
142
+ this._stack.push(store);
143
+ try {
144
+ return callback();
145
+ } finally {
146
+ this._stack.pop();
147
+ }
148
+ }
149
+ };
150
+ var ContextManager = class {
151
+ };
152
+ var RaindropContextManager = class extends ContextManager {
153
+ constructor() {
154
+ super();
155
+ this._fallback = null;
156
+ const Ctor = getAsyncLocalStorageCtor();
157
+ if (Ctor) {
158
+ this._storage = new Ctor();
159
+ return;
160
+ }
161
+ this._fallback = new SynchronousContextStorage();
162
+ this._storage = this._fallback;
163
+ }
164
+ maybeAdoptAsyncLocalStorage() {
165
+ if (!this._fallback || !this._fallback.isEmpty()) return;
166
+ const Ctor = getAsyncLocalStorageCtor();
167
+ if (!Ctor) return;
168
+ this._storage = new Ctor();
169
+ this._fallback = null;
170
+ }
171
+ isReady() {
172
+ return true;
173
+ }
174
+ getParentSpanIds() {
175
+ this.maybeAdoptAsyncLocalStorage();
176
+ const span = this._storage.getStore();
177
+ if (!span || span === NOOP_SPAN) return void 0;
178
+ return {
179
+ traceIdB64: span.traceIdB64,
180
+ spanIdB64: span.spanIdB64,
181
+ eventId: span.eventId
182
+ };
183
+ }
184
+ runInContext(span, callback) {
185
+ this.maybeAdoptAsyncLocalStorage();
186
+ return this._storage.run(span, callback);
187
+ }
188
+ getCurrentSpan() {
189
+ this.maybeAdoptAsyncLocalStorage();
190
+ return this._storage.getStore();
191
+ }
192
+ };
193
+ var _contextManager = null;
194
+ function getContextManager() {
195
+ if (!_contextManager) {
196
+ _contextManager = globalThis.RAINDROP_CONTEXT_MANAGER ? new globalThis.RAINDROP_CONTEXT_MANAGER() : new RaindropContextManager();
197
+ }
198
+ return _contextManager;
199
+ }
200
+ function currentSpan() {
201
+ var _a;
202
+ return (_a = getContextManager().getCurrentSpan()) != null ? _a : NOOP_SPAN;
203
+ }
204
+ function withCurrent(span, callback) {
205
+ return getContextManager().runInContext(span, callback);
206
+ }
207
+ async function getCurrentParentSpanContext() {
208
+ var _a, _b;
209
+ return (_b = getContextManager().getParentSpanIds()) != null ? _b : (_a = currentReplayTraceDestination()) == null ? void 0 : _a.parentSpanContext;
210
+ }
211
+ async function runWithParentSpanContext(ctx, fn) {
212
+ const cm = getContextManager();
213
+ const span = {
214
+ traceIdB64: ctx.traceIdB64,
215
+ spanIdB64: ctx.spanIdB64,
216
+ eventId: ctx.eventId
217
+ };
218
+ return cm.runInContext(span, fn);
219
+ }
220
+ async function* asyncGeneratorWithCurrent(span, gen) {
221
+ let nextValue;
222
+ while (true) {
223
+ const result = await withCurrent(span, async () => {
224
+ try {
225
+ return await gen.next(nextValue);
226
+ } catch (e) {
227
+ return { value: void 0, done: true, error: e };
228
+ }
229
+ });
230
+ if ("error" in result && result.error !== void 0) {
231
+ throw result.error;
232
+ }
233
+ if (result.done) {
234
+ return result.value;
235
+ }
236
+ nextValue = yield result.value;
237
+ }
238
+ }
239
+ var MAX_BINDING_STACK = 128;
240
+ var EMPTY_STACK = [];
241
+ var ContextStackStorage = class {
242
+ /** Emitted once when this runtime cannot support an ambient push. */
243
+ constructor(noAmbientBindWarning) {
244
+ this.noAmbientBindWarning = noAmbientBindWarning;
245
+ this._als = null;
246
+ this._enterWithUsable = false;
247
+ this._syncStack = EMPTY_STACK;
248
+ this._adoptionChecked = false;
249
+ this._warnedNoAmbientBind = false;
250
+ }
251
+ maybeAdoptAsyncLocalStorage() {
252
+ if (this._adoptionChecked) return;
253
+ this._adoptionChecked = true;
254
+ const Ctor = getAsyncLocalStorageCtor();
255
+ if (!Ctor) return;
256
+ const als = new Ctor();
257
+ try {
258
+ als.run(EMPTY_STACK, () => {
259
+ });
260
+ } catch (e) {
261
+ return;
262
+ }
263
+ this._als = als;
264
+ if (typeof als.enterWith === "function") {
265
+ try {
266
+ als.enterWith(EMPTY_STACK);
267
+ this._enterWithUsable = true;
268
+ } catch (e) {
269
+ this._enterWithUsable = false;
270
+ }
271
+ }
272
+ }
273
+ getStack() {
274
+ var _a;
275
+ this.maybeAdoptAsyncLocalStorage();
276
+ if (this._als) return (_a = this._als.getStore()) != null ? _a : this._syncStack;
277
+ return this._syncStack;
278
+ }
279
+ /**
280
+ * Persist an ambient stack mutation. Returns false when an ALS is adopted but
281
+ * `enterWith` is unusable (workerd): callers must NOT fall back to the
282
+ * process-shared sync stack, since concurrent isolates would cross-stamp.
283
+ */
284
+ setAmbientStack(stack) {
285
+ if (this._als) {
286
+ if (!this._enterWithUsable) return false;
287
+ this._als.enterWith(stack);
288
+ return true;
289
+ }
290
+ this._syncStack = stack;
291
+ return true;
292
+ }
293
+ push(binding) {
294
+ this.maybeAdoptAsyncLocalStorage();
295
+ if (this._als && !this._enterWithUsable) {
296
+ this.warnNoAmbientBindOnce();
297
+ return;
298
+ }
299
+ let stack = this.getStack();
300
+ if (stack.length >= MAX_BINDING_STACK) {
301
+ stack = stack.filter((b) => b.isLive());
302
+ if (stack.length >= MAX_BINDING_STACK) {
303
+ stack = stack.slice(stack.length - (MAX_BINDING_STACK - 1));
304
+ }
305
+ }
306
+ this.setAmbientStack([...stack, binding]);
307
+ }
308
+ remove(binding) {
309
+ binding.markDead();
310
+ const stack = this.getStack();
311
+ const pruned = stack.filter((b) => b !== binding && b.isLive());
312
+ if (pruned.length !== stack.length) {
313
+ this.setAmbientStack(pruned);
314
+ }
315
+ }
316
+ runWith(binding, callback) {
317
+ this.maybeAdoptAsyncLocalStorage();
318
+ if (this._als) {
319
+ return this._als.run([...this.getStack(), binding], callback);
320
+ }
321
+ const previous = this._syncStack;
322
+ this._syncStack = [...previous, binding];
323
+ try {
324
+ return callback();
325
+ } finally {
326
+ this._syncStack = previous;
327
+ }
328
+ }
329
+ current() {
330
+ const stack = this.getStack();
331
+ if (stack.length === 0) return void 0;
332
+ const top = stack[stack.length - 1];
333
+ if (top.isLive()) return top;
334
+ const pruned = stack.filter((b) => b.isLive());
335
+ this.setAmbientStack(pruned);
336
+ return pruned.length > 0 ? pruned[pruned.length - 1] : void 0;
337
+ }
338
+ warnNoAmbientBindOnce() {
339
+ if (this._warnedNoAmbientBind) return;
340
+ this._warnedNoAmbientBind = true;
341
+ console.warn(this.noAmbientBindWarning);
342
+ }
343
+ };
344
+ 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.";
345
+ var ROUTING_STORAGE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.routingContextStorage");
346
+ function routingStorage() {
347
+ const holder = globalThis;
348
+ let storage = holder[ROUTING_STORAGE_KEY];
349
+ if (!storage) {
350
+ storage = new ContextStackStorage(NO_AMBIENT_ROUTING_BIND_WARNING);
351
+ holder[ROUTING_STORAGE_KEY] = storage;
352
+ }
353
+ return storage;
354
+ }
355
+ function currentRoutingBinding() {
356
+ const bound = routingStorage().current();
357
+ if (!bound) return void 0;
358
+ return {
359
+ projectId: bound.projectId,
360
+ authHint: bound.authHint,
361
+ ...bound.appGit ? { appGit: bound.appGit } : {},
362
+ ...bound.appGitSource ? { appGitSource: bound.appGitSource } : {}
363
+ };
364
+ }
365
+ var APP_COMMIT_SHA = "raindrop.app.commit_sha";
366
+ var APP_COMMIT_DIRTY = "raindrop.app.commit_dirty";
367
+ var APP_BRANCH = "raindrop.app.branch";
368
+ var APP_GIT_KEYS = [APP_COMMIT_SHA, APP_COMMIT_DIRTY, APP_BRANCH];
369
+ var own = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
370
+ function appGitExplicitKeys(properties) {
371
+ const keys = /* @__PURE__ */ new Set();
372
+ if (!properties) return keys;
373
+ for (const key of APP_GIT_KEYS) {
374
+ if (own(properties, key)) keys.add(key);
375
+ }
376
+ return keys;
377
+ }
378
+ function mergeAppGitSnapshot(base, properties, explicitKeys = /* @__PURE__ */ new Set()) {
379
+ try {
380
+ const result = { ...base };
381
+ if (properties && own(properties, APP_COMMIT_SHA) && properties[APP_COMMIT_SHA] !== result[APP_COMMIT_SHA]) {
382
+ if (!explicitKeys.has(APP_COMMIT_DIRTY) && !own(properties, APP_COMMIT_DIRTY)) {
383
+ delete result[APP_COMMIT_DIRTY];
384
+ }
385
+ if (!explicitKeys.has(APP_BRANCH) && !own(properties, APP_BRANCH)) {
386
+ delete result[APP_BRANCH];
387
+ }
388
+ }
389
+ for (const key of APP_GIT_KEYS) {
390
+ if (properties && own(properties, key)) result[key] = properties[key];
391
+ }
392
+ return Object.freeze(result);
393
+ } catch (e) {
394
+ return Object.freeze({});
395
+ }
396
+ }
397
+ function validAppCommitSha(value) {
398
+ if (typeof value !== "string" || value.length > 128) return void 0;
399
+ const cleaned = value.trim();
400
+ return /^(?:[a-fA-F0-9]{40}|[a-fA-F0-9]{64})$/.test(cleaned) ? cleaned.toLowerCase() : void 0;
401
+ }
402
+ function shortString(value) {
403
+ if (typeof value !== "string" || value.length > 1024) return void 0;
404
+ const cleaned = value.trim();
405
+ return cleaned.length > 0 ? cleaned : void 0;
406
+ }
407
+ function flag(value) {
408
+ if (value === true || value === "true" || value === "1") return true;
409
+ if (value === false || value === "false" || value === "0") return false;
410
+ return void 0;
411
+ }
412
+ function environment() {
413
+ try {
414
+ return typeof process === "undefined" ? {} : process.env;
415
+ } catch (e) {
416
+ return {};
417
+ }
418
+ }
419
+ var DEPLOYMENTS = [
420
+ ["VERCEL", "VERCEL_GIT_COMMIT_SHA", "VERCEL_GIT_COMMIT_REF"],
421
+ ["NETLIFY", "COMMIT_REF", "BRANCH"],
422
+ ["RAILWAY_ENVIRONMENT_NAME", "RAILWAY_GIT_COMMIT_SHA", "RAILWAY_GIT_BRANCH"],
423
+ ["RAILWAY_ENVIRONMENT", "RAILWAY_GIT_COMMIT_SHA", "RAILWAY_GIT_BRANCH"],
424
+ ["RENDER", "RENDER_GIT_COMMIT", "RENDER_GIT_BRANCH"],
425
+ ["DYNO", "HEROKU_BUILD_COMMIT", ""],
426
+ ["DYNO", "HEROKU_SLUG_COMMIT", ""],
427
+ ["AWS_APP_ID", "AWS_COMMIT_ID", "AWS_BRANCH"],
428
+ ["WORKERS_CI", "WORKERS_CI_COMMIT_SHA", "WORKERS_CI_BRANCH"]
429
+ ];
430
+ var CI_SOURCES = [
431
+ ["GITHUB_ACTIONS", "GITHUB_SHA", "GITHUB_REF_NAME"],
432
+ ["GITLAB_CI", "CI_COMMIT_SHA", "CI_COMMIT_REF_NAME"],
433
+ ["CIRCLECI", "CIRCLE_SHA1", "CIRCLE_BRANCH"]
434
+ ];
435
+ function detectedSource(env, table, detectBranch) {
436
+ for (const row of table) {
437
+ const [marker, shaKey, branchKey] = row;
438
+ if (!marker || !shaKey || !shortString(env[marker]) || flag(env[marker]) === false) continue;
439
+ const commitSha = validAppCommitSha(env[shaKey]);
440
+ if (commitSha)
441
+ return {
442
+ commitSha,
443
+ ...detectBranch && branchKey ? { branch: shortString(env[branchKey]) } : {}
444
+ };
445
+ }
446
+ return {};
447
+ }
448
+ var AppGitContextImpl = class {
449
+ constructor(options, runtime = {}) {
450
+ this.defaults = {};
451
+ this.explicit = {};
452
+ this.explicitKeys = /* @__PURE__ */ new Set();
453
+ this.disposed = false;
454
+ this.operations = /* @__PURE__ */ new Map();
455
+ this.operationOverflow = false;
456
+ this.detectBranch = false;
457
+ this.disabled = false;
458
+ var _a, _b, _c, _d, _e, _f;
459
+ try {
460
+ if (options === false) {
461
+ this.disabled = true;
462
+ return;
463
+ }
464
+ const opts = options != null ? options : {};
465
+ const env = (_a = runtime.env) != null ? _a : environment();
466
+ const detectBranch = (_c = (_b = flag(opts.detectBranch)) != null ? _b : flag(env.RAINDROP_GIT_DETECT_BRANCH)) != null ? _c : false;
467
+ this.detectBranch = detectBranch;
468
+ const collectBranch = detectBranch || runtime.captureLegacyReplayBranch === true;
469
+ const autoDetect = runtime.allowDiscovery === false ? false : (_e = (_d = flag(opts.autoDetect)) != null ? _d : flag(env.RAINDROP_GIT_AUTO_DETECT)) != null ? _e : true;
470
+ const configuredSha = opts.commitSha;
471
+ const explicitSha = configuredSha === void 0 ? env.RAINDROP_COMMIT_SHA : configuredSha;
472
+ if (explicitSha === null) this.explicit[APP_COMMIT_SHA] = null;
473
+ else if (typeof explicitSha === "string" && validAppCommitSha(explicitSha))
474
+ this.explicit[APP_COMMIT_SHA] = explicitSha;
475
+ const configuredDirty = opts.commitDirty;
476
+ const explicitDirty = configuredDirty === void 0 ? flag(env.RAINDROP_COMMIT_DIRTY) : configuredDirty;
477
+ if (explicitDirty === null || typeof explicitDirty === "boolean")
478
+ this.explicit[APP_COMMIT_DIRTY] = explicitDirty;
479
+ const configuredBranch = opts.branch;
480
+ const explicitBranch = configuredBranch === void 0 ? env.RAINDROP_BRANCH : configuredBranch;
481
+ if (explicitBranch === null) this.explicit[APP_BRANCH] = null;
482
+ else if (typeof explicitBranch === "string" && explicitBranch.length <= 1024)
483
+ this.explicit[APP_BRANCH] = explicitBranch;
484
+ this.explicitKeys = appGitExplicitKeys(this.explicit);
485
+ this.defaults = { ...this.explicit };
486
+ if (!autoDetect || explicitSha !== void 0) return;
487
+ const sourceDirectory = (_f = shortString(opts.sourceDirectory)) != null ? _f : shortString(env.RAINDROP_GIT_SOURCE_DIRECTORY);
488
+ if (runtime.allowLocalGit === false && !sourceDirectory) return;
489
+ const deploy = sourceDirectory ? {} : detectedSource(env, DEPLOYMENTS, collectBranch);
490
+ if (deploy.commitSha) {
491
+ this.accept(deploy);
492
+ return;
493
+ }
494
+ const fallback = sourceDirectory ? {} : detectedSource(env, CI_SOURCES, collectBranch);
495
+ if (runtime.resolveLocal && (runtime.allowLocalGit !== false || sourceDirectory)) {
496
+ this.cancel = runtime.resolveLocal(sourceDirectory, collectBranch, (result) => {
497
+ try {
498
+ if (!this.disposed) this.accept(result.commitSha ? result : fallback);
499
+ } catch (e) {
500
+ }
501
+ });
502
+ } else this.accept(fallback);
503
+ } catch (e) {
504
+ }
505
+ }
506
+ accept(result) {
507
+ const sha = validAppCommitSha(result.commitSha);
508
+ if (!sha) return;
509
+ this.replayBranch = shortString(result.branch);
510
+ this.defaults = {
511
+ [APP_COMMIT_SHA]: sha,
512
+ ...typeof result.commitDirty === "boolean" ? { [APP_COMMIT_DIRTY]: result.commitDirty } : {},
513
+ ...this.detectBranch && this.replayBranch ? { [APP_BRANCH]: this.replayBranch } : {},
514
+ ...this.explicit
515
+ };
516
+ }
517
+ snapshot(properties) {
518
+ var _a;
519
+ try {
520
+ const binding = currentRoutingBinding();
521
+ const base = this.disabled && (binding == null ? void 0 : binding.appGitSource) !== "replay-override" ? {} : (_a = binding == null ? void 0 : binding.appGit) != null ? _a : this.defaults;
522
+ return this.mergeSnapshot(base, properties);
523
+ } catch (e) {
524
+ return Object.freeze({});
525
+ }
526
+ }
527
+ /** Safe defaults when no operation/span start was observed; never infer identity. */
528
+ snapshotExplicit(properties, eventId) {
529
+ try {
530
+ const base = { ...this.explicit };
531
+ const operation = eventId ? this.operations.get(eventId) : void 0;
532
+ if (operation) {
533
+ for (const key of operation.explicitKeys) base[key] = operation.snapshot[key];
534
+ }
535
+ return this.mergeSnapshot(base, properties, new Set(Object.keys(base)));
536
+ } catch (e) {
537
+ return mergeAppGitSnapshot({}, properties);
538
+ }
539
+ }
540
+ /** Existing replay branch reporting stays separate from opt-in event properties. */
541
+ snapshotForReplay() {
542
+ const snapshot = this.snapshot();
543
+ if (this.replayBranch && !own(snapshot, APP_BRANCH) && snapshot[APP_COMMIT_SHA] === this.defaults[APP_COMMIT_SHA]) {
544
+ return Object.freeze({ ...snapshot, [APP_BRANCH]: this.replayBranch });
545
+ }
546
+ return snapshot;
547
+ }
548
+ /** Merge a frozen span snapshot without losing client-authored provenance. */
549
+ mergeSnapshot(base, properties, explicitKeys = this.explicitKeys) {
550
+ return mergeAppGitSnapshot(base, properties, /* @__PURE__ */ new Set([...this.explicitKeys, ...explicitKeys]));
551
+ }
552
+ /** Shippers belonging to one client share this bounded operation registry. */
553
+ forOperation(eventId, properties, owner) {
554
+ if (!eventId) return this.snapshot(properties);
555
+ let operation = this.operations.get(eventId);
556
+ if (!operation) {
557
+ if (this.operations.size >= 1e4) this.operationOverflow = true;
558
+ if (this.operationOverflow) return this.mergeSnapshot({}, properties);
559
+ operation = {
560
+ snapshot: this.snapshot(properties),
561
+ owners: /* @__PURE__ */ new Set(),
562
+ unowned: owner === void 0,
563
+ explicitKeys: appGitExplicitKeys(properties)
564
+ };
565
+ this.operations.set(eventId, operation);
566
+ } else if (properties && APP_GIT_KEYS.some((key) => own(properties, key))) {
567
+ const explicitKeys = /* @__PURE__ */ new Set([...this.explicitKeys, ...operation.explicitKeys]);
568
+ operation.snapshot = this.mergeSnapshot(operation.snapshot, properties, explicitKeys);
569
+ for (const key of appGitExplicitKeys(properties)) operation.explicitKeys.add(key);
570
+ }
571
+ if (!owner) operation.unowned = true;
572
+ if (owner) operation.owners.add(owner);
573
+ return operation.snapshot;
574
+ }
575
+ releaseOperation(eventId, owner) {
576
+ const operation = this.operations.get(eventId);
577
+ if (!operation) return;
578
+ operation.owners.delete(owner);
579
+ if (operation.owners.size === 0 && !operation.unowned) this.operations.delete(eventId);
580
+ }
581
+ finishOperation(eventId) {
582
+ this.operations.delete(eventId);
583
+ }
584
+ dispose() {
585
+ var _a;
586
+ this.disposed = true;
587
+ try {
588
+ (_a = this.cancel) == null ? void 0 : _a.call(this);
589
+ } catch (e) {
590
+ }
591
+ }
592
+ };
593
+ var AppGitContext = AppGitContextImpl;
594
+ function createAppGitContext(options, runtime = {}) {
595
+ return new AppGitContext(options, runtime);
596
+ }
597
+ function withAppGitProperties(properties, snapshot) {
598
+ try {
599
+ const merged = { ...properties };
600
+ for (const key of APP_GIT_KEYS)
601
+ if (!own(merged, key) && own(snapshot, key)) merged[key] = snapshot[key];
602
+ return merged;
603
+ } catch (e) {
604
+ return properties != null ? properties : {};
605
+ }
606
+ }
607
+ function withAppGitAttributes(attributes, snapshot) {
608
+ try {
609
+ const present = new Set(attributes.flatMap((attr) => attr ? [attr.key] : []));
610
+ const added = [];
611
+ for (const key of APP_GIT_KEYS) {
612
+ if (present.has(key) || present.has(`ai.telemetry.metadata.${key}`) || present.has(`traceloop.association.properties.${key}`))
613
+ continue;
614
+ const value = snapshot[key];
615
+ if (typeof value === "string") added.push({ key, value: { stringValue: value } });
616
+ else if (typeof value === "boolean") added.push({ key, value: { boolValue: value } });
617
+ }
618
+ return added.length ? [...attributes, ...added] : attributes;
619
+ } catch (e) {
620
+ return attributes;
621
+ }
622
+ }
623
+ function appGitPropertiesFromAttributes(attributes) {
624
+ var _a, _b, _c;
625
+ const properties = {};
626
+ try {
627
+ for (const attr of attributes) {
628
+ if (!attr) continue;
629
+ for (const key of APP_GIT_KEYS) {
630
+ if (attr.key === key || attr.key === `ai.telemetry.metadata.${key}` || attr.key === `traceloop.association.properties.${key}`) {
631
+ properties[key] = (_c = (_b = (_a = attr.value.stringValue) != null ? _a : attr.value.boolValue) != null ? _b : attr.value.intValue) != null ? _c : null;
632
+ }
633
+ }
634
+ }
635
+ } catch (e) {
636
+ }
637
+ return properties;
638
+ }
70
639
  function normalizeFeatureFlags(input) {
71
640
  if (Array.isArray(input)) {
72
641
  return Object.fromEntries(input.map((name) => [name, "true"]));
@@ -451,7 +1020,7 @@ function runWithTracingSuppressed(fn) {
451
1020
  var DEFAULT_REQUEST_TIMEOUT_MS = 3e4;
452
1021
  var MAX_RETRY_DELAY_MS = 3e4;
453
1022
  function wait(ms) {
454
- return new Promise((resolve) => setTimeout(resolve, ms));
1023
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
455
1024
  }
456
1025
  function formatEndpoint(endpoint) {
457
1026
  if (!endpoint) return void 0;
@@ -488,9 +1057,9 @@ async function raceWithTimeout(promise, timeoutMs) {
488
1057
  () => true,
489
1058
  () => true
490
1059
  ),
491
- new Promise((resolve) => {
1060
+ new Promise((resolve2) => {
492
1061
  var _a;
493
- timer = setTimeout(() => resolve(false), Math.max(0, timeoutMs));
1062
+ timer = setTimeout(() => resolve2(false), Math.max(0, timeoutMs));
494
1063
  (_a = timer.unref) == null ? void 0 : _a.call(timer);
495
1064
  })
496
1065
  ]);
@@ -685,55 +1254,6 @@ function buildExportTraceServiceRequest(spans, serviceName = "raindrop.core", se
685
1254
  ]
686
1255
  };
687
1256
  }
688
- var STATE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.replayTraceRoutingState");
689
- function state() {
690
- const holder = globalThis;
691
- let current = holder[STATE_KEY];
692
- if (!current) {
693
- let storage = null;
694
- try {
695
- const Ctor = globalThis.RAINDROP_ASYNC_LOCAL_STORAGE;
696
- if (Ctor) storage = new Ctor();
697
- } catch (e) {
698
- storage = null;
699
- }
700
- current = {
701
- storage,
702
- syncDestination: void 0,
703
- spanDestinations: /* @__PURE__ */ new WeakMap()
704
- };
705
- holder[STATE_KEY] = current;
706
- }
707
- return current;
708
- }
709
- function currentReplayTraceDestination() {
710
- var _a, _b;
711
- const routing = state();
712
- return (_b = (_a = routing.storage) == null ? void 0 : _a.getStore()) != null ? _b : routing.syncDestination;
713
- }
714
- function rememberReplayTraceDestination(span) {
715
- const destination = currentReplayTraceDestination();
716
- if (destination) state().spanDestinations.set(span, destination);
717
- }
718
- function copyReplayTraceDestination(source, target) {
719
- const destination = state().spanDestinations.get(source);
720
- if (destination) state().spanDestinations.set(target, destination);
721
- }
722
- function replayTraceDestinationFor(value) {
723
- if (typeof value !== "object" && typeof value !== "function" || value === null) {
724
- return void 0;
725
- }
726
- return state().spanDestinations.get(value);
727
- }
728
- function recordReplayExportedSpan(destination, spanId, traceId) {
729
- var _a, _b;
730
- if (!destination || !spanId || !traceId) return;
731
- (_a = destination.exportedSpanIds) == null ? void 0 : _a.add(spanId);
732
- (_b = destination.exportedTraceIds) == null ? void 0 : _b.add(traceId);
733
- }
734
- function replayTraceUrl(baseUrl) {
735
- return `${baseUrl.replace(/\/+$/, "")}/v1/traces`;
736
- }
737
1257
  var LOCAL_DEBUGGER_ENV_VAR = "RAINDROP_LOCAL_DEBUGGER";
738
1258
  var WORKSHOP_ENV_VAR = "RAINDROP_WORKSHOP";
739
1259
  var DEFAULT_LOCAL_WORKSHOP_URL = "http://localhost:5899/v1/";
@@ -868,6 +1388,13 @@ function projectIdHeaders(projectId) {
868
1388
  }
869
1389
  var SHUTDOWN_DEADLINE_MS = 1e4;
870
1390
  var POST_SHUTDOWN_TIMEOUT_MS = 5e3;
1391
+ function appGitOwnerId(prefix) {
1392
+ try {
1393
+ return `${prefix}:${randomUUID()}`;
1394
+ } catch (e) {
1395
+ return `${prefix}:${Date.now().toString(36)}:${Math.random().toString(36).slice(2)}`;
1396
+ }
1397
+ }
871
1398
  function mergePatches(target, source) {
872
1399
  var _a, _b, _c, _d, _e, _f, _g, _h, _i;
873
1400
  const out = { ...target, ...source };
@@ -917,22 +1444,25 @@ function eventTelemetryProperties(patch) {
917
1444
  }
918
1445
  var EventShipper = class {
919
1446
  constructor(opts) {
1447
+ this.appGitOwner = appGitOwnerId("event");
920
1448
  this.buffers = /* @__PURE__ */ new Map();
921
1449
  this.sticky = /* @__PURE__ */ new Map();
922
1450
  this.timers = /* @__PURE__ */ new Map();
923
1451
  this.inFlight = /* @__PURE__ */ new Set();
924
1452
  this.hasShutdown = false;
925
- var _a, _b, _c, _d, _e, _f, _g, _h;
926
- this.writeKey = (_a = opts.writeKey) == null ? void 0 : _a.trim();
927
- this.baseUrl = (_b = formatEndpoint(opts.endpoint)) != null ? _b : "https://api.raindrop.ai/v1/";
1453
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
1454
+ this.appGitContext = (_a = opts.appGitContext) != null ? _a : createAppGitContext(opts.appGit);
1455
+ this.ownsAppGitContext = opts.appGitContext === void 0;
1456
+ this.writeKey = (_b = opts.writeKey) == null ? void 0 : _b.trim();
1457
+ this.baseUrl = (_c = formatEndpoint(opts.endpoint)) != null ? _c : "https://api.raindrop.ai/v1/";
928
1458
  this.enabled = opts.enabled !== false;
929
1459
  this.debug = opts.debug;
930
- this.partialFlushMs = (_c = opts.partialFlushMs) != null ? _c : 1e3;
931
- this.sdkName = (_d = opts.sdkName) != null ? _d : "core";
1460
+ this.partialFlushMs = (_d = opts.partialFlushMs) != null ? _d : 1e3;
1461
+ this.sdkName = (_e = opts.sdkName) != null ? _e : "core";
932
1462
  this.prefix = `[raindrop-ai/${this.sdkName}]`;
933
- this.defaultEventName = (_e = opts.defaultEventName) != null ? _e : "ai_generation";
1463
+ this.defaultEventName = (_f = opts.defaultEventName) != null ? _f : "ai_generation";
934
1464
  this.maxTextFieldCharsOpt = opts.maxTextFieldChars;
935
- this.localDebuggerUrl = (_f = resolveLocalDebuggerBaseUrl(opts.localDebuggerUrl)) != null ? _f : void 0;
1465
+ this.localDebuggerUrl = (_g = resolveLocalDebuggerBaseUrl(opts.localDebuggerUrl)) != null ? _g : void 0;
936
1466
  if (this.debug && this.localDebuggerUrl) {
937
1467
  console.log(`${this.prefix} Local debugger mirroring: ${this.localDebuggerUrl}`);
938
1468
  }
@@ -943,8 +1473,8 @@ var EventShipper = class {
943
1473
  const isNode = typeof process !== "undefined" && typeof process.version === "string";
944
1474
  this.context = {
945
1475
  library: {
946
- name: (_g = opts.libraryName) != null ? _g : "@raindrop-ai/core",
947
- version: (_h = opts.libraryVersion) != null ? _h : "0.0.0"
1476
+ name: (_h = opts.libraryName) != null ? _h : "@raindrop-ai/core",
1477
+ version: (_i = opts.libraryVersion) != null ? _i : "0.0.0"
948
1478
  },
949
1479
  metadata: {
950
1480
  jsRuntime: isNode ? "node" : "web",
@@ -952,6 +1482,9 @@ var EventShipper = class {
952
1482
  }
953
1483
  };
954
1484
  }
1485
+ ownAppGitContextForShutdown() {
1486
+ this.ownsAppGitContext = true;
1487
+ }
955
1488
  isDebugEnabled() {
956
1489
  return this.debug;
957
1490
  }
@@ -1030,6 +1563,13 @@ var EventShipper = class {
1030
1563
  }
1031
1564
  const sticky = (_c = this.sticky.get(eventId)) != null ? _c : {};
1032
1565
  const existing = (_d = this.buffers.get(eventId)) != null ? _d : {};
1566
+ patch = {
1567
+ ...patch,
1568
+ properties: withAppGitProperties(
1569
+ patch.properties,
1570
+ this.appGitContext.forOperation(eventId, patch.properties, this.appGitOwner)
1571
+ )
1572
+ };
1033
1573
  const merged = mergePatches(existing, patch);
1034
1574
  merged.isPending = (_g = (_f = (_e = patch.isPending) != null ? _e : existing.isPending) != null ? _f : sticky.isPending) != null ? _g : true;
1035
1575
  this.buffers.set(eventId, merged);
@@ -1043,6 +1583,8 @@ var EventShipper = class {
1043
1583
  if (t) clearTimeout(t);
1044
1584
  if (merged.isPending === false) {
1045
1585
  await this.flushOne(eventId);
1586
+ if (this.appGitContext.releaseOperation) this.appGitContext.releaseOperation(eventId, this.appGitOwner);
1587
+ else this.appGitContext.finishOperation(eventId);
1046
1588
  return;
1047
1589
  }
1048
1590
  const timeout = setTimeout(() => {
@@ -1074,6 +1616,7 @@ var EventShipper = class {
1074
1616
  if (!settled) this.warnShutdownDrop("in-flight request(s) at shutdown");
1075
1617
  } finally {
1076
1618
  this.shutdownDeadlineAt = void 0;
1619
+ if (this.ownsAppGitContext) this.appGitContext.dispose();
1077
1620
  }
1078
1621
  }
1079
1622
  async trackSignal(signal) {
@@ -1508,6 +2051,13 @@ function redactJsonAttributeValue(key, value) {
1508
2051
  if (scrubbedJson === json) return void 0;
1509
2052
  return { stringValue: scrubbedJson };
1510
2053
  }
2054
+ function appGitOwnerId2(prefix) {
2055
+ try {
2056
+ return `${prefix}:${randomUUID()}`;
2057
+ } catch (e) {
2058
+ return `${prefix}:${Date.now().toString(36)}:${Math.random().toString(36).slice(2)}`;
2059
+ }
2060
+ }
1511
2061
  function identityAttrs(args) {
1512
2062
  return [
1513
2063
  attrString("ai.telemetry.metadata.raindrop.ai.userId", args.userId),
@@ -1530,23 +2080,30 @@ function applyOtelSpanAttributeLimit(limit) {
1530
2080
  }
1531
2081
  var TraceShipper = class {
1532
2082
  constructor(opts) {
2083
+ this.appGitOwner = appGitOwnerId2("trace");
2084
+ this.appGitEventIds = /* @__PURE__ */ new WeakMap();
2085
+ this.appGitActiveSpans = /* @__PURE__ */ new Map();
2086
+ this.appGitCaptured = /* @__PURE__ */ new WeakSet();
2087
+ this.appGitAdded = /* @__PURE__ */ new WeakMap();
1533
2088
  this.queue = [];
1534
2089
  this.inFlight = /* @__PURE__ */ new Set();
1535
2090
  this.hasShutdown = false;
1536
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
1537
- this.writeKey = (_a = opts.writeKey) == null ? void 0 : _a.trim();
1538
- this.baseUrl = (_b = formatEndpoint(opts.endpoint)) != null ? _b : "https://api.raindrop.ai/v1/";
2091
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
2092
+ this.appGitContext = (_a = opts.appGitContext) != null ? _a : createAppGitContext(opts.appGit);
2093
+ this.ownsAppGitContext = opts.appGitContext === void 0;
2094
+ this.writeKey = (_b = opts.writeKey) == null ? void 0 : _b.trim();
2095
+ this.baseUrl = (_c = formatEndpoint(opts.endpoint)) != null ? _c : "https://api.raindrop.ai/v1/";
1539
2096
  this.enabled = opts.enabled !== false;
1540
2097
  this.debug = opts.debug;
1541
2098
  this.debugSpans = opts.debugSpans === true;
1542
- this.flushIntervalMs = (_c = opts.flushIntervalMs) != null ? _c : 1e3;
1543
- this.maxBatchSize = (_d = opts.maxBatchSize) != null ? _d : 50;
1544
- this.maxQueueSize = (_e = opts.maxQueueSize) != null ? _e : 5e3;
1545
- this.sdkName = (_f = opts.sdkName) != null ? _f : "core";
2099
+ this.flushIntervalMs = (_d = opts.flushIntervalMs) != null ? _d : 1e3;
2100
+ this.maxBatchSize = (_e = opts.maxBatchSize) != null ? _e : 50;
2101
+ this.maxQueueSize = (_f = opts.maxQueueSize) != null ? _f : 5e3;
2102
+ this.sdkName = (_g = opts.sdkName) != null ? _g : "core";
1546
2103
  this.prefix = `[raindrop-ai/${this.sdkName}]`;
1547
- this.serviceName = (_g = opts.serviceName) != null ? _g : "raindrop.core";
1548
- this.serviceVersion = (_h = opts.serviceVersion) != null ? _h : "0.0.0";
1549
- this.localDebuggerUrl = (_i = resolveLocalDebuggerBaseUrl(opts.localDebuggerUrl)) != null ? _i : void 0;
2104
+ this.serviceName = (_h = opts.serviceName) != null ? _h : "raindrop.core";
2105
+ this.serviceVersion = (_i = opts.serviceVersion) != null ? _i : "0.0.0";
2106
+ this.localDebuggerUrl = (_j = resolveLocalDebuggerBaseUrl(opts.localDebuggerUrl)) != null ? _j : void 0;
1550
2107
  if (this.debug && this.localDebuggerUrl) {
1551
2108
  console.log(`${this.prefix} Local debugger mirroring: ${this.localDebuggerUrl}`);
1552
2109
  }
@@ -1647,7 +2204,7 @@ var TraceShipper = class {
1647
2204
  return { ...this.authHeaders(), ...projectIdHeaders(this.projectId) };
1648
2205
  }
1649
2206
  startSpan(args) {
1650
- var _a, _b;
2207
+ var _a, _b, _c;
1651
2208
  const ids = createSpanIds(args.parent);
1652
2209
  const started = (_a = args.startTimeUnixNano) != null ? _a : nowUnixNanoString();
1653
2210
  const attrs = [
@@ -1657,13 +2214,24 @@ var TraceShipper = class {
1657
2214
  ...Object.entries(evalScopeAttributes()).map(([key, value]) => attrString(key, value))
1658
2215
  ];
1659
2216
  if ((_b = args.attributes) == null ? void 0 : _b.length) attrs.push(...args.attributes);
2217
+ const tracksAppGit = this.appGitActiveSpans.has(args.eventId) || this.appGitActiveSpans.size < 1e4;
2218
+ const appGitOverrides = appGitPropertiesFromAttributes(attrs);
1660
2219
  const span = {
1661
2220
  ids,
1662
2221
  name: args.name,
1663
2222
  startTimeUnixNano: started,
1664
- attributes: attrs
2223
+ attributes: withAppGitAttributes(
2224
+ attrs,
2225
+ this.appGitContext.forOperation(args.eventId, appGitOverrides, this.appGitOwner)
2226
+ )
1665
2227
  };
1666
2228
  rememberReplayTraceDestination(span);
2229
+ this.appGitCaptured.add(span);
2230
+ this.appGitEventIds.set(span, args.eventId);
2231
+ if (tracksAppGit) {
2232
+ this.appGitActiveSpans.set(args.eventId, ((_c = this.appGitActiveSpans.get(args.eventId)) != null ? _c : 0) + 1);
2233
+ }
2234
+ this.appGitAdded.set(span, new Set(span.attributes.filter((attr) => !attrs.includes(attr))));
1667
2235
  const openSpan = buildOtlpSpan({
1668
2236
  ids: span.ids,
1669
2237
  name: span.name,
@@ -1703,11 +2271,17 @@ var TraceShipper = class {
1703
2271
  });
1704
2272
  }
1705
2273
  endSpan(span, extra) {
1706
- var _a, _b;
2274
+ var _a, _b, _c;
1707
2275
  if (span.endTimeUnixNano) return;
1708
2276
  span.endTimeUnixNano = (_a = extra == null ? void 0 : extra.endTimeUnixNano) != null ? _a : nowUnixNanoString();
1709
2277
  if ((_b = extra == null ? void 0 : extra.attributes) == null ? void 0 : _b.length) {
2278
+ const overrides = appGitPropertiesFromAttributes(extra.attributes);
2279
+ const eventId2 = this.appGitEventIds.get(span);
2280
+ const snapshot = eventId2 ? this.appGitContext.forOperation(eventId2, overrides, this.appGitOwner) : overrides;
2281
+ const added = this.appGitAdded.get(span);
2282
+ 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));
1710
2283
  span.attributes.push(...extra.attributes);
2284
+ span.attributes = withAppGitAttributes(span.attributes, snapshot);
1711
2285
  }
1712
2286
  let status = extra == null ? void 0 : extra.status;
1713
2287
  if (!status && (extra == null ? void 0 : extra.error) !== void 0) {
@@ -1723,8 +2297,19 @@ var TraceShipper = class {
1723
2297
  status
1724
2298
  });
1725
2299
  copyReplayTraceDestination(span, otlp);
2300
+ this.appGitCaptured.add(otlp);
1726
2301
  this.enqueue(otlp);
1727
2302
  this.mirrorToLocalDebugger(otlp, true);
2303
+ const eventId = this.appGitEventIds.get(span);
2304
+ if (eventId && this.appGitActiveSpans.has(eventId)) {
2305
+ const remaining = ((_c = this.appGitActiveSpans.get(eventId)) != null ? _c : 1) - 1;
2306
+ if (remaining > 0) this.appGitActiveSpans.set(eventId, remaining);
2307
+ else {
2308
+ this.appGitActiveSpans.delete(eventId);
2309
+ if (this.appGitContext.releaseOperation) this.appGitContext.releaseOperation(eventId, this.appGitOwner);
2310
+ else if (this.ownsAppGitContext) this.appGitContext.finishOperation(eventId);
2311
+ }
2312
+ }
1728
2313
  }
1729
2314
  createSpan(args) {
1730
2315
  var _a;
@@ -1735,20 +2320,41 @@ var TraceShipper = class {
1735
2320
  ...Object.entries(evalScopeAttributes()).map(([key, value]) => attrString(key, value))
1736
2321
  ];
1737
2322
  if ((_a = args.attributes) == null ? void 0 : _a.length) attrs.push(...args.attributes);
2323
+ const tracksAppGit = !this.appGitActiveSpans.has(args.eventId);
1738
2324
  const otlp = buildOtlpSpan({
1739
2325
  ids,
1740
2326
  name: args.name,
1741
2327
  startTimeUnixNano: args.startTimeUnixNano,
1742
2328
  endTimeUnixNano: args.endTimeUnixNano,
1743
- attributes: attrs,
2329
+ attributes: withAppGitAttributes(
2330
+ attrs,
2331
+ this.appGitContext.forOperation(
2332
+ args.eventId,
2333
+ appGitPropertiesFromAttributes(attrs),
2334
+ this.appGitOwner
2335
+ )
2336
+ ),
1744
2337
  status: args.status
1745
2338
  });
1746
2339
  rememberReplayTraceDestination(otlp);
2340
+ this.appGitCaptured.add(otlp);
2341
+ if (tracksAppGit) {
2342
+ if (this.appGitContext.releaseOperation) this.appGitContext.releaseOperation(args.eventId, this.appGitOwner);
2343
+ else if (this.ownsAppGitContext) this.appGitContext.finishOperation(args.eventId);
2344
+ }
1747
2345
  this.enqueue(otlp);
1748
2346
  this.mirrorToLocalDebugger(otlp, true);
1749
2347
  }
1750
2348
  enqueue(span) {
2349
+ var _a;
1751
2350
  if (!this.enabled) return;
2351
+ const attributes = (_a = span.attributes) != null ? _a : [];
2352
+ const enriched = this.appGitCaptured.has(span) ? attributes : withAppGitAttributes(attributes, this.appGitContext.snapshot(appGitPropertiesFromAttributes(attributes)));
2353
+ if (enriched !== attributes) {
2354
+ const original = span;
2355
+ span = { ...span, attributes: enriched.filter((attr) => attr !== void 0) };
2356
+ copyReplayTraceDestination(original, span);
2357
+ }
1752
2358
  if (this.debugSpans) {
1753
2359
  const short = (s) => s ? s.slice(-8) : "none";
1754
2360
  console.log(
@@ -1894,127 +2500,153 @@ var TraceShipper = class {
1894
2500
  }
1895
2501
  } finally {
1896
2502
  this.shutdownDeadlineAt = void 0;
2503
+ if (this.ownsAppGitContext) this.appGitContext.dispose();
1897
2504
  }
1898
2505
  }
1899
2506
  };
1900
- var NOOP_SPAN = {
1901
- traceIdB64: "",
1902
- spanIdB64: "",
1903
- eventId: "",
1904
- log() {
1905
- }
1906
- };
1907
- function getAsyncLocalStorageCtor() {
1908
- return globalThis.RAINDROP_ASYNC_LOCAL_STORAGE;
1909
- }
1910
- var SynchronousContextStorage = class {
1911
- constructor() {
1912
- this._stack = [];
1913
- }
1914
- isEmpty() {
1915
- return this._stack.length === 0;
1916
- }
1917
- getStore() {
1918
- return this._stack[this._stack.length - 1];
1919
- }
1920
- run(store, callback) {
1921
- this._stack.push(store);
2507
+ var resolveLocal = (sourceDirectory, detectBranch, completed) => {
2508
+ const cwd = sourceDirectory ? path.resolve(sourceDirectory) : process.cwd();
2509
+ let cancelled = false;
2510
+ let active;
2511
+ let deadlineTimer;
2512
+ const deadline = Date.now() + 1e3;
2513
+ const run = (args, done) => {
2514
+ if (cancelled) return;
2515
+ const remaining = deadline - Date.now();
2516
+ if (remaining <= 0) {
2517
+ done(void 0);
2518
+ return;
2519
+ }
1922
2520
  try {
1923
- return callback();
1924
- } finally {
1925
- this._stack.pop();
2521
+ active = child_process.execFile(
2522
+ "git",
2523
+ args,
2524
+ {
2525
+ cwd,
2526
+ encoding: "utf8",
2527
+ maxBuffer: 4096,
2528
+ windowsHide: true,
2529
+ env: {
2530
+ ...process.env,
2531
+ // The selected application cwd, not the invoking shell's Git plumbing, owns identity.
2532
+ GIT_DIR: void 0,
2533
+ GIT_WORK_TREE: void 0,
2534
+ GIT_COMMON_DIR: void 0,
2535
+ GIT_NAMESPACE: void 0,
2536
+ GIT_INDEX_FILE: void 0,
2537
+ GIT_OBJECT_DIRECTORY: void 0,
2538
+ GIT_ALTERNATE_OBJECT_DIRECTORIES: void 0,
2539
+ GIT_CONFIG_PARAMETERS: void 0,
2540
+ GIT_CONFIG_COUNT: "0",
2541
+ GIT_TERMINAL_PROMPT: "0",
2542
+ GIT_OPTIONAL_LOCKS: "0"
2543
+ }
2544
+ },
2545
+ (error, stdout) => {
2546
+ clearTimeout(deadlineTimer);
2547
+ deadlineTimer = void 0;
2548
+ active = void 0;
2549
+ if (!cancelled) {
2550
+ try {
2551
+ done(error ? void 0 : stdout.trim());
2552
+ } catch (e) {
2553
+ }
2554
+ }
2555
+ }
2556
+ );
2557
+ active.unref();
2558
+ if (active.stdout && "unref" in active.stdout && typeof active.stdout.unref === "function")
2559
+ active.stdout.unref();
2560
+ if (active.stderr && "unref" in active.stderr && typeof active.stderr.unref === "function")
2561
+ active.stderr.unref();
2562
+ deadlineTimer = setTimeout(() => {
2563
+ try {
2564
+ active == null ? void 0 : active.kill("SIGKILL");
2565
+ } catch (e) {
2566
+ }
2567
+ }, remaining);
2568
+ deadlineTimer.unref();
2569
+ } catch (e) {
2570
+ try {
2571
+ done(void 0);
2572
+ } catch (e2) {
2573
+ }
1926
2574
  }
1927
- }
1928
- };
1929
- var ContextManager = class {
1930
- };
1931
- var RaindropContextManager = class extends ContextManager {
1932
- constructor() {
1933
- super();
1934
- this._fallback = null;
1935
- const Ctor = getAsyncLocalStorageCtor();
1936
- if (Ctor) {
1937
- this._storage = new Ctor();
1938
- return;
2575
+ };
2576
+ const scheduled = setTimeout(() => {
2577
+ try {
2578
+ run(["rev-parse", "HEAD"], (rawSha) => {
2579
+ const commitSha = validAppCommitSha(rawSha);
2580
+ if (!commitSha) {
2581
+ completed({});
2582
+ return;
2583
+ }
2584
+ run(["-c", "core.fsmonitor=false", "status", "--porcelain"], (status) => {
2585
+ const finish = (branch) => {
2586
+ run(["rev-parse", "HEAD"], (finalSha) => {
2587
+ const coherent = validAppCommitSha(finalSha) === commitSha;
2588
+ completed({
2589
+ commitSha,
2590
+ ...coherent && status !== void 0 ? { commitDirty: status !== "" } : {},
2591
+ ...coherent && branch && branch !== "HEAD" ? { branch } : {}
2592
+ });
2593
+ });
2594
+ };
2595
+ if (detectBranch) run(["symbolic-ref", "--quiet", "--short", "HEAD"], finish);
2596
+ else finish();
2597
+ });
2598
+ });
2599
+ } catch (e) {
2600
+ completed({});
2601
+ }
2602
+ }, 0);
2603
+ scheduled.unref();
2604
+ return () => {
2605
+ cancelled = true;
2606
+ clearTimeout(scheduled);
2607
+ clearTimeout(deadlineTimer);
2608
+ try {
2609
+ active == null ? void 0 : active.kill("SIGKILL");
2610
+ } catch (e) {
1939
2611
  }
1940
- this._fallback = new SynchronousContextStorage();
1941
- this._storage = this._fallback;
1942
- }
1943
- maybeAdoptAsyncLocalStorage() {
1944
- if (!this._fallback || !this._fallback.isEmpty()) return;
1945
- const Ctor = getAsyncLocalStorageCtor();
1946
- if (!Ctor) return;
1947
- this._storage = new Ctor();
1948
- this._fallback = null;
1949
- }
1950
- isReady() {
1951
- return true;
1952
- }
1953
- getParentSpanIds() {
1954
- this.maybeAdoptAsyncLocalStorage();
1955
- const span = this._storage.getStore();
1956
- if (!span || span === NOOP_SPAN) return void 0;
1957
- return {
1958
- traceIdB64: span.traceIdB64,
1959
- spanIdB64: span.spanIdB64,
1960
- eventId: span.eventId
1961
- };
1962
- }
1963
- runInContext(span, callback) {
1964
- this.maybeAdoptAsyncLocalStorage();
1965
- return this._storage.run(span, callback);
1966
- }
1967
- getCurrentSpan() {
1968
- this.maybeAdoptAsyncLocalStorage();
1969
- return this._storage.getStore();
1970
- }
2612
+ };
1971
2613
  };
1972
- var _contextManager = null;
1973
- function getContextManager() {
1974
- if (!_contextManager) {
1975
- _contextManager = globalThis.RAINDROP_CONTEXT_MANAGER ? new globalThis.RAINDROP_CONTEXT_MANAGER() : new RaindropContextManager();
1976
- }
1977
- return _contextManager;
2614
+ function createAppGitContext2(options, runtime = {}) {
2615
+ return new AppGitContext(options, { ...runtime, resolveLocal });
1978
2616
  }
1979
- function currentSpan() {
2617
+ function hasDestination(options) {
1980
2618
  var _a;
1981
- return (_a = getContextManager().getCurrentSpan()) != null ? _a : NOOP_SPAN;
1982
- }
1983
- function withCurrent(span, callback) {
1984
- return getContextManager().runInContext(span, callback);
1985
- }
1986
- async function getCurrentParentSpanContext() {
1987
- var _a, _b;
1988
- return (_b = getContextManager().getParentSpanIds()) != null ? _b : (_a = currentReplayTraceDestination()) == null ? void 0 : _a.parentSpanContext;
1989
- }
1990
- async function runWithParentSpanContext(ctx, fn) {
1991
- const cm = getContextManager();
1992
- const span = {
1993
- traceIdB64: ctx.traceIdB64,
1994
- spanIdB64: ctx.spanIdB64,
1995
- eventId: ctx.eventId
1996
- };
1997
- return cm.runInContext(span, fn);
2619
+ if (options.enabled === false) return false;
2620
+ return Boolean(((_a = options.writeKey) == null ? void 0 : _a.trim()) || resolveLocalDebuggerBaseUrl(options.localDebuggerUrl));
1998
2621
  }
1999
- async function* asyncGeneratorWithCurrent(span, gen) {
2000
- let nextValue;
2001
- while (true) {
2002
- const result = await withCurrent(span, async () => {
2003
- try {
2004
- return await gen.next(nextValue);
2005
- } catch (e) {
2006
- return { value: void 0, done: true, error: e };
2007
- }
2008
- });
2009
- if ("error" in result && result.error !== void 0) {
2010
- throw result.error;
2622
+ var EventShipper2 = class extends EventShipper {
2623
+ constructor(options) {
2624
+ var _a;
2625
+ const ownsAppGitContext = options.appGitContext === void 0;
2626
+ const appGitContext = (_a = options.appGitContext) != null ? _a : createAppGitContext2(options.appGit, { allowDiscovery: hasDestination(options) });
2627
+ try {
2628
+ super({ ...options, appGitContext });
2629
+ } catch (error) {
2630
+ if (ownsAppGitContext) appGitContext.dispose();
2631
+ throw error;
2011
2632
  }
2012
- if (result.done) {
2013
- return result.value;
2633
+ if (ownsAppGitContext) this.ownAppGitContextForShutdown();
2634
+ }
2635
+ };
2636
+ var TraceShipper2 = class extends TraceShipper {
2637
+ constructor(options) {
2638
+ var _a;
2639
+ const ownsAppGitContext = options.appGitContext === void 0;
2640
+ const appGitContext = (_a = options.appGitContext) != null ? _a : createAppGitContext2(options.appGit, { allowDiscovery: hasDestination(options) });
2641
+ try {
2642
+ super({ ...options, appGitContext });
2643
+ } catch (error) {
2644
+ if (ownsAppGitContext) appGitContext.dispose();
2645
+ throw error;
2014
2646
  }
2015
- nextValue = yield result.value;
2647
+ this.ownsAppGitContext = ownsAppGitContext;
2016
2648
  }
2017
- }
2649
+ };
2018
2650
  globalThis.RAINDROP_ASYNC_LOCAL_STORAGE = async_hooks.AsyncLocalStorage;
2019
2651
  var SUPPRESS_TRACING_KEY = /* @__PURE__ */ Symbol.for(
2020
2652
  "OpenTelemetry SDK Context Key SUPPRESS_TRACING"
@@ -2045,14 +2677,14 @@ installTracingSuppressionHook();
2045
2677
  // package.json
2046
2678
  var package_default = {
2047
2679
  name: "@raindrop-ai/ai-sdk",
2048
- version: "0.3.2"};
2680
+ version: "0.3.3"};
2049
2681
 
2050
2682
  // src/internal/version.ts
2051
2683
  var libraryName = package_default.name;
2052
2684
  var libraryVersion = package_default.version;
2053
2685
 
2054
2686
  // src/internal/events.ts
2055
- var EventShipper2 = class extends EventShipper {
2687
+ var EventShipper3 = class extends EventShipper2 {
2056
2688
  constructor(opts) {
2057
2689
  var _a, _b, _c;
2058
2690
  super({
@@ -4564,7 +5196,7 @@ function createStandaloneSelfDiagnosticsTool(args) {
4564
5196
  }
4565
5197
 
4566
5198
  // src/internal/traces.ts
4567
- var TraceShipper2 = class extends TraceShipper {
5199
+ var TraceShipper3 = class extends TraceShipper2 {
4568
5200
  constructor(opts) {
4569
5201
  var _a, _b, _c;
4570
5202
  super({
@@ -6543,11 +7175,11 @@ function userAttrsToOtlp(attrs) {
6543
7175
  function envDebugEnabled() {
6544
7176
  var _a;
6545
7177
  if (typeof process === "undefined") return false;
6546
- const flag = (_a = process.env) == null ? void 0 : _a.RAINDROP_AI_DEBUG;
6547
- return flag === "1" || flag === "true";
7178
+ const flag2 = (_a = process.env) == null ? void 0 : _a.RAINDROP_AI_DEBUG;
7179
+ return flag2 === "1" || flag2 === "true";
6548
7180
  }
6549
7181
  function createRaindropAISDK(opts) {
6550
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
7182
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l;
6551
7183
  const writeKey = opts.writeKey;
6552
7184
  const eventsRequested = ((_a = opts.events) == null ? void 0 : _a.enabled) !== false;
6553
7185
  const tracesRequested = ((_b = opts.traces) == null ? void 0 : _b.enabled) !== false;
@@ -6556,37 +7188,53 @@ function createRaindropAISDK(opts) {
6556
7188
  const localWorkshopInput = opts.localWorkshopUrl === false ? null : opts.localWorkshopUrl;
6557
7189
  const resolvedLocalDebuggerUrl = resolveLocalDebuggerBaseUrl(localWorkshopInput);
6558
7190
  const localDebuggerUrl = localWorkshopInput === null ? null : resolvedLocalDebuggerUrl != null ? resolvedLocalDebuggerUrl : void 0;
6559
- const hasDestination = !!writeKey || !!resolvedLocalDebuggerUrl;
6560
- const eventsEnabled = eventsRequested && hasDestination;
6561
- const tracesEnabled = tracesRequested && hasDestination;
6562
- if (!hasDestination && (eventsRequested || tracesRequested)) {
7191
+ const hasDestination2 = Boolean(writeKey == null ? void 0 : writeKey.trim()) || Boolean(resolvedLocalDebuggerUrl);
7192
+ const eventsEnabled = eventsRequested && hasDestination2;
7193
+ const tracesEnabled = tracesRequested && hasDestination2;
7194
+ const appGitContext = (_c = opts.appGitContext) != null ? _c : createAppGitContext2(
7195
+ eventsEnabled || tracesEnabled ? opts.appGit : false,
7196
+ { allowLocalGit: true }
7197
+ );
7198
+ if (!hasDestination2 && (eventsRequested || tracesRequested)) {
6563
7199
  console.warn(
6564
7200
  "[raindrop-ai/ai-sdk] writeKey not provided and no local Workshop reachable; telemetry shipping is disabled"
6565
7201
  );
6566
7202
  }
6567
- const eventShipper = new EventShipper2({
6568
- writeKey,
6569
- endpoint: opts.endpoint,
6570
- enabled: eventsEnabled,
6571
- debug: ((_c = opts.events) == null ? void 0 : _c.debug) === true || envDebug,
6572
- partialFlushMs: (_d = opts.events) == null ? void 0 : _d.partialFlushMs,
6573
- projectId: opts.projectId,
6574
- localDebuggerUrl
6575
- });
6576
- const traceShipper = new TraceShipper2({
6577
- writeKey,
6578
- endpoint: opts.endpoint,
6579
- enabled: tracesEnabled,
6580
- debug: ((_e = opts.traces) == null ? void 0 : _e.debug) === true || envDebug,
6581
- debugSpans: ((_f = opts.traces) == null ? void 0 : _f.debugSpans) === true || envDebug,
6582
- flushIntervalMs: (_g = opts.traces) == null ? void 0 : _g.flushIntervalMs,
6583
- maxBatchSize: (_h = opts.traces) == null ? void 0 : _h.maxBatchSize,
6584
- maxQueueSize: (_i = opts.traces) == null ? void 0 : _i.maxQueueSize,
6585
- projectId: opts.projectId,
6586
- localDebuggerUrl,
6587
- transformSpan: (_j = opts.traces) == null ? void 0 : _j.transformSpan,
6588
- disableDefaultRedaction: (_k = opts.traces) == null ? void 0 : _k.disableDefaultRedaction
6589
- });
7203
+ let eventShipper;
7204
+ let traceShipper;
7205
+ try {
7206
+ eventShipper = new EventShipper3({
7207
+ writeKey,
7208
+ endpoint: opts.endpoint,
7209
+ enabled: eventsEnabled,
7210
+ debug: ((_d = opts.events) == null ? void 0 : _d.debug) === true || envDebug,
7211
+ partialFlushMs: (_e = opts.events) == null ? void 0 : _e.partialFlushMs,
7212
+ projectId: opts.projectId,
7213
+ localDebuggerUrl,
7214
+ appGitContext
7215
+ });
7216
+ traceShipper = new TraceShipper3({
7217
+ writeKey,
7218
+ endpoint: opts.endpoint,
7219
+ enabled: tracesEnabled,
7220
+ debug: ((_f = opts.traces) == null ? void 0 : _f.debug) === true || envDebug,
7221
+ debugSpans: ((_g = opts.traces) == null ? void 0 : _g.debugSpans) === true || envDebug,
7222
+ flushIntervalMs: (_h = opts.traces) == null ? void 0 : _h.flushIntervalMs,
7223
+ maxBatchSize: (_i = opts.traces) == null ? void 0 : _i.maxBatchSize,
7224
+ maxQueueSize: (_j = opts.traces) == null ? void 0 : _j.maxQueueSize,
7225
+ projectId: opts.projectId,
7226
+ localDebuggerUrl,
7227
+ transformSpan: (_k = opts.traces) == null ? void 0 : _k.transformSpan,
7228
+ disableDefaultRedaction: (_l = opts.traces) == null ? void 0 : _l.disableDefaultRedaction,
7229
+ appGitContext
7230
+ });
7231
+ } catch (error) {
7232
+ try {
7233
+ appGitContext.dispose();
7234
+ } catch (e) {
7235
+ }
7236
+ throw error;
7237
+ }
6590
7238
  const settledEventIds = /* @__PURE__ */ new Set();
6591
7239
  const subagentApi = new SubagentApi({
6592
7240
  traceShipper,
@@ -6754,7 +7402,14 @@ function createRaindropAISDK(opts) {
6754
7402
  await Promise.all([eventShipper.flush(), traceShipper.flush()]);
6755
7403
  },
6756
7404
  async shutdown() {
6757
- await Promise.all([eventShipper.shutdown(), traceShipper.shutdown()]);
7405
+ try {
7406
+ await Promise.all([eventShipper.shutdown(), traceShipper.shutdown()]);
7407
+ } finally {
7408
+ try {
7409
+ appGitContext.dispose();
7410
+ } catch (e) {
7411
+ }
7412
+ }
6758
7413
  }
6759
7414
  };
6760
7415
  }