@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.
- package/README.md +26 -0
- package/dist/{chunk-SGSAYTKI.mjs → chunk-MCRACPKM.mjs} +1274 -422
- package/dist/{index-BqXHiknB.d.mts → index-B_mpeckV.d.mts} +123 -38
- package/dist/{index-BqXHiknB.d.ts → index-B_mpeckV.d.ts} +123 -38
- package/dist/index.browser.d.mts +123 -38
- package/dist/index.browser.d.ts +123 -38
- package/dist/index.browser.js +1131 -424
- package/dist/index.browser.mjs +1131 -424
- package/dist/index.node.d.mts +1 -1
- package/dist/index.node.d.ts +1 -1
- package/dist/index.node.js +1274 -422
- package/dist/index.node.mjs +1 -1
- package/dist/index.workers.d.mts +1 -1
- package/dist/index.workers.d.ts +1 -1
- package/dist/index.workers.js +1274 -422
- package/dist/index.workers.mjs +1 -1
- package/package.json +2 -2
package/dist/index.node.js
CHANGED
|
@@ -1,10 +1,641 @@
|
|
|
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
|
|
|
7
|
-
// ../core/dist/chunk-
|
|
9
|
+
// ../core/dist/chunk-BYBMRLZM.js
|
|
10
|
+
var EVAL_CORRELATION_ID_ATTRIBUTE = "raindrop.eval_correlation_id";
|
|
11
|
+
var PROBE_SCOPE = { correlationId: "" };
|
|
12
|
+
var EvalScopeStorage = class {
|
|
13
|
+
constructor() {
|
|
14
|
+
this._als = null;
|
|
15
|
+
this._probed = false;
|
|
16
|
+
}
|
|
17
|
+
maybeAdoptAsyncLocalStorage() {
|
|
18
|
+
if (this._probed) return;
|
|
19
|
+
this._probed = true;
|
|
20
|
+
try {
|
|
21
|
+
const Ctor = globalThis.RAINDROP_ASYNC_LOCAL_STORAGE;
|
|
22
|
+
if (!Ctor) return;
|
|
23
|
+
const als = new Ctor();
|
|
24
|
+
als.run(PROBE_SCOPE, () => {
|
|
25
|
+
});
|
|
26
|
+
this._als = als;
|
|
27
|
+
} catch (e) {
|
|
28
|
+
this._als = null;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
run(scope, callback) {
|
|
32
|
+
this.maybeAdoptAsyncLocalStorage();
|
|
33
|
+
if (this._als) return this._als.run(scope, callback);
|
|
34
|
+
const previous = this._syncScope;
|
|
35
|
+
this._syncScope = scope;
|
|
36
|
+
try {
|
|
37
|
+
return callback();
|
|
38
|
+
} finally {
|
|
39
|
+
this._syncScope = previous;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
current() {
|
|
43
|
+
this.maybeAdoptAsyncLocalStorage();
|
|
44
|
+
if (this._als) return this._als.getStore();
|
|
45
|
+
return this._syncScope;
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
var EVAL_SCOPE_STORAGE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.evalScopeStorage");
|
|
49
|
+
function evalScopeStorage() {
|
|
50
|
+
const holder = globalThis;
|
|
51
|
+
let storage = holder[EVAL_SCOPE_STORAGE_KEY];
|
|
52
|
+
if (!storage) {
|
|
53
|
+
storage = new EvalScopeStorage();
|
|
54
|
+
holder[EVAL_SCOPE_STORAGE_KEY] = storage;
|
|
55
|
+
}
|
|
56
|
+
return storage;
|
|
57
|
+
}
|
|
58
|
+
function currentEvalScope() {
|
|
59
|
+
try {
|
|
60
|
+
return evalScopeStorage().current();
|
|
61
|
+
} catch (e) {
|
|
62
|
+
return void 0;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function evalScopeAttributes() {
|
|
66
|
+
const scope = currentEvalScope();
|
|
67
|
+
if (!scope) return {};
|
|
68
|
+
return { [EVAL_CORRELATION_ID_ATTRIBUTE]: scope.correlationId };
|
|
69
|
+
}
|
|
70
|
+
|
|
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
|
+
}
|
|
8
639
|
function normalizeFeatureFlags(input) {
|
|
9
640
|
if (Array.isArray(input)) {
|
|
10
641
|
return Object.fromEntries(input.map((name) => [name, "true"]));
|
|
@@ -389,7 +1020,7 @@ function runWithTracingSuppressed(fn) {
|
|
|
389
1020
|
var DEFAULT_REQUEST_TIMEOUT_MS = 3e4;
|
|
390
1021
|
var MAX_RETRY_DELAY_MS = 3e4;
|
|
391
1022
|
function wait(ms) {
|
|
392
|
-
return new Promise((
|
|
1023
|
+
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
393
1024
|
}
|
|
394
1025
|
function formatEndpoint(endpoint) {
|
|
395
1026
|
if (!endpoint) return void 0;
|
|
@@ -426,9 +1057,9 @@ async function raceWithTimeout(promise, timeoutMs) {
|
|
|
426
1057
|
() => true,
|
|
427
1058
|
() => true
|
|
428
1059
|
),
|
|
429
|
-
new Promise((
|
|
1060
|
+
new Promise((resolve2) => {
|
|
430
1061
|
var _a;
|
|
431
|
-
timer = setTimeout(() =>
|
|
1062
|
+
timer = setTimeout(() => resolve2(false), Math.max(0, timeoutMs));
|
|
432
1063
|
(_a = timer.unref) == null ? void 0 : _a.call(timer);
|
|
433
1064
|
})
|
|
434
1065
|
]);
|
|
@@ -499,6 +1130,7 @@ async function postJson(url, body, headers, opts) {
|
|
|
499
1130
|
const resp = await runWithTracingSuppressed(
|
|
500
1131
|
() => fetch(url, {
|
|
501
1132
|
method: "POST",
|
|
1133
|
+
redirect: headers["X-Raindrop-Replay-Id"] !== void 0 ? "error" : "follow",
|
|
502
1134
|
headers: {
|
|
503
1135
|
"Content-Type": "application/json",
|
|
504
1136
|
...headers
|
|
@@ -687,31 +1319,36 @@ function resolveLocalDebuggerBaseUrl(baseUrl) {
|
|
|
687
1319
|
function localDebuggerEnabled(baseUrl) {
|
|
688
1320
|
return resolveLocalDebuggerBaseUrl(baseUrl) !== null;
|
|
689
1321
|
}
|
|
1322
|
+
var LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS = 2e3;
|
|
690
1323
|
function mirrorTraceExportToLocalDebugger(body, options = {}) {
|
|
691
1324
|
var _a;
|
|
692
1325
|
const baseUrl = resolveLocalDebuggerBaseUrl(options.baseUrl);
|
|
693
|
-
if (!baseUrl) return;
|
|
694
|
-
|
|
1326
|
+
if (!baseUrl) return Promise.resolve();
|
|
1327
|
+
return postJson(`${baseUrl}traces`, body, {}, {
|
|
695
1328
|
maxAttempts: 1,
|
|
696
1329
|
debug: (_a = options.debug) != null ? _a : false,
|
|
697
|
-
sdkName: options.sdkName
|
|
1330
|
+
sdkName: options.sdkName,
|
|
1331
|
+
timeoutMs: LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS
|
|
698
1332
|
}).catch(() => {
|
|
699
1333
|
});
|
|
700
1334
|
}
|
|
701
1335
|
function mirrorPartialEventToLocalDebugger(event, options = {}) {
|
|
702
1336
|
var _a;
|
|
703
1337
|
const baseUrl = resolveLocalDebuggerBaseUrl(options.baseUrl);
|
|
704
|
-
if (!baseUrl) return;
|
|
1338
|
+
if (!baseUrl) return Promise.resolve();
|
|
705
1339
|
const headers = options.writeKey ? { Authorization: `Bearer ${options.writeKey}` } : {};
|
|
706
|
-
|
|
1340
|
+
return postJson(`${baseUrl}events/track_partial`, event, headers, {
|
|
707
1341
|
maxAttempts: 1,
|
|
708
1342
|
debug: (_a = options.debug) != null ? _a : false,
|
|
709
|
-
sdkName: options.sdkName
|
|
1343
|
+
sdkName: options.sdkName,
|
|
1344
|
+
timeoutMs: LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS
|
|
710
1345
|
}).catch(() => {
|
|
711
1346
|
});
|
|
712
1347
|
}
|
|
713
1348
|
function sendLocalDebuggerLiveEvent(event, options = {}) {
|
|
714
1349
|
var _a, _b;
|
|
1350
|
+
const destination = currentReplayTraceDestination();
|
|
1351
|
+
if (destination && destination.kind !== "workshop") return;
|
|
715
1352
|
const baseUrl = resolveLocalDebuggerBaseUrl(options.baseUrl);
|
|
716
1353
|
if (!baseUrl) return;
|
|
717
1354
|
void postJson(
|
|
@@ -751,6 +1388,13 @@ function projectIdHeaders(projectId) {
|
|
|
751
1388
|
}
|
|
752
1389
|
var SHUTDOWN_DEADLINE_MS = 1e4;
|
|
753
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
|
+
}
|
|
754
1398
|
function mergePatches(target, source) {
|
|
755
1399
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
756
1400
|
const out = { ...target, ...source };
|
|
@@ -800,22 +1444,25 @@ function eventTelemetryProperties(patch) {
|
|
|
800
1444
|
}
|
|
801
1445
|
var EventShipper = class {
|
|
802
1446
|
constructor(opts) {
|
|
1447
|
+
this.appGitOwner = appGitOwnerId("event");
|
|
803
1448
|
this.buffers = /* @__PURE__ */ new Map();
|
|
804
1449
|
this.sticky = /* @__PURE__ */ new Map();
|
|
805
1450
|
this.timers = /* @__PURE__ */ new Map();
|
|
806
1451
|
this.inFlight = /* @__PURE__ */ new Set();
|
|
807
1452
|
this.hasShutdown = false;
|
|
808
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
809
|
-
this.
|
|
810
|
-
this.
|
|
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/";
|
|
811
1458
|
this.enabled = opts.enabled !== false;
|
|
812
1459
|
this.debug = opts.debug;
|
|
813
|
-
this.partialFlushMs = (
|
|
814
|
-
this.sdkName = (
|
|
1460
|
+
this.partialFlushMs = (_d = opts.partialFlushMs) != null ? _d : 1e3;
|
|
1461
|
+
this.sdkName = (_e = opts.sdkName) != null ? _e : "core";
|
|
815
1462
|
this.prefix = `[raindrop-ai/${this.sdkName}]`;
|
|
816
|
-
this.defaultEventName = (
|
|
1463
|
+
this.defaultEventName = (_f = opts.defaultEventName) != null ? _f : "ai_generation";
|
|
817
1464
|
this.maxTextFieldCharsOpt = opts.maxTextFieldChars;
|
|
818
|
-
this.localDebuggerUrl = (
|
|
1465
|
+
this.localDebuggerUrl = (_g = resolveLocalDebuggerBaseUrl(opts.localDebuggerUrl)) != null ? _g : void 0;
|
|
819
1466
|
if (this.debug && this.localDebuggerUrl) {
|
|
820
1467
|
console.log(`${this.prefix} Local debugger mirroring: ${this.localDebuggerUrl}`);
|
|
821
1468
|
}
|
|
@@ -826,8 +1473,8 @@ var EventShipper = class {
|
|
|
826
1473
|
const isNode = typeof process !== "undefined" && typeof process.version === "string";
|
|
827
1474
|
this.context = {
|
|
828
1475
|
library: {
|
|
829
|
-
name: (
|
|
830
|
-
version: (
|
|
1476
|
+
name: (_h = opts.libraryName) != null ? _h : "@raindrop-ai/core",
|
|
1477
|
+
version: (_i = opts.libraryVersion) != null ? _i : "0.0.0"
|
|
831
1478
|
},
|
|
832
1479
|
metadata: {
|
|
833
1480
|
jsRuntime: isNode ? "node" : "web",
|
|
@@ -835,6 +1482,9 @@ var EventShipper = class {
|
|
|
835
1482
|
}
|
|
836
1483
|
};
|
|
837
1484
|
}
|
|
1485
|
+
ownAppGitContextForShutdown() {
|
|
1486
|
+
this.ownsAppGitContext = true;
|
|
1487
|
+
}
|
|
838
1488
|
isDebugEnabled() {
|
|
839
1489
|
return this.debug;
|
|
840
1490
|
}
|
|
@@ -883,6 +1533,15 @@ var EventShipper = class {
|
|
|
883
1533
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
884
1534
|
if (!this.enabled) return;
|
|
885
1535
|
if (!eventId || !eventId.trim()) return;
|
|
1536
|
+
const capturedSticky = this.sticky.get(eventId);
|
|
1537
|
+
const eventAlreadyKnown = capturedSticky !== void 0 || this.buffers.has(eventId);
|
|
1538
|
+
const destination = currentReplayTraceDestination();
|
|
1539
|
+
const cloudReplay = destination !== void 0 && destination.kind !== "workshop";
|
|
1540
|
+
if ((capturedSticky == null ? void 0 : capturedSticky.replayOnly) === true || !eventAlreadyKnown && cloudReplay) {
|
|
1541
|
+
if (patch.isPending === false) this.sticky.delete(eventId);
|
|
1542
|
+
else this.sticky.set(eventId, { ...capturedSticky, replayOnly: true });
|
|
1543
|
+
return;
|
|
1544
|
+
}
|
|
886
1545
|
const maxChars = resolveMaxTextFieldChars(this.maxTextFieldCharsOpt);
|
|
887
1546
|
if (typeof patch.input === "string" && patch.input.length > maxChars) {
|
|
888
1547
|
patch = { ...patch, input: capText(patch.input, maxChars) };
|
|
@@ -904,6 +1563,13 @@ var EventShipper = class {
|
|
|
904
1563
|
}
|
|
905
1564
|
const sticky = (_c = this.sticky.get(eventId)) != null ? _c : {};
|
|
906
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
|
+
};
|
|
907
1573
|
const merged = mergePatches(existing, patch);
|
|
908
1574
|
merged.isPending = (_g = (_f = (_e = patch.isPending) != null ? _e : existing.isPending) != null ? _f : sticky.isPending) != null ? _g : true;
|
|
909
1575
|
this.buffers.set(eventId, merged);
|
|
@@ -917,6 +1583,8 @@ var EventShipper = class {
|
|
|
917
1583
|
if (t) clearTimeout(t);
|
|
918
1584
|
if (merged.isPending === false) {
|
|
919
1585
|
await this.flushOne(eventId);
|
|
1586
|
+
if (this.appGitContext.releaseOperation) this.appGitContext.releaseOperation(eventId, this.appGitOwner);
|
|
1587
|
+
else this.appGitContext.finishOperation(eventId);
|
|
920
1588
|
return;
|
|
921
1589
|
}
|
|
922
1590
|
const timeout = setTimeout(() => {
|
|
@@ -941,15 +1609,21 @@ var EventShipper = class {
|
|
|
941
1609
|
try {
|
|
942
1610
|
for (const t of this.timers.values()) clearTimeout(t);
|
|
943
1611
|
this.timers.clear();
|
|
1612
|
+
for (const [eventId, sticky] of this.sticky) {
|
|
1613
|
+
if (sticky.replayOnly) this.sticky.delete(eventId);
|
|
1614
|
+
}
|
|
944
1615
|
const settled = await raceWithTimeout(this.flush(), SHUTDOWN_DEADLINE_MS);
|
|
945
1616
|
if (!settled) this.warnShutdownDrop("in-flight request(s) at shutdown");
|
|
946
1617
|
} finally {
|
|
947
1618
|
this.shutdownDeadlineAt = void 0;
|
|
1619
|
+
if (this.ownsAppGitContext) this.appGitContext.dispose();
|
|
948
1620
|
}
|
|
949
1621
|
}
|
|
950
1622
|
async trackSignal(signal) {
|
|
951
1623
|
var _a, _b;
|
|
952
1624
|
if (!this.enabled) return;
|
|
1625
|
+
const destination = currentReplayTraceDestination();
|
|
1626
|
+
if (destination && destination.kind !== "workshop") return;
|
|
953
1627
|
const body = [
|
|
954
1628
|
{
|
|
955
1629
|
event_id: signal.eventId,
|
|
@@ -984,6 +1658,8 @@ var EventShipper = class {
|
|
|
984
1658
|
}
|
|
985
1659
|
async identify(users) {
|
|
986
1660
|
if (!this.enabled) return;
|
|
1661
|
+
const destination = currentReplayTraceDestination();
|
|
1662
|
+
if (destination && destination.kind !== "workshop") return;
|
|
987
1663
|
const list = Array.isArray(users) ? users : [users];
|
|
988
1664
|
const body = list.filter((user) => {
|
|
989
1665
|
if (!(user == null ? void 0 : user.userId) || !user.userId.trim()) {
|
|
@@ -1036,8 +1712,9 @@ var EventShipper = class {
|
|
|
1036
1712
|
this.buffers.delete(eventId);
|
|
1037
1713
|
if (!accumulated) return;
|
|
1038
1714
|
const sticky = (_a = this.sticky.get(eventId)) != null ? _a : {};
|
|
1039
|
-
const
|
|
1040
|
-
const
|
|
1715
|
+
const isPending = (_c = (_b = accumulated.isPending) != null ? _b : sticky.isPending) != null ? _c : true;
|
|
1716
|
+
const eventName = (_e = (_d = accumulated.eventName) != null ? _d : sticky.eventName) != null ? _e : this.defaultEventName;
|
|
1717
|
+
const userId = (_f = accumulated.userId) != null ? _f : sticky.userId;
|
|
1041
1718
|
if (!userId) {
|
|
1042
1719
|
if (this.debug) {
|
|
1043
1720
|
console.warn(`${this.prefix} skipping track_partial for ${eventId}: missing userId`);
|
|
@@ -1045,14 +1722,13 @@ var EventShipper = class {
|
|
|
1045
1722
|
this.sticky.delete(eventId);
|
|
1046
1723
|
return;
|
|
1047
1724
|
}
|
|
1048
|
-
const { wizardSession, ...restProperties } = (
|
|
1725
|
+
const { wizardSession, ...restProperties } = (_g = accumulated.properties) != null ? _g : {};
|
|
1049
1726
|
let telemetryProperties = {};
|
|
1050
1727
|
try {
|
|
1051
1728
|
telemetryProperties = eventTelemetryProperties(accumulated);
|
|
1052
1729
|
} catch (e) {
|
|
1053
1730
|
}
|
|
1054
|
-
const convoId = (
|
|
1055
|
-
const isPending = (_h = (_g = accumulated.isPending) != null ? _g : sticky.isPending) != null ? _h : true;
|
|
1731
|
+
const convoId = (_h = accumulated.convoId) != null ? _h : sticky.convoId;
|
|
1056
1732
|
const payload = {
|
|
1057
1733
|
event_id: eventId,
|
|
1058
1734
|
user_id: userId,
|
|
@@ -1094,29 +1770,30 @@ var EventShipper = class {
|
|
|
1094
1770
|
endpoint: url
|
|
1095
1771
|
});
|
|
1096
1772
|
}
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
});
|
|
1104
|
-
}
|
|
1773
|
+
const mirror = this.localDebuggerUrl ? mirrorPartialEventToLocalDebugger(payload, {
|
|
1774
|
+
baseUrl: this.localDebuggerUrl,
|
|
1775
|
+
writeKey: this.writeKey,
|
|
1776
|
+
debug: this.debug,
|
|
1777
|
+
sdkName: this.sdkName
|
|
1778
|
+
}) : void 0;
|
|
1105
1779
|
if (!this.writeKey) {
|
|
1106
1780
|
if (!isPending) this.sticky.delete(eventId);
|
|
1781
|
+
if (mirror) await mirror;
|
|
1107
1782
|
return;
|
|
1108
1783
|
}
|
|
1109
1784
|
const opts = this.requestOpts();
|
|
1110
1785
|
if (!opts) {
|
|
1111
1786
|
this.warnShutdownDrop(`track_partial ${eventId}`);
|
|
1112
1787
|
if (!isPending) this.sticky.delete(eventId);
|
|
1788
|
+
if (mirror) await mirror;
|
|
1113
1789
|
return;
|
|
1114
1790
|
}
|
|
1115
1791
|
const p = postJson(url, payload, this.requestHeaders(), opts);
|
|
1116
|
-
|
|
1792
|
+
const combined = mirror ? Promise.all([mirror, p]).then(() => void 0) : p;
|
|
1793
|
+
this.inFlight.add(combined);
|
|
1117
1794
|
try {
|
|
1118
1795
|
try {
|
|
1119
|
-
await
|
|
1796
|
+
await combined;
|
|
1120
1797
|
if (this.debug) {
|
|
1121
1798
|
console.log(`${this.prefix} sent track_partial ${eventId} (${eventName})`);
|
|
1122
1799
|
}
|
|
@@ -1128,7 +1805,7 @@ var EventShipper = class {
|
|
|
1128
1805
|
);
|
|
1129
1806
|
}
|
|
1130
1807
|
} finally {
|
|
1131
|
-
this.inFlight.delete(
|
|
1808
|
+
this.inFlight.delete(combined);
|
|
1132
1809
|
}
|
|
1133
1810
|
if (!isPending) {
|
|
1134
1811
|
this.sticky.delete(eventId);
|
|
@@ -1374,6 +2051,13 @@ function redactJsonAttributeValue(key, value) {
|
|
|
1374
2051
|
if (scrubbedJson === json) return void 0;
|
|
1375
2052
|
return { stringValue: scrubbedJson };
|
|
1376
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
|
+
}
|
|
1377
2061
|
function identityAttrs(args) {
|
|
1378
2062
|
return [
|
|
1379
2063
|
attrString("ai.telemetry.metadata.raindrop.ai.userId", args.userId),
|
|
@@ -1396,23 +2080,30 @@ function applyOtelSpanAttributeLimit(limit) {
|
|
|
1396
2080
|
}
|
|
1397
2081
|
var TraceShipper = class {
|
|
1398
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();
|
|
1399
2088
|
this.queue = [];
|
|
1400
2089
|
this.inFlight = /* @__PURE__ */ new Set();
|
|
1401
2090
|
this.hasShutdown = false;
|
|
1402
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
1403
|
-
this.
|
|
1404
|
-
this.
|
|
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/";
|
|
1405
2096
|
this.enabled = opts.enabled !== false;
|
|
1406
2097
|
this.debug = opts.debug;
|
|
1407
2098
|
this.debugSpans = opts.debugSpans === true;
|
|
1408
|
-
this.flushIntervalMs = (
|
|
1409
|
-
this.maxBatchSize = (
|
|
1410
|
-
this.maxQueueSize = (
|
|
1411
|
-
this.sdkName = (
|
|
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";
|
|
1412
2103
|
this.prefix = `[raindrop-ai/${this.sdkName}]`;
|
|
1413
|
-
this.serviceName = (
|
|
1414
|
-
this.serviceVersion = (
|
|
1415
|
-
this.localDebuggerUrl = (
|
|
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;
|
|
1416
2107
|
if (this.debug && this.localDebuggerUrl) {
|
|
1417
2108
|
console.log(`${this.prefix} Local debugger mirroring: ${this.localDebuggerUrl}`);
|
|
1418
2109
|
}
|
|
@@ -1476,7 +2167,10 @@ var TraceShipper = class {
|
|
|
1476
2167
|
try {
|
|
1477
2168
|
const result = this.transformSpanHook(current);
|
|
1478
2169
|
if (result === null) return null;
|
|
1479
|
-
if (result !== void 0)
|
|
2170
|
+
if (result !== void 0) {
|
|
2171
|
+
copyReplayTraceDestination(current, result);
|
|
2172
|
+
current = result;
|
|
2173
|
+
}
|
|
1480
2174
|
} catch (err) {
|
|
1481
2175
|
if (this.debug) {
|
|
1482
2176
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -1486,13 +2180,19 @@ var TraceShipper = class {
|
|
|
1486
2180
|
}
|
|
1487
2181
|
}
|
|
1488
2182
|
try {
|
|
1489
|
-
|
|
2183
|
+
const normalized = normalizeModelUsageSpan(current);
|
|
2184
|
+
copyReplayTraceDestination(current, normalized);
|
|
2185
|
+
current = normalized;
|
|
1490
2186
|
} catch (e) {
|
|
1491
2187
|
}
|
|
1492
2188
|
if (!this.disableDefaultRedaction) {
|
|
1493
|
-
|
|
2189
|
+
const redacted = defaultTransformSpan(current);
|
|
2190
|
+
copyReplayTraceDestination(current, redacted);
|
|
2191
|
+
current = redacted;
|
|
1494
2192
|
}
|
|
1495
|
-
|
|
2193
|
+
const capped = this.capSpanAttributes(current);
|
|
2194
|
+
copyReplayTraceDestination(current, capped);
|
|
2195
|
+
return capped;
|
|
1496
2196
|
}
|
|
1497
2197
|
isDebugEnabled() {
|
|
1498
2198
|
return this.debug;
|
|
@@ -1504,46 +2204,84 @@ var TraceShipper = class {
|
|
|
1504
2204
|
return { ...this.authHeaders(), ...projectIdHeaders(this.projectId) };
|
|
1505
2205
|
}
|
|
1506
2206
|
startSpan(args) {
|
|
1507
|
-
var _a, _b;
|
|
2207
|
+
var _a, _b, _c;
|
|
1508
2208
|
const ids = createSpanIds(args.parent);
|
|
1509
2209
|
const started = (_a = args.startTimeUnixNano) != null ? _a : nowUnixNanoString();
|
|
1510
2210
|
const attrs = [
|
|
1511
2211
|
attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId),
|
|
1512
2212
|
...identityAttrs(args),
|
|
1513
|
-
attrString("ai.operationId", args.operationId)
|
|
2213
|
+
attrString("ai.operationId", args.operationId),
|
|
2214
|
+
...Object.entries(evalScopeAttributes()).map(([key, value]) => attrString(key, value))
|
|
1514
2215
|
];
|
|
1515
2216
|
if ((_b = args.attributes) == null ? void 0 : _b.length) attrs.push(...args.attributes);
|
|
1516
|
-
const
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
);
|
|
2217
|
+
const tracksAppGit = this.appGitActiveSpans.has(args.eventId) || this.appGitActiveSpans.size < 1e4;
|
|
2218
|
+
const appGitOverrides = appGitPropertiesFromAttributes(attrs);
|
|
2219
|
+
const span = {
|
|
2220
|
+
ids,
|
|
2221
|
+
name: args.name,
|
|
2222
|
+
startTimeUnixNano: started,
|
|
2223
|
+
attributes: withAppGitAttributes(
|
|
2224
|
+
attrs,
|
|
2225
|
+
this.appGitContext.forOperation(args.eventId, appGitOverrides, this.appGitOwner)
|
|
2226
|
+
)
|
|
2227
|
+
};
|
|
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))));
|
|
2235
|
+
const openSpan = buildOtlpSpan({
|
|
2236
|
+
ids: span.ids,
|
|
2237
|
+
name: span.name,
|
|
2238
|
+
startTimeUnixNano: span.startTimeUnixNano,
|
|
2239
|
+
endTimeUnixNano: span.startTimeUnixNano,
|
|
2240
|
+
// placeholder — will be updated on endSpan
|
|
2241
|
+
attributes: span.attributes,
|
|
2242
|
+
status: { code: SpanStatusCode.UNSET }
|
|
2243
|
+
});
|
|
2244
|
+
copyReplayTraceDestination(span, openSpan);
|
|
2245
|
+
this.mirrorToLocalDebugger(openSpan);
|
|
1528
2246
|
return span;
|
|
1529
2247
|
}
|
|
1530
|
-
mirrorToLocalDebugger(span) {
|
|
1531
|
-
|
|
2248
|
+
mirrorToLocalDebugger(span, completed = false) {
|
|
2249
|
+
const destination = replayTraceDestinationFor(span);
|
|
2250
|
+
if (destination && destination.kind !== "workshop") return;
|
|
2251
|
+
const localDebuggerUrl = (destination == null ? void 0 : destination.kind) === "workshop" ? destination.url : this.localDebuggerUrl;
|
|
2252
|
+
if (!localDebuggerUrl) return;
|
|
1532
2253
|
const redacted = this.redactSpan(span);
|
|
1533
2254
|
if (redacted === null) return;
|
|
2255
|
+
if (completed && (destination == null ? void 0 : destination.kind) === "workshop") {
|
|
2256
|
+
recordReplayExportedSpan(
|
|
2257
|
+
destination,
|
|
2258
|
+
base64ToHex(redacted.spanId),
|
|
2259
|
+
base64ToHex(redacted.traceId)
|
|
2260
|
+
);
|
|
2261
|
+
}
|
|
1534
2262
|
const body = buildExportTraceServiceRequest([redacted], this.serviceName, this.serviceVersion);
|
|
1535
|
-
mirrorTraceExportToLocalDebugger(body, {
|
|
1536
|
-
baseUrl:
|
|
2263
|
+
const p = mirrorTraceExportToLocalDebugger(body, {
|
|
2264
|
+
baseUrl: localDebuggerUrl,
|
|
1537
2265
|
debug: false,
|
|
1538
2266
|
sdkName: this.sdkName
|
|
1539
2267
|
});
|
|
2268
|
+
this.inFlight.add(p);
|
|
2269
|
+
void p.finally(() => {
|
|
2270
|
+
this.inFlight.delete(p);
|
|
2271
|
+
});
|
|
1540
2272
|
}
|
|
1541
2273
|
endSpan(span, extra) {
|
|
1542
|
-
var _a, _b;
|
|
2274
|
+
var _a, _b, _c;
|
|
1543
2275
|
if (span.endTimeUnixNano) return;
|
|
1544
2276
|
span.endTimeUnixNano = (_a = extra == null ? void 0 : extra.endTimeUnixNano) != null ? _a : nowUnixNanoString();
|
|
1545
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));
|
|
1546
2283
|
span.attributes.push(...extra.attributes);
|
|
2284
|
+
span.attributes = withAppGitAttributes(span.attributes, snapshot);
|
|
1547
2285
|
}
|
|
1548
2286
|
let status = extra == null ? void 0 : extra.status;
|
|
1549
2287
|
if (!status && (extra == null ? void 0 : extra.error) !== void 0) {
|
|
@@ -1558,30 +2296,65 @@ var TraceShipper = class {
|
|
|
1558
2296
|
attributes: span.attributes,
|
|
1559
2297
|
status
|
|
1560
2298
|
});
|
|
2299
|
+
copyReplayTraceDestination(span, otlp);
|
|
2300
|
+
this.appGitCaptured.add(otlp);
|
|
1561
2301
|
this.enqueue(otlp);
|
|
1562
|
-
this.mirrorToLocalDebugger(otlp);
|
|
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
|
+
}
|
|
1563
2313
|
}
|
|
1564
2314
|
createSpan(args) {
|
|
1565
2315
|
var _a;
|
|
1566
2316
|
const ids = createSpanIds(args.parent);
|
|
1567
2317
|
const attrs = [
|
|
1568
2318
|
attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId),
|
|
1569
|
-
...identityAttrs(args)
|
|
2319
|
+
...identityAttrs(args),
|
|
2320
|
+
...Object.entries(evalScopeAttributes()).map(([key, value]) => attrString(key, value))
|
|
1570
2321
|
];
|
|
1571
2322
|
if ((_a = args.attributes) == null ? void 0 : _a.length) attrs.push(...args.attributes);
|
|
2323
|
+
const tracksAppGit = !this.appGitActiveSpans.has(args.eventId);
|
|
1572
2324
|
const otlp = buildOtlpSpan({
|
|
1573
2325
|
ids,
|
|
1574
2326
|
name: args.name,
|
|
1575
2327
|
startTimeUnixNano: args.startTimeUnixNano,
|
|
1576
2328
|
endTimeUnixNano: args.endTimeUnixNano,
|
|
1577
|
-
attributes:
|
|
2329
|
+
attributes: withAppGitAttributes(
|
|
2330
|
+
attrs,
|
|
2331
|
+
this.appGitContext.forOperation(
|
|
2332
|
+
args.eventId,
|
|
2333
|
+
appGitPropertiesFromAttributes(attrs),
|
|
2334
|
+
this.appGitOwner
|
|
2335
|
+
)
|
|
2336
|
+
),
|
|
1578
2337
|
status: args.status
|
|
1579
2338
|
});
|
|
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
|
+
}
|
|
1580
2345
|
this.enqueue(otlp);
|
|
1581
|
-
this.mirrorToLocalDebugger(otlp);
|
|
2346
|
+
this.mirrorToLocalDebugger(otlp, true);
|
|
1582
2347
|
}
|
|
1583
2348
|
enqueue(span) {
|
|
2349
|
+
var _a;
|
|
1584
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
|
+
}
|
|
1585
2358
|
if (this.debugSpans) {
|
|
1586
2359
|
const short = (s) => s ? s.slice(-8) : "none";
|
|
1587
2360
|
console.log(
|
|
@@ -1592,6 +2365,13 @@ var TraceShipper = class {
|
|
|
1592
2365
|
}
|
|
1593
2366
|
const redacted = this.redactSpan(span);
|
|
1594
2367
|
if (redacted === null) return;
|
|
2368
|
+
const destination = replayTraceDestinationFor(redacted);
|
|
2369
|
+
recordReplayExportedSpan(
|
|
2370
|
+
destination,
|
|
2371
|
+
base64ToHex(redacted.spanId),
|
|
2372
|
+
base64ToHex(redacted.traceId)
|
|
2373
|
+
);
|
|
2374
|
+
if ((destination == null ? void 0 : destination.kind) === "workshop") return;
|
|
1595
2375
|
if (this.queue.length >= this.maxQueueSize) {
|
|
1596
2376
|
this.queue.shift();
|
|
1597
2377
|
}
|
|
@@ -1610,47 +2390,67 @@ var TraceShipper = class {
|
|
|
1610
2390
|
}
|
|
1611
2391
|
}
|
|
1612
2392
|
async flush() {
|
|
1613
|
-
|
|
2393
|
+
var _a;
|
|
2394
|
+
if (!this.enabled) {
|
|
2395
|
+
await Promise.all([...this.inFlight].map((p) => p.catch(() => {
|
|
2396
|
+
})));
|
|
2397
|
+
return;
|
|
2398
|
+
}
|
|
1614
2399
|
if (this.timer) {
|
|
1615
2400
|
clearTimeout(this.timer);
|
|
1616
2401
|
this.timer = void 0;
|
|
1617
2402
|
}
|
|
1618
2403
|
while (this.queue.length > 0) {
|
|
1619
2404
|
const batch = this.queue.splice(0, this.maxBatchSize);
|
|
1620
|
-
|
|
1621
|
-
const
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
`${this.prefix} shutdown flush deadline exceeded; dropping ${batch.length} spans`
|
|
1627
|
-
)
|
|
1628
|
-
);
|
|
1629
|
-
continue;
|
|
2405
|
+
const groups = /* @__PURE__ */ new Map();
|
|
2406
|
+
for (const span of batch) {
|
|
2407
|
+
const destination = replayTraceDestinationFor(span);
|
|
2408
|
+
const spans = groups.get(destination);
|
|
2409
|
+
if (spans) spans.push(span);
|
|
2410
|
+
else groups.set(destination, [span]);
|
|
1630
2411
|
}
|
|
1631
|
-
const
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
endpoint: url
|
|
1637
|
-
});
|
|
1638
|
-
}
|
|
1639
|
-
const p = postJson(url, body, this.requestHeaders(), opts);
|
|
1640
|
-
this.inFlight.add(p);
|
|
1641
|
-
try {
|
|
1642
|
-
try {
|
|
1643
|
-
await p;
|
|
1644
|
-
if (this.debug) console.log(`${this.prefix} sent ${batch.length} spans`);
|
|
1645
|
-
} catch (err) {
|
|
1646
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
2412
|
+
for (const [destination, spans] of groups) {
|
|
2413
|
+
if (!destination && !this.writeKey) continue;
|
|
2414
|
+
if ((destination == null ? void 0 : destination.kind) === "workshop") continue;
|
|
2415
|
+
const opts = this.requestOpts();
|
|
2416
|
+
if (!opts) {
|
|
1647
2417
|
rateLimitedLog(
|
|
1648
|
-
`${this.prefix}.
|
|
1649
|
-
() => console.warn(
|
|
2418
|
+
`${this.prefix}.shutdown_deadline`,
|
|
2419
|
+
() => console.warn(
|
|
2420
|
+
`${this.prefix} shutdown flush deadline exceeded; dropping ${spans.length} spans`
|
|
2421
|
+
)
|
|
1650
2422
|
);
|
|
2423
|
+
continue;
|
|
2424
|
+
}
|
|
2425
|
+
const body = buildExportTraceServiceRequest(spans, this.serviceName, this.serviceVersion);
|
|
2426
|
+
const url = destination ? replayTraceUrl(destination.url) : `${this.baseUrl}traces`;
|
|
2427
|
+
const headers = destination ? {
|
|
2428
|
+
Authorization: `Bearer ${destination.apiKey}`,
|
|
2429
|
+
"X-Raindrop-Replay-Id": destination.replayId,
|
|
2430
|
+
"X-Raindrop-Project-Id": (_a = destination.projectId) != null ? _a : "default"
|
|
2431
|
+
} : this.requestHeaders();
|
|
2432
|
+
if (this.debug) {
|
|
2433
|
+
console.log(`${this.prefix} sending traces batch`, {
|
|
2434
|
+
spans: spans.length,
|
|
2435
|
+
endpoint: url
|
|
2436
|
+
});
|
|
2437
|
+
}
|
|
2438
|
+
const p = postJson(url, body, headers, opts);
|
|
2439
|
+
this.inFlight.add(p);
|
|
2440
|
+
try {
|
|
2441
|
+
try {
|
|
2442
|
+
await p;
|
|
2443
|
+
if (this.debug) console.log(`${this.prefix} sent ${spans.length} spans`);
|
|
2444
|
+
} catch (err) {
|
|
2445
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2446
|
+
rateLimitedLog(
|
|
2447
|
+
`${this.prefix}.send_spans_failed`,
|
|
2448
|
+
() => console.warn(`${this.prefix} failed to send ${spans.length} spans: ${msg}`)
|
|
2449
|
+
);
|
|
2450
|
+
}
|
|
2451
|
+
} finally {
|
|
2452
|
+
this.inFlight.delete(p);
|
|
1651
2453
|
}
|
|
1652
|
-
} finally {
|
|
1653
|
-
this.inFlight.delete(p);
|
|
1654
2454
|
}
|
|
1655
2455
|
}
|
|
1656
2456
|
}
|
|
@@ -1693,131 +2493,160 @@ var TraceShipper = class {
|
|
|
1693
2493
|
if (!settled) {
|
|
1694
2494
|
rateLimitedLog(
|
|
1695
2495
|
`${this.prefix}.shutdown_deadline`,
|
|
1696
|
-
() => console.warn(
|
|
2496
|
+
() => console.warn(
|
|
2497
|
+
`${this.prefix} shutdown flush deadline exceeded; abandoning in-flight spans`
|
|
2498
|
+
)
|
|
1697
2499
|
);
|
|
1698
2500
|
}
|
|
1699
2501
|
} finally {
|
|
1700
2502
|
this.shutdownDeadlineAt = void 0;
|
|
2503
|
+
if (this.ownsAppGitContext) this.appGitContext.dispose();
|
|
1701
2504
|
}
|
|
1702
2505
|
}
|
|
1703
2506
|
};
|
|
1704
|
-
var
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
}
|
|
1718
|
-
isEmpty() {
|
|
1719
|
-
return this._stack.length === 0;
|
|
1720
|
-
}
|
|
1721
|
-
getStore() {
|
|
1722
|
-
return this._stack[this._stack.length - 1];
|
|
1723
|
-
}
|
|
1724
|
-
run(store, callback) {
|
|
1725
|
-
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
|
+
}
|
|
1726
2520
|
try {
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
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
|
+
}
|
|
1730
2574
|
}
|
|
1731
|
-
}
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
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) {
|
|
1743
2611
|
}
|
|
1744
|
-
|
|
1745
|
-
this._storage = this._fallback;
|
|
1746
|
-
}
|
|
1747
|
-
maybeAdoptAsyncLocalStorage() {
|
|
1748
|
-
if (!this._fallback || !this._fallback.isEmpty()) return;
|
|
1749
|
-
const Ctor = getAsyncLocalStorageCtor();
|
|
1750
|
-
if (!Ctor) return;
|
|
1751
|
-
this._storage = new Ctor();
|
|
1752
|
-
this._fallback = null;
|
|
1753
|
-
}
|
|
1754
|
-
isReady() {
|
|
1755
|
-
return true;
|
|
1756
|
-
}
|
|
1757
|
-
getParentSpanIds() {
|
|
1758
|
-
this.maybeAdoptAsyncLocalStorage();
|
|
1759
|
-
const span = this._storage.getStore();
|
|
1760
|
-
if (!span || span === NOOP_SPAN) return void 0;
|
|
1761
|
-
return {
|
|
1762
|
-
traceIdB64: span.traceIdB64,
|
|
1763
|
-
spanIdB64: span.spanIdB64,
|
|
1764
|
-
eventId: span.eventId
|
|
1765
|
-
};
|
|
1766
|
-
}
|
|
1767
|
-
runInContext(span, callback) {
|
|
1768
|
-
this.maybeAdoptAsyncLocalStorage();
|
|
1769
|
-
return this._storage.run(span, callback);
|
|
1770
|
-
}
|
|
1771
|
-
getCurrentSpan() {
|
|
1772
|
-
this.maybeAdoptAsyncLocalStorage();
|
|
1773
|
-
return this._storage.getStore();
|
|
1774
|
-
}
|
|
2612
|
+
};
|
|
1775
2613
|
};
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
if (!_contextManager) {
|
|
1779
|
-
_contextManager = globalThis.RAINDROP_CONTEXT_MANAGER ? new globalThis.RAINDROP_CONTEXT_MANAGER() : new RaindropContextManager();
|
|
1780
|
-
}
|
|
1781
|
-
return _contextManager;
|
|
2614
|
+
function createAppGitContext2(options, runtime = {}) {
|
|
2615
|
+
return new AppGitContext(options, { ...runtime, resolveLocal });
|
|
1782
2616
|
}
|
|
1783
|
-
function
|
|
2617
|
+
function hasDestination(options) {
|
|
1784
2618
|
var _a;
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
function withCurrent(span, callback) {
|
|
1788
|
-
return getContextManager().runInContext(span, callback);
|
|
1789
|
-
}
|
|
1790
|
-
async function getCurrentParentSpanContext() {
|
|
1791
|
-
return getContextManager().getParentSpanIds();
|
|
1792
|
-
}
|
|
1793
|
-
async function runWithParentSpanContext(ctx, fn) {
|
|
1794
|
-
const cm = getContextManager();
|
|
1795
|
-
const span = {
|
|
1796
|
-
traceIdB64: ctx.traceIdB64,
|
|
1797
|
-
spanIdB64: ctx.spanIdB64,
|
|
1798
|
-
eventId: ctx.eventId
|
|
1799
|
-
};
|
|
1800
|
-
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));
|
|
1801
2621
|
}
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
const
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
if ("error" in result && result.error !== void 0) {
|
|
1813
|
-
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;
|
|
1814
2632
|
}
|
|
1815
|
-
if (
|
|
1816
|
-
|
|
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;
|
|
1817
2646
|
}
|
|
1818
|
-
|
|
2647
|
+
this.ownsAppGitContext = ownsAppGitContext;
|
|
1819
2648
|
}
|
|
1820
|
-
}
|
|
2649
|
+
};
|
|
1821
2650
|
globalThis.RAINDROP_ASYNC_LOCAL_STORAGE = async_hooks.AsyncLocalStorage;
|
|
1822
2651
|
var SUPPRESS_TRACING_KEY = /* @__PURE__ */ Symbol.for(
|
|
1823
2652
|
"OpenTelemetry SDK Context Key SUPPRESS_TRACING"
|
|
@@ -1848,14 +2677,14 @@ installTracingSuppressionHook();
|
|
|
1848
2677
|
// package.json
|
|
1849
2678
|
var package_default = {
|
|
1850
2679
|
name: "@raindrop-ai/ai-sdk",
|
|
1851
|
-
version: "0.3.
|
|
2680
|
+
version: "0.3.3"};
|
|
1852
2681
|
|
|
1853
2682
|
// src/internal/version.ts
|
|
1854
2683
|
var libraryName = package_default.name;
|
|
1855
2684
|
var libraryVersion = package_default.version;
|
|
1856
2685
|
|
|
1857
2686
|
// src/internal/events.ts
|
|
1858
|
-
var
|
|
2687
|
+
var EventShipper3 = class extends EventShipper2 {
|
|
1859
2688
|
constructor(opts) {
|
|
1860
2689
|
var _a, _b, _c;
|
|
1861
2690
|
super({
|
|
@@ -3374,13 +4203,13 @@ var RaindropTelemetryIntegration = class {
|
|
|
3374
4203
|
};
|
|
3375
4204
|
// ── onStepStart ─────────────────────────────────────────────────────────
|
|
3376
4205
|
this.onStepStart = (event) => {
|
|
3377
|
-
const
|
|
3378
|
-
if (!(
|
|
3379
|
-
const isStream =
|
|
3380
|
-
const stepOperationId = isStream ? `${
|
|
3381
|
-
const { operationName, resourceName } = opName(stepOperationId,
|
|
4206
|
+
const state2 = this.getState(event.callId);
|
|
4207
|
+
if (!(state2 == null ? void 0 : state2.rootSpan) || !state2.rootParent) return;
|
|
4208
|
+
const isStream = state2.operationId === "ai.streamText" || state2.operationId === "ai.streamObject";
|
|
4209
|
+
const stepOperationId = isStream ? `${state2.operationId}.doStream` : `${state2.operationId}.doGenerate`;
|
|
4210
|
+
const { operationName, resourceName } = opName(stepOperationId, state2.functionId);
|
|
3382
4211
|
const inputAttrs = [];
|
|
3383
|
-
if (
|
|
4212
|
+
if (state2.recordInputs) {
|
|
3384
4213
|
if (event.promptMessages) {
|
|
3385
4214
|
inputAttrs.push(attrString("ai.prompt.messages", safeJsonWithUint8(event.promptMessages)));
|
|
3386
4215
|
}
|
|
@@ -3403,25 +4232,25 @@ var RaindropTelemetryIntegration = class {
|
|
|
3403
4232
|
}
|
|
3404
4233
|
const stepSpan = this.traceShipper.startSpan({
|
|
3405
4234
|
name: stepOperationId,
|
|
3406
|
-
parent:
|
|
3407
|
-
eventId:
|
|
3408
|
-
...
|
|
4235
|
+
parent: state2.rootParent,
|
|
4236
|
+
eventId: state2.eventId,
|
|
4237
|
+
...state2.identity,
|
|
3409
4238
|
operationId: stepOperationId,
|
|
3410
4239
|
attributes: [
|
|
3411
4240
|
attrString("operation.name", operationName),
|
|
3412
4241
|
attrString("resource.name", resourceName),
|
|
3413
|
-
attrString("ai.telemetry.functionId",
|
|
4242
|
+
attrString("ai.telemetry.functionId", state2.functionId),
|
|
3414
4243
|
...attrsFromModelProvider(event.provider),
|
|
3415
4244
|
attrString("ai.model.id", event.modelId),
|
|
3416
4245
|
attrString(MODEL_USAGE_ATTRIBUTES.requestModel, event.modelId),
|
|
3417
4246
|
...inputAttrs,
|
|
3418
|
-
...handoffSpanAttrs(
|
|
4247
|
+
...handoffSpanAttrs(state2.handoff)
|
|
3419
4248
|
]
|
|
3420
4249
|
});
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
4250
|
+
state2.stepSpan = stepSpan;
|
|
4251
|
+
state2.stepParent = this.spanParentRef(stepSpan);
|
|
4252
|
+
state2.stepProvider = event.provider;
|
|
4253
|
+
state2.stepModelId = event.modelId;
|
|
3425
4254
|
};
|
|
3426
4255
|
this.onToolExecutionStart = (event) => this.toolExecutionStart(event);
|
|
3427
4256
|
this.onToolExecutionEnd = (event) => this.toolExecutionEnd(event);
|
|
@@ -3448,33 +4277,33 @@ var RaindropTelemetryIntegration = class {
|
|
|
3448
4277
|
var _a, _b, _c, _d, _e;
|
|
3449
4278
|
const callId = (_b = event.callId) != null ? _b : (_a = event.chunk) == null ? void 0 : _a.callId;
|
|
3450
4279
|
if (!callId) return;
|
|
3451
|
-
const
|
|
3452
|
-
if (!
|
|
4280
|
+
const state2 = this.getState(callId);
|
|
4281
|
+
if (!state2) return;
|
|
3453
4282
|
const chunk = event.chunk;
|
|
3454
4283
|
if (!chunk || typeof chunk !== "object") return;
|
|
3455
4284
|
if (chunk.type === "text-delta") {
|
|
3456
4285
|
const delta = (_c = chunk.textDelta) != null ? _c : chunk.delta;
|
|
3457
4286
|
if (typeof delta === "string") {
|
|
3458
|
-
if (
|
|
3459
|
-
|
|
4287
|
+
if (state2.accumulatedText.length <= effectiveMaxTextFieldChars()) {
|
|
4288
|
+
state2.accumulatedText += delta;
|
|
3460
4289
|
}
|
|
3461
|
-
this.emitLive(
|
|
4290
|
+
this.emitLive(state2, "text_delta", delta);
|
|
3462
4291
|
}
|
|
3463
4292
|
} else if (chunk.type === "reasoning" || chunk.type === "reasoning-delta") {
|
|
3464
4293
|
const text = (_e = (_d = chunk.textDelta) != null ? _d : chunk.text) != null ? _e : chunk.delta;
|
|
3465
4294
|
if (typeof text === "string") {
|
|
3466
|
-
this.emitLive(
|
|
4295
|
+
this.emitLive(state2, "reasoning_delta", text);
|
|
3467
4296
|
}
|
|
3468
4297
|
}
|
|
3469
4298
|
};
|
|
3470
4299
|
// ── onStepFinish ────────────────────────────────────────────────────────
|
|
3471
4300
|
this.onStepFinish = (event) => {
|
|
3472
4301
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
3473
|
-
const
|
|
3474
|
-
if (!(
|
|
3475
|
-
const responseModelId = (_b = (_a = event.response) == null ? void 0 : _a.modelId) != null ? _b :
|
|
4302
|
+
const state2 = this.getState(event.callId);
|
|
4303
|
+
if (!(state2 == null ? void 0 : state2.stepSpan)) return;
|
|
4304
|
+
const responseModelId = (_b = (_a = event.response) == null ? void 0 : _a.modelId) != null ? _b : state2.stepModelId;
|
|
3476
4305
|
const outputAttrs = [];
|
|
3477
|
-
if (
|
|
4306
|
+
if (state2.recordOutputs) {
|
|
3478
4307
|
outputAttrs.push(
|
|
3479
4308
|
attrString("ai.response.finishReason", event.finishReason),
|
|
3480
4309
|
attrString("ai.response.text", capText2((_c = event.text) != null ? _c : void 0)),
|
|
@@ -3519,7 +4348,7 @@ var RaindropTelemetryIntegration = class {
|
|
|
3519
4348
|
if (usage) {
|
|
3520
4349
|
const usageMetrics = extractUsageMetricsFromUsage(
|
|
3521
4350
|
usage,
|
|
3522
|
-
|
|
4351
|
+
state2.stepProvider,
|
|
3523
4352
|
event.providerMetadata
|
|
3524
4353
|
);
|
|
3525
4354
|
outputAttrs.push(
|
|
@@ -3532,51 +4361,51 @@ var RaindropTelemetryIntegration = class {
|
|
|
3532
4361
|
...buildRawModelUsageAttributes(usageMetrics)
|
|
3533
4362
|
);
|
|
3534
4363
|
}
|
|
3535
|
-
this.emitProviderExecutedToolSpans(event,
|
|
3536
|
-
this.traceShipper.endSpan(
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
4364
|
+
this.emitProviderExecutedToolSpans(event, state2);
|
|
4365
|
+
this.traceShipper.endSpan(state2.stepSpan, { attributes: outputAttrs });
|
|
4366
|
+
state2.stepSpan = void 0;
|
|
4367
|
+
state2.stepParent = void 0;
|
|
4368
|
+
state2.stepProvider = void 0;
|
|
4369
|
+
state2.stepModelId = void 0;
|
|
3541
4370
|
};
|
|
3542
4371
|
// ── onEmbedStart ────────────────────────────────────────────────────────
|
|
3543
4372
|
this.onEmbedStart = (event) => {
|
|
3544
|
-
const
|
|
3545
|
-
if (!(
|
|
3546
|
-
const { operationName, resourceName } = opName(event.operationId,
|
|
3547
|
-
const inputAttrs =
|
|
4373
|
+
const state2 = this.getState(event.callId);
|
|
4374
|
+
if (!(state2 == null ? void 0 : state2.rootSpan) || !state2.rootParent) return;
|
|
4375
|
+
const { operationName, resourceName } = opName(event.operationId, state2.functionId);
|
|
4376
|
+
const inputAttrs = state2.recordInputs ? [attrString("ai.values", safeJsonWithUint8(event.values))] : [];
|
|
3548
4377
|
const embedSpan = this.traceShipper.startSpan({
|
|
3549
4378
|
name: event.operationId,
|
|
3550
|
-
parent:
|
|
3551
|
-
eventId:
|
|
3552
|
-
...
|
|
4379
|
+
parent: state2.rootParent,
|
|
4380
|
+
eventId: state2.eventId,
|
|
4381
|
+
...state2.identity,
|
|
3553
4382
|
operationId: event.operationId,
|
|
3554
4383
|
attributes: [
|
|
3555
4384
|
attrString("operation.name", operationName),
|
|
3556
4385
|
attrString("resource.name", resourceName),
|
|
3557
|
-
attrString("ai.telemetry.functionId",
|
|
4386
|
+
attrString("ai.telemetry.functionId", state2.functionId),
|
|
3558
4387
|
...inputAttrs,
|
|
3559
|
-
...handoffSpanAttrs(
|
|
4388
|
+
...handoffSpanAttrs(state2.handoff)
|
|
3560
4389
|
]
|
|
3561
4390
|
});
|
|
3562
|
-
|
|
4391
|
+
state2.embedSpans.set(event.embedCallId, embedSpan);
|
|
3563
4392
|
};
|
|
3564
4393
|
// ── onEmbedFinish ───────────────────────────────────────────────────────
|
|
3565
4394
|
this.onEmbedFinish = (event) => {
|
|
3566
4395
|
var _a;
|
|
3567
|
-
const
|
|
3568
|
-
if (!
|
|
3569
|
-
const embedSpan =
|
|
4396
|
+
const state2 = this.getState(event.callId);
|
|
4397
|
+
if (!state2) return;
|
|
4398
|
+
const embedSpan = state2.embedSpans.get(event.embedCallId);
|
|
3570
4399
|
if (!embedSpan) return;
|
|
3571
4400
|
const outputAttrs = [];
|
|
3572
|
-
if (
|
|
4401
|
+
if (state2.recordOutputs) {
|
|
3573
4402
|
outputAttrs.push(attrString("ai.embeddings", safeJsonWithUint8(event.embeddings)));
|
|
3574
4403
|
}
|
|
3575
4404
|
if (((_a = event.usage) == null ? void 0 : _a.tokens) != null) {
|
|
3576
4405
|
outputAttrs.push(attrInt("ai.usage.tokens", event.usage.tokens));
|
|
3577
4406
|
}
|
|
3578
4407
|
this.traceShipper.endSpan(embedSpan, { attributes: outputAttrs });
|
|
3579
|
-
|
|
4408
|
+
state2.embedSpans.delete(event.embedCallId);
|
|
3580
4409
|
};
|
|
3581
4410
|
// v7 canary.159 renamed `onEmbedFinish` -> `onEmbedEnd`. Both names forward
|
|
3582
4411
|
// to the same implementation; the installed SDK only wires up whichever it
|
|
@@ -3584,16 +4413,16 @@ var RaindropTelemetryIntegration = class {
|
|
|
3584
4413
|
this.onEmbedEnd = (event) => this.onEmbedFinish(event);
|
|
3585
4414
|
// ── onFinish ────────────────────────────────────────────────────────────
|
|
3586
4415
|
this.onFinish = (event) => {
|
|
3587
|
-
const
|
|
3588
|
-
if (!
|
|
3589
|
-
const isEmbed =
|
|
4416
|
+
const state2 = this.getState(event.callId);
|
|
4417
|
+
if (!state2) return;
|
|
4418
|
+
const isEmbed = state2.operationId === "ai.embed" || state2.operationId === "ai.embedMany";
|
|
3590
4419
|
if (isEmbed) {
|
|
3591
|
-
this.finishEmbed(event,
|
|
4420
|
+
this.finishEmbed(event, state2);
|
|
3592
4421
|
} else {
|
|
3593
|
-
this.finishGenerate(event,
|
|
4422
|
+
this.finishGenerate(event, state2);
|
|
3594
4423
|
}
|
|
3595
|
-
if (
|
|
3596
|
-
this.traceShipper.endSpan(
|
|
4424
|
+
if (state2.subagentToolCallSpan) {
|
|
4425
|
+
this.traceShipper.endSpan(state2.subagentToolCallSpan);
|
|
3597
4426
|
}
|
|
3598
4427
|
this.cleanup(event.callId);
|
|
3599
4428
|
};
|
|
@@ -3608,42 +4437,42 @@ var RaindropTelemetryIntegration = class {
|
|
|
3608
4437
|
var _a;
|
|
3609
4438
|
const event = error;
|
|
3610
4439
|
if (!(event == null ? void 0 : event.callId)) return;
|
|
3611
|
-
const
|
|
3612
|
-
if (!
|
|
4440
|
+
const state2 = this.getState(event.callId);
|
|
4441
|
+
if (!state2) return;
|
|
3613
4442
|
const actualError = (_a = event.error) != null ? _a : error;
|
|
3614
|
-
if (
|
|
3615
|
-
this.traceShipper.endSpan(
|
|
3616
|
-
|
|
3617
|
-
|
|
4443
|
+
if (state2.stepSpan) {
|
|
4444
|
+
this.traceShipper.endSpan(state2.stepSpan, { error: actualError });
|
|
4445
|
+
state2.stepProvider = void 0;
|
|
4446
|
+
state2.stepModelId = void 0;
|
|
3618
4447
|
}
|
|
3619
|
-
for (const embedSpan of
|
|
4448
|
+
for (const embedSpan of state2.embedSpans.values()) {
|
|
3620
4449
|
this.traceShipper.endSpan(embedSpan, { error: actualError });
|
|
3621
4450
|
}
|
|
3622
|
-
|
|
3623
|
-
for (const toolCallId of
|
|
4451
|
+
state2.embedSpans.clear();
|
|
4452
|
+
for (const toolCallId of state2.parentContextToolCallIds) {
|
|
3624
4453
|
this.priorParentContexts.delete(toolCallId);
|
|
3625
4454
|
}
|
|
3626
|
-
|
|
3627
|
-
for (const toolSpan of
|
|
4455
|
+
state2.parentContextToolCallIds.clear();
|
|
4456
|
+
for (const toolSpan of state2.toolSpans.values()) {
|
|
3628
4457
|
this.traceShipper.endSpan(toolSpan, { error: actualError });
|
|
3629
4458
|
}
|
|
3630
|
-
|
|
4459
|
+
state2.toolSpans.clear();
|
|
3631
4460
|
const abortReason = describeAbortReason(actualError);
|
|
3632
|
-
if (
|
|
3633
|
-
this.traceShipper.endSpan(
|
|
4461
|
+
if (state2.rootSpan) {
|
|
4462
|
+
this.traceShipper.endSpan(state2.rootSpan, {
|
|
3634
4463
|
error: actualError,
|
|
3635
|
-
attributes: this.abortOutcomeAttrs(
|
|
4464
|
+
attributes: this.abortOutcomeAttrs(state2, abortReason, "error")
|
|
3636
4465
|
});
|
|
3637
4466
|
}
|
|
3638
|
-
if (
|
|
3639
|
-
this.traceShipper.endSpan(
|
|
4467
|
+
if (state2.subagentToolCallSpan) {
|
|
4468
|
+
this.traceShipper.endSpan(state2.subagentToolCallSpan, { error: actualError });
|
|
3640
4469
|
}
|
|
3641
|
-
const isEmbed =
|
|
4470
|
+
const isEmbed = state2.operationId === "ai.embed" || state2.operationId === "ai.embedMany";
|
|
3642
4471
|
if (!isEmbed) {
|
|
3643
|
-
const errorIsTheRunsOutcome =
|
|
4472
|
+
const errorIsTheRunsOutcome = state2.handoff !== void 0 && !state2.nestedInEvent;
|
|
3644
4473
|
this.finalizeGenerateEvent(
|
|
3645
|
-
|
|
3646
|
-
|
|
4474
|
+
state2,
|
|
4475
|
+
state2.accumulatedText || void 0,
|
|
3647
4476
|
void 0,
|
|
3648
4477
|
false,
|
|
3649
4478
|
errorIsTheRunsOutcome ? { fallbackOutput: abortReason } : void 0
|
|
@@ -3662,51 +4491,51 @@ var RaindropTelemetryIntegration = class {
|
|
|
3662
4491
|
this.onAbort = (event) => {
|
|
3663
4492
|
const callId = event == null ? void 0 : event.callId;
|
|
3664
4493
|
if (!callId) return;
|
|
3665
|
-
const
|
|
3666
|
-
if (!
|
|
4494
|
+
const state2 = this.getState(callId);
|
|
4495
|
+
if (!state2) return;
|
|
3667
4496
|
const abortedAttr = attrString("ai.response.aborted", "true");
|
|
3668
|
-
if (
|
|
3669
|
-
this.traceShipper.endSpan(
|
|
3670
|
-
|
|
3671
|
-
|
|
3672
|
-
|
|
3673
|
-
|
|
4497
|
+
if (state2.stepSpan) {
|
|
4498
|
+
this.traceShipper.endSpan(state2.stepSpan, { attributes: [abortedAttr] });
|
|
4499
|
+
state2.stepSpan = void 0;
|
|
4500
|
+
state2.stepParent = void 0;
|
|
4501
|
+
state2.stepProvider = void 0;
|
|
4502
|
+
state2.stepModelId = void 0;
|
|
3674
4503
|
}
|
|
3675
|
-
for (const embedSpan of
|
|
4504
|
+
for (const embedSpan of state2.embedSpans.values()) {
|
|
3676
4505
|
this.traceShipper.endSpan(embedSpan, { attributes: [abortedAttr] });
|
|
3677
4506
|
}
|
|
3678
|
-
|
|
3679
|
-
for (const toolCallId of
|
|
4507
|
+
state2.embedSpans.clear();
|
|
4508
|
+
for (const toolCallId of state2.parentContextToolCallIds) {
|
|
3680
4509
|
this.priorParentContexts.delete(toolCallId);
|
|
3681
4510
|
}
|
|
3682
|
-
|
|
3683
|
-
for (const toolSpan of
|
|
4511
|
+
state2.parentContextToolCallIds.clear();
|
|
4512
|
+
for (const toolSpan of state2.toolSpans.values()) {
|
|
3684
4513
|
this.traceShipper.endSpan(toolSpan, { attributes: [abortedAttr] });
|
|
3685
4514
|
}
|
|
3686
|
-
|
|
3687
|
-
const abortIsTheRunsOutcome =
|
|
3688
|
-
if (
|
|
3689
|
-
this.traceShipper.endSpan(
|
|
4515
|
+
state2.toolSpans.clear();
|
|
4516
|
+
const abortIsTheRunsOutcome = state2.handoff !== void 0 && !state2.nestedInEvent;
|
|
4517
|
+
if (state2.rootSpan) {
|
|
4518
|
+
this.traceShipper.endSpan(state2.rootSpan, {
|
|
3690
4519
|
attributes: [
|
|
3691
4520
|
abortedAttr,
|
|
3692
|
-
attrInt("ai.toolCall.count",
|
|
4521
|
+
attrInt("ai.toolCall.count", state2.toolCallCount),
|
|
3693
4522
|
// An aborted detached child IS a cancelled sub-agent, and a cancelled
|
|
3694
4523
|
// run is span-for-span identical to a finished one — spans close,
|
|
3695
4524
|
// nothing errors, there is just no answer. So it is the one outcome
|
|
3696
4525
|
// that has to be stated, and the child states it on itself.
|
|
3697
4526
|
...abortIsTheRunsOutcome ? cancelledSpanAttrs() : [],
|
|
3698
|
-
...abortIsTheRunsOutcome ? this.abortOutcomeAttrs(
|
|
4527
|
+
...abortIsTheRunsOutcome ? this.abortOutcomeAttrs(state2, SUBAGENT_CANCELLED_OUTPUT, "stop") : []
|
|
3699
4528
|
]
|
|
3700
4529
|
});
|
|
3701
4530
|
}
|
|
3702
|
-
if (
|
|
3703
|
-
this.traceShipper.endSpan(
|
|
4531
|
+
if (state2.subagentToolCallSpan) {
|
|
4532
|
+
this.traceShipper.endSpan(state2.subagentToolCallSpan, {
|
|
3704
4533
|
attributes: [abortedAttr]
|
|
3705
4534
|
});
|
|
3706
4535
|
}
|
|
3707
4536
|
this.finalizeGenerateEvent(
|
|
3708
|
-
|
|
3709
|
-
|
|
4537
|
+
state2,
|
|
4538
|
+
state2.accumulatedText || void 0,
|
|
3710
4539
|
void 0,
|
|
3711
4540
|
false,
|
|
3712
4541
|
abortIsTheRunsOutcome ? {
|
|
@@ -3714,7 +4543,7 @@ var RaindropTelemetryIntegration = class {
|
|
|
3714
4543
|
properties: { [HANDOFF_TERMINAL_PROPERTY_KEY]: HANDOFF_TERMINAL_CANCELLED }
|
|
3715
4544
|
} : void 0
|
|
3716
4545
|
);
|
|
3717
|
-
if (abortIsTheRunsOutcome) this.subagents.noteSettled(
|
|
4546
|
+
if (abortIsTheRunsOutcome) this.subagents.noteSettled(state2.eventId);
|
|
3718
4547
|
this.cleanup(callId);
|
|
3719
4548
|
};
|
|
3720
4549
|
// ── executeTool ─────────────────────────────────────────────────────────
|
|
@@ -3723,14 +4552,14 @@ var RaindropTelemetryIntegration = class {
|
|
|
3723
4552
|
toolCallId,
|
|
3724
4553
|
execute
|
|
3725
4554
|
}) => {
|
|
3726
|
-
const
|
|
3727
|
-
const toolSpan =
|
|
4555
|
+
const state2 = this.getState(callId);
|
|
4556
|
+
const toolSpan = state2 == null ? void 0 : state2.toolSpans.get(toolCallId);
|
|
3728
4557
|
if (!toolSpan) return execute();
|
|
3729
4558
|
return runWithParentSpanContext(
|
|
3730
4559
|
{
|
|
3731
4560
|
traceIdB64: toolSpan.ids.traceIdB64,
|
|
3732
4561
|
spanIdB64: toolSpan.ids.spanIdB64,
|
|
3733
|
-
eventId:
|
|
4562
|
+
eventId: state2.eventId
|
|
3734
4563
|
},
|
|
3735
4564
|
() => execute()
|
|
3736
4565
|
);
|
|
@@ -3779,35 +4608,35 @@ var RaindropTelemetryIntegration = class {
|
|
|
3779
4608
|
activeDispatch() {
|
|
3780
4609
|
var _a;
|
|
3781
4610
|
const parentTool = getCurrentParentToolContext();
|
|
3782
|
-
let
|
|
4611
|
+
let state2 = parentTool ? this.getState(parentTool.parentCallId) : void 0;
|
|
3783
4612
|
const inheritedEventId = (_a = getContextManager().getParentSpanIds()) == null ? void 0 : _a.eventId;
|
|
3784
|
-
if (!
|
|
4613
|
+
if (!state2 && inheritedEventId) {
|
|
3785
4614
|
for (const candidate of this.callStates.values()) {
|
|
3786
4615
|
if (candidate.eventId === inheritedEventId) {
|
|
3787
|
-
|
|
4616
|
+
state2 = candidate;
|
|
3788
4617
|
break;
|
|
3789
4618
|
}
|
|
3790
4619
|
}
|
|
3791
4620
|
}
|
|
3792
|
-
if (!
|
|
4621
|
+
if (!state2) return void 0;
|
|
3793
4622
|
return {
|
|
3794
|
-
eventId:
|
|
3795
|
-
userId:
|
|
3796
|
-
convoId:
|
|
3797
|
-
dispatchSpan: parentTool ?
|
|
3798
|
-
turnSpans: [
|
|
4623
|
+
eventId: state2.eventId,
|
|
4624
|
+
userId: state2.identity.userId,
|
|
4625
|
+
convoId: state2.identity.convoId,
|
|
4626
|
+
dispatchSpan: parentTool ? state2.toolSpans.get(parentTool.toolCallId) : void 0,
|
|
4627
|
+
turnSpans: [state2.rootSpan, state2.stepSpan].filter(
|
|
3799
4628
|
(span) => span !== void 0
|
|
3800
4629
|
),
|
|
3801
|
-
recordInputs:
|
|
4630
|
+
recordInputs: state2.recordInputs
|
|
3802
4631
|
};
|
|
3803
4632
|
}
|
|
3804
4633
|
/** Spans still open for an event, so a late outcome can still be stated. */
|
|
3805
4634
|
openSpansForEvent(eventId) {
|
|
3806
4635
|
const spans = [];
|
|
3807
|
-
for (const
|
|
3808
|
-
if (
|
|
3809
|
-
if (
|
|
3810
|
-
if (
|
|
4636
|
+
for (const state2 of this.callStates.values()) {
|
|
4637
|
+
if (state2.eventId !== eventId) continue;
|
|
4638
|
+
if (state2.rootSpan) spans.push(state2.rootSpan);
|
|
4639
|
+
if (state2.stepSpan) spans.push(state2.stepSpan);
|
|
3811
4640
|
}
|
|
3812
4641
|
return spans;
|
|
3813
4642
|
}
|
|
@@ -3827,10 +4656,10 @@ var RaindropTelemetryIntegration = class {
|
|
|
3827
4656
|
* created from an LLM span with output, `ai.response.text` here would state
|
|
3828
4657
|
* the run's outcome through the span while the turn is still working.
|
|
3829
4658
|
*/
|
|
3830
|
-
abortOutcomeAttrs(
|
|
3831
|
-
if (!
|
|
4659
|
+
abortOutcomeAttrs(state2, reason, finishReason) {
|
|
4660
|
+
if (!state2.handoff || state2.nestedInEvent) return [];
|
|
3832
4661
|
return [
|
|
3833
|
-
attrString("ai.response.text", capText2(
|
|
4662
|
+
attrString("ai.response.text", capText2(state2.accumulatedText || reason)),
|
|
3834
4663
|
attrString("ai.response.finishReason", finishReason)
|
|
3835
4664
|
];
|
|
3836
4665
|
}
|
|
@@ -3844,19 +4673,19 @@ var RaindropTelemetryIntegration = class {
|
|
|
3844
4673
|
spanParentRef(span) {
|
|
3845
4674
|
return { traceIdB64: span.ids.traceIdB64, spanIdB64: span.ids.spanIdB64 };
|
|
3846
4675
|
}
|
|
3847
|
-
emitLive(
|
|
4676
|
+
emitLive(state2, type, content, extra) {
|
|
3848
4677
|
var _a, _b, _c, _d, _e, _f;
|
|
3849
|
-
if (!localDebuggerEnabled() || !
|
|
3850
|
-
const callMeta = this.extractRaindropMetadata(
|
|
4678
|
+
if (!localDebuggerEnabled() || !state2.rootSpan) return;
|
|
4679
|
+
const callMeta = this.extractRaindropMetadata(state2.metadata);
|
|
3851
4680
|
sendLocalDebuggerLiveEvent({
|
|
3852
|
-
traceId:
|
|
4681
|
+
traceId: state2.rootSpan.ids.traceIdB64,
|
|
3853
4682
|
type,
|
|
3854
4683
|
content,
|
|
3855
4684
|
metadata: {
|
|
3856
4685
|
userId: (_b = callMeta.userId) != null ? _b : (_a = this.defaultContext) == null ? void 0 : _a.userId,
|
|
3857
4686
|
convoId: (_d = callMeta.convoId) != null ? _d : (_c = this.defaultContext) == null ? void 0 : _c.convoId,
|
|
3858
4687
|
eventName: (_f = callMeta.eventName) != null ? _f : (_e = this.defaultContext) == null ? void 0 : _e.eventName,
|
|
3859
|
-
eventId:
|
|
4688
|
+
eventId: state2.eventId,
|
|
3860
4689
|
...extra
|
|
3861
4690
|
}
|
|
3862
4691
|
});
|
|
@@ -3934,29 +4763,29 @@ var RaindropTelemetryIntegration = class {
|
|
|
3934
4763
|
toolCallId: toolCall.toolCallId,
|
|
3935
4764
|
toolName: toolCall.toolName
|
|
3936
4765
|
});
|
|
3937
|
-
const
|
|
3938
|
-
|
|
3939
|
-
if (!(
|
|
3940
|
-
const { operationName, resourceName } = opName("ai.toolCall",
|
|
3941
|
-
const inputAttrs =
|
|
4766
|
+
const state2 = this.getState(event.callId);
|
|
4767
|
+
state2 == null ? void 0 : state2.parentContextToolCallIds.add(toolCall.toolCallId);
|
|
4768
|
+
if (!(state2 == null ? void 0 : state2.stepParent)) return;
|
|
4769
|
+
const { operationName, resourceName } = opName("ai.toolCall", state2.functionId);
|
|
4770
|
+
const inputAttrs = state2.recordInputs ? [attrString("ai.toolCall.args", safeJsonWithUint8(toolCall.input))] : [];
|
|
3942
4771
|
const toolSpan = this.traceShipper.startSpan({
|
|
3943
4772
|
name: "ai.toolCall",
|
|
3944
|
-
parent:
|
|
3945
|
-
eventId:
|
|
3946
|
-
...
|
|
4773
|
+
parent: state2.stepParent,
|
|
4774
|
+
eventId: state2.eventId,
|
|
4775
|
+
...state2.identity,
|
|
3947
4776
|
operationId: "ai.toolCall",
|
|
3948
4777
|
attributes: [
|
|
3949
4778
|
attrString("operation.name", operationName),
|
|
3950
4779
|
attrString("resource.name", resourceName),
|
|
3951
|
-
attrString("ai.telemetry.functionId",
|
|
4780
|
+
attrString("ai.telemetry.functionId", state2.functionId),
|
|
3952
4781
|
attrString("ai.toolCall.name", toolCall.toolName),
|
|
3953
4782
|
attrString("ai.toolCall.id", toolCall.toolCallId),
|
|
3954
4783
|
...inputAttrs,
|
|
3955
|
-
...handoffSpanAttrs(
|
|
4784
|
+
...handoffSpanAttrs(state2.handoff)
|
|
3956
4785
|
]
|
|
3957
4786
|
});
|
|
3958
|
-
|
|
3959
|
-
this.emitLive(
|
|
4787
|
+
state2.toolSpans.set(toolCall.toolCallId, toolSpan);
|
|
4788
|
+
this.emitLive(state2, "tool_start", toolCall.toolName, { args: toolCall.input });
|
|
3960
4789
|
}
|
|
3961
4790
|
toolExecutionEnd(event) {
|
|
3962
4791
|
var _a;
|
|
@@ -3970,20 +4799,20 @@ var RaindropTelemetryIntegration = class {
|
|
|
3970
4799
|
clearParentToolContext();
|
|
3971
4800
|
}
|
|
3972
4801
|
}
|
|
3973
|
-
const
|
|
3974
|
-
if (!
|
|
3975
|
-
const toolSpan =
|
|
4802
|
+
const state2 = this.getState(event.callId);
|
|
4803
|
+
if (!state2) return;
|
|
4804
|
+
const toolSpan = state2.toolSpans.get(event.toolCall.toolCallId);
|
|
3976
4805
|
if (!toolSpan) return;
|
|
3977
|
-
|
|
4806
|
+
state2.toolCallCount += 1;
|
|
3978
4807
|
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 };
|
|
3979
4808
|
if (outcome.success) {
|
|
3980
|
-
const outputAttrs =
|
|
4809
|
+
const outputAttrs = state2.recordOutputs ? [attrString("ai.toolCall.result", safeJsonWithUint8(outcome.output))] : [];
|
|
3981
4810
|
this.traceShipper.endSpan(toolSpan, { attributes: outputAttrs });
|
|
3982
4811
|
} else {
|
|
3983
4812
|
this.traceShipper.endSpan(toolSpan, { error: outcome.error });
|
|
3984
4813
|
}
|
|
3985
|
-
this.emitLive(
|
|
3986
|
-
|
|
4814
|
+
this.emitLive(state2, "tool_result", event.toolCall.toolName);
|
|
4815
|
+
state2.toolSpans.delete(event.toolCall.toolCallId);
|
|
3987
4816
|
}
|
|
3988
4817
|
// ── provider-executed tool calls ─────────────────────────────────────────
|
|
3989
4818
|
//
|
|
@@ -4002,8 +4831,8 @@ var RaindropTelemetryIntegration = class {
|
|
|
4002
4831
|
//
|
|
4003
4832
|
// Client-executed tools are excluded (`providerExecuted` falsy) — they were
|
|
4004
4833
|
// already spanned during execution, so this never double-emits.
|
|
4005
|
-
emitProviderExecutedToolSpans(event,
|
|
4006
|
-
if (!
|
|
4834
|
+
emitProviderExecutedToolSpans(event, state2) {
|
|
4835
|
+
if (!state2.stepParent) return;
|
|
4007
4836
|
const content = Array.isArray(event.content) ? event.content : [];
|
|
4008
4837
|
const providerToolCalls = content.filter(
|
|
4009
4838
|
(part) => (part == null ? void 0 : part.type) === "tool-call" && part.providerExecuted === true
|
|
@@ -4016,42 +4845,42 @@ var RaindropTelemetryIntegration = class {
|
|
|
4016
4845
|
}
|
|
4017
4846
|
}
|
|
4018
4847
|
for (const call of providerToolCalls) {
|
|
4019
|
-
const { operationName, resourceName } = opName("ai.toolCall",
|
|
4020
|
-
const inputAttrs =
|
|
4848
|
+
const { operationName, resourceName } = opName("ai.toolCall", state2.functionId);
|
|
4849
|
+
const inputAttrs = state2.recordInputs ? [attrString("ai.toolCall.args", safeJsonWithUint8(call.input))] : [];
|
|
4021
4850
|
const toolSpan = this.traceShipper.startSpan({
|
|
4022
4851
|
name: "ai.toolCall",
|
|
4023
|
-
parent:
|
|
4024
|
-
eventId:
|
|
4025
|
-
...
|
|
4852
|
+
parent: state2.stepParent,
|
|
4853
|
+
eventId: state2.eventId,
|
|
4854
|
+
...state2.identity,
|
|
4026
4855
|
operationId: "ai.toolCall",
|
|
4027
4856
|
attributes: [
|
|
4028
4857
|
attrString("operation.name", operationName),
|
|
4029
4858
|
attrString("resource.name", resourceName),
|
|
4030
|
-
attrString("ai.telemetry.functionId",
|
|
4859
|
+
attrString("ai.telemetry.functionId", state2.functionId),
|
|
4031
4860
|
attrString("ai.toolCall.name", call.toolName),
|
|
4032
4861
|
attrString("ai.toolCall.id", call.toolCallId),
|
|
4033
4862
|
attrString("ai.toolCall.providerExecuted", "true"),
|
|
4034
4863
|
...inputAttrs,
|
|
4035
|
-
...handoffSpanAttrs(
|
|
4864
|
+
...handoffSpanAttrs(state2.handoff)
|
|
4036
4865
|
]
|
|
4037
4866
|
});
|
|
4038
|
-
|
|
4039
|
-
this.emitLive(
|
|
4867
|
+
state2.toolCallCount += 1;
|
|
4868
|
+
this.emitLive(state2, "tool_start", call.toolName, { args: call.input });
|
|
4040
4869
|
const resultPart = resultsByCallId.get(call.toolCallId);
|
|
4041
4870
|
if ((resultPart == null ? void 0 : resultPart.type) === "tool-error") {
|
|
4042
4871
|
this.traceShipper.endSpan(toolSpan, { error: resultPart.error });
|
|
4043
4872
|
} else {
|
|
4044
|
-
const outputAttrs =
|
|
4873
|
+
const outputAttrs = state2.recordOutputs && resultPart && "output" in resultPart ? [attrString("ai.toolCall.result", safeJsonWithUint8(resultPart.output))] : [];
|
|
4045
4874
|
this.traceShipper.endSpan(toolSpan, { attributes: outputAttrs });
|
|
4046
4875
|
}
|
|
4047
|
-
this.emitLive(
|
|
4876
|
+
this.emitLive(state2, "tool_result", call.toolName);
|
|
4048
4877
|
}
|
|
4049
4878
|
}
|
|
4050
|
-
finishGenerate(event,
|
|
4879
|
+
finishGenerate(event, state2) {
|
|
4051
4880
|
var _a, _b, _c, _d, _e, _f;
|
|
4052
|
-
if (
|
|
4881
|
+
if (state2.rootSpan) {
|
|
4053
4882
|
const outputAttrs = [];
|
|
4054
|
-
if (
|
|
4883
|
+
if (state2.recordOutputs) {
|
|
4055
4884
|
outputAttrs.push(
|
|
4056
4885
|
attrString("ai.response.finishReason", event.finishReason),
|
|
4057
4886
|
attrString("ai.response.text", capText2((_a = event.text) != null ? _a : void 0)),
|
|
@@ -4092,12 +4921,12 @@ var RaindropTelemetryIntegration = class {
|
|
|
4092
4921
|
attrInt("ai.usage.cachedInputTokens", usageMetrics.cachedInputTokens)
|
|
4093
4922
|
);
|
|
4094
4923
|
}
|
|
4095
|
-
outputAttrs.push(attrInt("ai.toolCall.count",
|
|
4096
|
-
this.traceShipper.endSpan(
|
|
4924
|
+
outputAttrs.push(attrInt("ai.toolCall.count", state2.toolCallCount));
|
|
4925
|
+
this.traceShipper.endSpan(state2.rootSpan, { attributes: outputAttrs });
|
|
4097
4926
|
}
|
|
4098
4927
|
this.finalizeGenerateEvent(
|
|
4099
|
-
|
|
4100
|
-
(_e = event.text) != null ? _e :
|
|
4928
|
+
state2,
|
|
4929
|
+
(_e = event.text) != null ? _e : state2.accumulatedText || void 0,
|
|
4101
4930
|
(_f = event.response) == null ? void 0 : _f.modelId,
|
|
4102
4931
|
hasUnresolvedToolApproval(event)
|
|
4103
4932
|
);
|
|
@@ -4113,29 +4942,29 @@ var RaindropTelemetryIntegration = class {
|
|
|
4113
4942
|
* is finalized by that resume — otherwise each execution would finalize the
|
|
4114
4943
|
* same event ID into a separate canonical row.
|
|
4115
4944
|
*/
|
|
4116
|
-
finalizeGenerateEvent(
|
|
4945
|
+
finalizeGenerateEvent(state2, output, model, keepPending = false, detachedOutcome) {
|
|
4117
4946
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
4118
|
-
const suppressSubagentEvent =
|
|
4947
|
+
const suppressSubagentEvent = state2.subagentName !== void 0 && state2.subagentToolCallSpan !== void 0;
|
|
4119
4948
|
if (!this.sendEvents || suppressSubagentEvent) return;
|
|
4120
|
-
if (this.subagents.wasSettledExplicitly(
|
|
4121
|
-
const callMeta = this.extractRaindropMetadata(
|
|
4949
|
+
if (this.subagents.wasSettledExplicitly(state2.eventId)) return;
|
|
4950
|
+
const callMeta = this.extractRaindropMetadata(state2.metadata);
|
|
4122
4951
|
const userId = (_b = callMeta.userId) != null ? _b : (_a = this.defaultContext) == null ? void 0 : _a.userId;
|
|
4123
4952
|
if (!userId) return;
|
|
4124
|
-
const eventName = (_e = (_d = callMeta.eventName) != null ? _d : (_c = this.defaultContext) == null ? void 0 : _c.eventName) != null ? _e :
|
|
4953
|
+
const eventName = (_e = (_d = callMeta.eventName) != null ? _d : (_c = this.defaultContext) == null ? void 0 : _c.eventName) != null ? _e : state2.operationId;
|
|
4125
4954
|
const cappedOutput = capText2(output);
|
|
4126
|
-
const reportedOutput =
|
|
4127
|
-
const input = capText2(
|
|
4955
|
+
const reportedOutput = state2.handoff && detachedOutcome && !(cappedOutput == null ? void 0 : cappedOutput.trim()) ? detachedOutcome.fallbackOutput : cappedOutput;
|
|
4956
|
+
const input = capText2(state2.inputText);
|
|
4128
4957
|
const properties = {
|
|
4129
4958
|
...(_f = this.defaultContext) == null ? void 0 : _f.properties,
|
|
4130
4959
|
...callMeta.properties,
|
|
4131
|
-
...
|
|
4960
|
+
...state2.handoff ? detachedOutcome == null ? void 0 : detachedOutcome.properties : void 0
|
|
4132
4961
|
};
|
|
4133
4962
|
const featureFlags = {
|
|
4134
4963
|
...((_g = this.defaultContext) == null ? void 0 : _g.featureFlags) ? normalizeFeatureFlags(this.defaultContext.featureFlags) : {},
|
|
4135
4964
|
...callMeta.featureFlags
|
|
4136
4965
|
};
|
|
4137
4966
|
const convoId = (_i = callMeta.convoId) != null ? _i : (_h = this.defaultContext) == null ? void 0 : _h.convoId;
|
|
4138
|
-
void this.eventShipper.patch(
|
|
4967
|
+
void this.eventShipper.patch(state2.eventId, {
|
|
4139
4968
|
eventName,
|
|
4140
4969
|
userId,
|
|
4141
4970
|
convoId,
|
|
@@ -4153,12 +4982,12 @@ var RaindropTelemetryIntegration = class {
|
|
|
4153
4982
|
}
|
|
4154
4983
|
});
|
|
4155
4984
|
}
|
|
4156
|
-
finishEmbed(event,
|
|
4985
|
+
finishEmbed(event, state2) {
|
|
4157
4986
|
var _a;
|
|
4158
|
-
if (!
|
|
4987
|
+
if (!state2.rootSpan) return;
|
|
4159
4988
|
const outputAttrs = [];
|
|
4160
|
-
const isMany =
|
|
4161
|
-
if (
|
|
4989
|
+
const isMany = state2.operationId === "ai.embedMany";
|
|
4990
|
+
if (state2.recordOutputs) {
|
|
4162
4991
|
if (isMany) {
|
|
4163
4992
|
outputAttrs.push(attrString("ai.embeddings", safeJsonWithUint8(event.embedding)));
|
|
4164
4993
|
} else {
|
|
@@ -4168,7 +4997,7 @@ var RaindropTelemetryIntegration = class {
|
|
|
4168
4997
|
if (((_a = event.usage) == null ? void 0 : _a.tokens) != null) {
|
|
4169
4998
|
outputAttrs.push(attrInt("ai.usage.tokens", event.usage.tokens));
|
|
4170
4999
|
}
|
|
4171
|
-
this.traceShipper.endSpan(
|
|
5000
|
+
this.traceShipper.endSpan(state2.rootSpan, { attributes: outputAttrs });
|
|
4172
5001
|
}
|
|
4173
5002
|
};
|
|
4174
5003
|
|
|
@@ -4367,7 +5196,7 @@ function createStandaloneSelfDiagnosticsTool(args) {
|
|
|
4367
5196
|
}
|
|
4368
5197
|
|
|
4369
5198
|
// src/internal/traces.ts
|
|
4370
|
-
var
|
|
5199
|
+
var TraceShipper3 = class extends TraceShipper2 {
|
|
4371
5200
|
constructor(opts) {
|
|
4372
5201
|
var _a, _b, _c;
|
|
4373
5202
|
super({
|
|
@@ -6346,11 +7175,11 @@ function userAttrsToOtlp(attrs) {
|
|
|
6346
7175
|
function envDebugEnabled() {
|
|
6347
7176
|
var _a;
|
|
6348
7177
|
if (typeof process === "undefined") return false;
|
|
6349
|
-
const
|
|
6350
|
-
return
|
|
7178
|
+
const flag2 = (_a = process.env) == null ? void 0 : _a.RAINDROP_AI_DEBUG;
|
|
7179
|
+
return flag2 === "1" || flag2 === "true";
|
|
6351
7180
|
}
|
|
6352
7181
|
function createRaindropAISDK(opts) {
|
|
6353
|
-
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;
|
|
6354
7183
|
const writeKey = opts.writeKey;
|
|
6355
7184
|
const eventsRequested = ((_a = opts.events) == null ? void 0 : _a.enabled) !== false;
|
|
6356
7185
|
const tracesRequested = ((_b = opts.traces) == null ? void 0 : _b.enabled) !== false;
|
|
@@ -6359,37 +7188,53 @@ function createRaindropAISDK(opts) {
|
|
|
6359
7188
|
const localWorkshopInput = opts.localWorkshopUrl === false ? null : opts.localWorkshopUrl;
|
|
6360
7189
|
const resolvedLocalDebuggerUrl = resolveLocalDebuggerBaseUrl(localWorkshopInput);
|
|
6361
7190
|
const localDebuggerUrl = localWorkshopInput === null ? null : resolvedLocalDebuggerUrl != null ? resolvedLocalDebuggerUrl : void 0;
|
|
6362
|
-
const
|
|
6363
|
-
const eventsEnabled = eventsRequested &&
|
|
6364
|
-
const tracesEnabled = tracesRequested &&
|
|
6365
|
-
|
|
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)) {
|
|
6366
7199
|
console.warn(
|
|
6367
7200
|
"[raindrop-ai/ai-sdk] writeKey not provided and no local Workshop reachable; telemetry shipping is disabled"
|
|
6368
7201
|
);
|
|
6369
7202
|
}
|
|
6370
|
-
|
|
6371
|
-
|
|
6372
|
-
|
|
6373
|
-
|
|
6374
|
-
|
|
6375
|
-
|
|
6376
|
-
|
|
6377
|
-
|
|
6378
|
-
|
|
6379
|
-
|
|
6380
|
-
|
|
6381
|
-
|
|
6382
|
-
|
|
6383
|
-
|
|
6384
|
-
|
|
6385
|
-
|
|
6386
|
-
|
|
6387
|
-
|
|
6388
|
-
|
|
6389
|
-
|
|
6390
|
-
|
|
6391
|
-
|
|
6392
|
-
|
|
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
|
+
}
|
|
6393
7238
|
const settledEventIds = /* @__PURE__ */ new Set();
|
|
6394
7239
|
const subagentApi = new SubagentApi({
|
|
6395
7240
|
traceShipper,
|
|
@@ -6557,7 +7402,14 @@ function createRaindropAISDK(opts) {
|
|
|
6557
7402
|
await Promise.all([eventShipper.flush(), traceShipper.flush()]);
|
|
6558
7403
|
},
|
|
6559
7404
|
async shutdown() {
|
|
6560
|
-
|
|
7405
|
+
try {
|
|
7406
|
+
await Promise.all([eventShipper.shutdown(), traceShipper.shutdown()]);
|
|
7407
|
+
} finally {
|
|
7408
|
+
try {
|
|
7409
|
+
appGitContext.dispose();
|
|
7410
|
+
} catch (e) {
|
|
7411
|
+
}
|
|
7412
|
+
}
|
|
6561
7413
|
}
|
|
6562
7414
|
};
|
|
6563
7415
|
}
|