@raindrop-ai/claude-code 0.0.18 → 0.0.20
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/.claude-plugin/plugin.json +1 -1
- package/README.md +4 -0
- package/dist/cli.js +1354 -164
- package/dist/index.cjs +1296 -125
- package/dist/index.d.cts +110 -10
- package/dist/index.d.ts +110 -10
- package/dist/index.js +1295 -125
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,4 +1,518 @@
|
|
|
1
|
-
// ../core/dist/chunk-
|
|
1
|
+
// ../core/dist/chunk-BYBMRLZM.js
|
|
2
|
+
var EVAL_CORRELATION_ID_ATTRIBUTE = "raindrop.eval_correlation_id";
|
|
3
|
+
var PROBE_SCOPE = { correlationId: "" };
|
|
4
|
+
var EvalScopeStorage = class {
|
|
5
|
+
constructor() {
|
|
6
|
+
this._als = null;
|
|
7
|
+
this._probed = false;
|
|
8
|
+
}
|
|
9
|
+
maybeAdoptAsyncLocalStorage() {
|
|
10
|
+
if (this._probed) return;
|
|
11
|
+
this._probed = true;
|
|
12
|
+
try {
|
|
13
|
+
const Ctor = globalThis.RAINDROP_ASYNC_LOCAL_STORAGE;
|
|
14
|
+
if (!Ctor) return;
|
|
15
|
+
const als = new Ctor();
|
|
16
|
+
als.run(PROBE_SCOPE, () => {
|
|
17
|
+
});
|
|
18
|
+
this._als = als;
|
|
19
|
+
} catch (e) {
|
|
20
|
+
this._als = null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
run(scope, callback) {
|
|
24
|
+
this.maybeAdoptAsyncLocalStorage();
|
|
25
|
+
if (this._als) return this._als.run(scope, callback);
|
|
26
|
+
const previous = this._syncScope;
|
|
27
|
+
this._syncScope = scope;
|
|
28
|
+
try {
|
|
29
|
+
return callback();
|
|
30
|
+
} finally {
|
|
31
|
+
this._syncScope = previous;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
current() {
|
|
35
|
+
this.maybeAdoptAsyncLocalStorage();
|
|
36
|
+
if (this._als) return this._als.getStore();
|
|
37
|
+
return this._syncScope;
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
var EVAL_SCOPE_STORAGE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.evalScopeStorage");
|
|
41
|
+
function evalScopeStorage() {
|
|
42
|
+
const holder = globalThis;
|
|
43
|
+
let storage = holder[EVAL_SCOPE_STORAGE_KEY];
|
|
44
|
+
if (!storage) {
|
|
45
|
+
storage = new EvalScopeStorage();
|
|
46
|
+
holder[EVAL_SCOPE_STORAGE_KEY] = storage;
|
|
47
|
+
}
|
|
48
|
+
return storage;
|
|
49
|
+
}
|
|
50
|
+
function currentEvalScope() {
|
|
51
|
+
try {
|
|
52
|
+
return evalScopeStorage().current();
|
|
53
|
+
} catch (e) {
|
|
54
|
+
return void 0;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function evalScopeAttributes() {
|
|
58
|
+
const scope = currentEvalScope();
|
|
59
|
+
if (!scope) return {};
|
|
60
|
+
return { [EVAL_CORRELATION_ID_ATTRIBUTE]: scope.correlationId };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// ../core/dist/chunk-WJOR6M7H.js
|
|
64
|
+
var STATE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.replayTraceRoutingState");
|
|
65
|
+
function state() {
|
|
66
|
+
const holder = globalThis;
|
|
67
|
+
let current = holder[STATE_KEY];
|
|
68
|
+
if (!current) {
|
|
69
|
+
let storage = null;
|
|
70
|
+
try {
|
|
71
|
+
const Ctor = globalThis.RAINDROP_ASYNC_LOCAL_STORAGE;
|
|
72
|
+
if (Ctor) storage = new Ctor();
|
|
73
|
+
} catch (e) {
|
|
74
|
+
storage = null;
|
|
75
|
+
}
|
|
76
|
+
current = {
|
|
77
|
+
storage,
|
|
78
|
+
syncDestination: void 0,
|
|
79
|
+
spanDestinations: /* @__PURE__ */ new WeakMap()
|
|
80
|
+
};
|
|
81
|
+
holder[STATE_KEY] = current;
|
|
82
|
+
}
|
|
83
|
+
return current;
|
|
84
|
+
}
|
|
85
|
+
function currentReplayTraceDestination() {
|
|
86
|
+
var _a, _b;
|
|
87
|
+
const routing = state();
|
|
88
|
+
return (_b = (_a = routing.storage) == null ? void 0 : _a.getStore()) != null ? _b : routing.syncDestination;
|
|
89
|
+
}
|
|
90
|
+
function rememberReplayTraceDestination(span) {
|
|
91
|
+
const destination = currentReplayTraceDestination();
|
|
92
|
+
if (destination) state().spanDestinations.set(span, destination);
|
|
93
|
+
}
|
|
94
|
+
function copyReplayTraceDestination(source, target) {
|
|
95
|
+
const destination = state().spanDestinations.get(source);
|
|
96
|
+
if (destination) state().spanDestinations.set(target, destination);
|
|
97
|
+
}
|
|
98
|
+
function replayTraceDestinationFor(value) {
|
|
99
|
+
if (typeof value !== "object" && typeof value !== "function" || value === null) {
|
|
100
|
+
return void 0;
|
|
101
|
+
}
|
|
102
|
+
return state().spanDestinations.get(value);
|
|
103
|
+
}
|
|
104
|
+
function recordReplayExportedSpan(destination, spanId, traceId) {
|
|
105
|
+
var _a, _b;
|
|
106
|
+
if (!destination || !spanId || !traceId) return;
|
|
107
|
+
(_a = destination.exportedSpanIds) == null ? void 0 : _a.add(spanId);
|
|
108
|
+
(_b = destination.exportedTraceIds) == null ? void 0 : _b.add(traceId);
|
|
109
|
+
}
|
|
110
|
+
function replayTraceUrl(baseUrl) {
|
|
111
|
+
return `${baseUrl.replace(/\/+$/, "")}/v1/traces`;
|
|
112
|
+
}
|
|
113
|
+
function getAsyncLocalStorageCtor() {
|
|
114
|
+
return globalThis.RAINDROP_ASYNC_LOCAL_STORAGE;
|
|
115
|
+
}
|
|
116
|
+
var MAX_BINDING_STACK = 128;
|
|
117
|
+
var EMPTY_STACK = [];
|
|
118
|
+
var ContextStackStorage = class {
|
|
119
|
+
/** Emitted once when this runtime cannot support an ambient push. */
|
|
120
|
+
constructor(noAmbientBindWarning) {
|
|
121
|
+
this.noAmbientBindWarning = noAmbientBindWarning;
|
|
122
|
+
this._als = null;
|
|
123
|
+
this._enterWithUsable = false;
|
|
124
|
+
this._syncStack = EMPTY_STACK;
|
|
125
|
+
this._adoptionChecked = false;
|
|
126
|
+
this._warnedNoAmbientBind = false;
|
|
127
|
+
}
|
|
128
|
+
maybeAdoptAsyncLocalStorage() {
|
|
129
|
+
if (this._adoptionChecked) return;
|
|
130
|
+
this._adoptionChecked = true;
|
|
131
|
+
const Ctor = getAsyncLocalStorageCtor();
|
|
132
|
+
if (!Ctor) return;
|
|
133
|
+
const als = new Ctor();
|
|
134
|
+
try {
|
|
135
|
+
als.run(EMPTY_STACK, () => {
|
|
136
|
+
});
|
|
137
|
+
} catch (e) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
this._als = als;
|
|
141
|
+
if (typeof als.enterWith === "function") {
|
|
142
|
+
try {
|
|
143
|
+
als.enterWith(EMPTY_STACK);
|
|
144
|
+
this._enterWithUsable = true;
|
|
145
|
+
} catch (e) {
|
|
146
|
+
this._enterWithUsable = false;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
getStack() {
|
|
151
|
+
var _a;
|
|
152
|
+
this.maybeAdoptAsyncLocalStorage();
|
|
153
|
+
if (this._als) return (_a = this._als.getStore()) != null ? _a : this._syncStack;
|
|
154
|
+
return this._syncStack;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Persist an ambient stack mutation. Returns false when an ALS is adopted but
|
|
158
|
+
* `enterWith` is unusable (workerd): callers must NOT fall back to the
|
|
159
|
+
* process-shared sync stack, since concurrent isolates would cross-stamp.
|
|
160
|
+
*/
|
|
161
|
+
setAmbientStack(stack) {
|
|
162
|
+
if (this._als) {
|
|
163
|
+
if (!this._enterWithUsable) return false;
|
|
164
|
+
this._als.enterWith(stack);
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
167
|
+
this._syncStack = stack;
|
|
168
|
+
return true;
|
|
169
|
+
}
|
|
170
|
+
push(binding) {
|
|
171
|
+
this.maybeAdoptAsyncLocalStorage();
|
|
172
|
+
if (this._als && !this._enterWithUsable) {
|
|
173
|
+
this.warnNoAmbientBindOnce();
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
let stack = this.getStack();
|
|
177
|
+
if (stack.length >= MAX_BINDING_STACK) {
|
|
178
|
+
stack = stack.filter((b) => b.isLive());
|
|
179
|
+
if (stack.length >= MAX_BINDING_STACK) {
|
|
180
|
+
stack = stack.slice(stack.length - (MAX_BINDING_STACK - 1));
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
this.setAmbientStack([...stack, binding]);
|
|
184
|
+
}
|
|
185
|
+
remove(binding) {
|
|
186
|
+
binding.markDead();
|
|
187
|
+
const stack = this.getStack();
|
|
188
|
+
const pruned = stack.filter((b) => b !== binding && b.isLive());
|
|
189
|
+
if (pruned.length !== stack.length) {
|
|
190
|
+
this.setAmbientStack(pruned);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
runWith(binding, callback) {
|
|
194
|
+
this.maybeAdoptAsyncLocalStorage();
|
|
195
|
+
if (this._als) {
|
|
196
|
+
return this._als.run([...this.getStack(), binding], callback);
|
|
197
|
+
}
|
|
198
|
+
const previous = this._syncStack;
|
|
199
|
+
this._syncStack = [...previous, binding];
|
|
200
|
+
try {
|
|
201
|
+
return callback();
|
|
202
|
+
} finally {
|
|
203
|
+
this._syncStack = previous;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
current() {
|
|
207
|
+
const stack = this.getStack();
|
|
208
|
+
if (stack.length === 0) return void 0;
|
|
209
|
+
const top = stack[stack.length - 1];
|
|
210
|
+
if (top.isLive()) return top;
|
|
211
|
+
const pruned = stack.filter((b) => b.isLive());
|
|
212
|
+
this.setAmbientStack(pruned);
|
|
213
|
+
return pruned.length > 0 ? pruned[pruned.length - 1] : void 0;
|
|
214
|
+
}
|
|
215
|
+
warnNoAmbientBindOnce() {
|
|
216
|
+
if (this._warnedNoAmbientBind) return;
|
|
217
|
+
this._warnedNoAmbientBind = true;
|
|
218
|
+
console.warn(this.noAmbientBindWarning);
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
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.";
|
|
222
|
+
var ROUTING_STORAGE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.routingContextStorage");
|
|
223
|
+
function routingStorage() {
|
|
224
|
+
const holder = globalThis;
|
|
225
|
+
let storage = holder[ROUTING_STORAGE_KEY];
|
|
226
|
+
if (!storage) {
|
|
227
|
+
storage = new ContextStackStorage(NO_AMBIENT_ROUTING_BIND_WARNING);
|
|
228
|
+
holder[ROUTING_STORAGE_KEY] = storage;
|
|
229
|
+
}
|
|
230
|
+
return storage;
|
|
231
|
+
}
|
|
232
|
+
function currentRoutingBinding() {
|
|
233
|
+
const bound = routingStorage().current();
|
|
234
|
+
if (!bound) return void 0;
|
|
235
|
+
return {
|
|
236
|
+
projectId: bound.projectId,
|
|
237
|
+
authHint: bound.authHint,
|
|
238
|
+
...bound.appGit ? { appGit: bound.appGit } : {},
|
|
239
|
+
...bound.appGitSource ? { appGitSource: bound.appGitSource } : {}
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
var APP_COMMIT_SHA = "raindrop.app.commit_sha";
|
|
243
|
+
var APP_COMMIT_DIRTY = "raindrop.app.commit_dirty";
|
|
244
|
+
var APP_BRANCH = "raindrop.app.branch";
|
|
245
|
+
var APP_GIT_KEYS = [APP_COMMIT_SHA, APP_COMMIT_DIRTY, APP_BRANCH];
|
|
246
|
+
var own = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
247
|
+
function appGitExplicitKeys(properties) {
|
|
248
|
+
const keys = /* @__PURE__ */ new Set();
|
|
249
|
+
if (!properties) return keys;
|
|
250
|
+
for (const key of APP_GIT_KEYS) {
|
|
251
|
+
if (own(properties, key)) keys.add(key);
|
|
252
|
+
}
|
|
253
|
+
return keys;
|
|
254
|
+
}
|
|
255
|
+
function mergeAppGitSnapshot(base, properties, explicitKeys = /* @__PURE__ */ new Set()) {
|
|
256
|
+
try {
|
|
257
|
+
const result = { ...base };
|
|
258
|
+
if (properties && own(properties, APP_COMMIT_SHA) && properties[APP_COMMIT_SHA] !== result[APP_COMMIT_SHA]) {
|
|
259
|
+
if (!explicitKeys.has(APP_COMMIT_DIRTY) && !own(properties, APP_COMMIT_DIRTY)) {
|
|
260
|
+
delete result[APP_COMMIT_DIRTY];
|
|
261
|
+
}
|
|
262
|
+
if (!explicitKeys.has(APP_BRANCH) && !own(properties, APP_BRANCH)) {
|
|
263
|
+
delete result[APP_BRANCH];
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
for (const key of APP_GIT_KEYS) {
|
|
267
|
+
if (properties && own(properties, key)) result[key] = properties[key];
|
|
268
|
+
}
|
|
269
|
+
return Object.freeze(result);
|
|
270
|
+
} catch (e) {
|
|
271
|
+
return Object.freeze({});
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
function validAppCommitSha(value) {
|
|
275
|
+
if (typeof value !== "string" || value.length > 128) return void 0;
|
|
276
|
+
const cleaned = value.trim();
|
|
277
|
+
return /^(?:[a-fA-F0-9]{40}|[a-fA-F0-9]{64})$/.test(cleaned) ? cleaned.toLowerCase() : void 0;
|
|
278
|
+
}
|
|
279
|
+
function shortString(value) {
|
|
280
|
+
if (typeof value !== "string" || value.length > 1024) return void 0;
|
|
281
|
+
const cleaned = value.trim();
|
|
282
|
+
return cleaned.length > 0 ? cleaned : void 0;
|
|
283
|
+
}
|
|
284
|
+
function flag(value) {
|
|
285
|
+
if (value === true || value === "true" || value === "1") return true;
|
|
286
|
+
if (value === false || value === "false" || value === "0") return false;
|
|
287
|
+
return void 0;
|
|
288
|
+
}
|
|
289
|
+
function environment() {
|
|
290
|
+
try {
|
|
291
|
+
return typeof process === "undefined" ? {} : process.env;
|
|
292
|
+
} catch (e) {
|
|
293
|
+
return {};
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
var DEPLOYMENTS = [
|
|
297
|
+
["VERCEL", "VERCEL_GIT_COMMIT_SHA", "VERCEL_GIT_COMMIT_REF"],
|
|
298
|
+
["NETLIFY", "COMMIT_REF", "BRANCH"],
|
|
299
|
+
["RAILWAY_ENVIRONMENT_NAME", "RAILWAY_GIT_COMMIT_SHA", "RAILWAY_GIT_BRANCH"],
|
|
300
|
+
["RAILWAY_ENVIRONMENT", "RAILWAY_GIT_COMMIT_SHA", "RAILWAY_GIT_BRANCH"],
|
|
301
|
+
["RENDER", "RENDER_GIT_COMMIT", "RENDER_GIT_BRANCH"],
|
|
302
|
+
["DYNO", "HEROKU_BUILD_COMMIT", ""],
|
|
303
|
+
["DYNO", "HEROKU_SLUG_COMMIT", ""],
|
|
304
|
+
["AWS_APP_ID", "AWS_COMMIT_ID", "AWS_BRANCH"],
|
|
305
|
+
["WORKERS_CI", "WORKERS_CI_COMMIT_SHA", "WORKERS_CI_BRANCH"]
|
|
306
|
+
];
|
|
307
|
+
var CI_SOURCES = [
|
|
308
|
+
["GITHUB_ACTIONS", "GITHUB_SHA", "GITHUB_REF_NAME"],
|
|
309
|
+
["GITLAB_CI", "CI_COMMIT_SHA", "CI_COMMIT_REF_NAME"],
|
|
310
|
+
["CIRCLECI", "CIRCLE_SHA1", "CIRCLE_BRANCH"]
|
|
311
|
+
];
|
|
312
|
+
function detectedSource(env, table, detectBranch) {
|
|
313
|
+
for (const row of table) {
|
|
314
|
+
const [marker, shaKey, branchKey] = row;
|
|
315
|
+
if (!marker || !shaKey || !shortString(env[marker]) || flag(env[marker]) === false) continue;
|
|
316
|
+
const commitSha = validAppCommitSha(env[shaKey]);
|
|
317
|
+
if (commitSha)
|
|
318
|
+
return {
|
|
319
|
+
commitSha,
|
|
320
|
+
...detectBranch && branchKey ? { branch: shortString(env[branchKey]) } : {}
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
return {};
|
|
324
|
+
}
|
|
325
|
+
var AppGitContextImpl = class {
|
|
326
|
+
constructor(options, runtime = {}) {
|
|
327
|
+
this.defaults = {};
|
|
328
|
+
this.explicit = {};
|
|
329
|
+
this.explicitKeys = /* @__PURE__ */ new Set();
|
|
330
|
+
this.disposed = false;
|
|
331
|
+
this.operations = /* @__PURE__ */ new Map();
|
|
332
|
+
this.operationOverflow = false;
|
|
333
|
+
this.detectBranch = false;
|
|
334
|
+
this.disabled = false;
|
|
335
|
+
var _a, _b, _c, _d, _e, _f;
|
|
336
|
+
try {
|
|
337
|
+
if (options === false) {
|
|
338
|
+
this.disabled = true;
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
const opts = options != null ? options : {};
|
|
342
|
+
const env = (_a = runtime.env) != null ? _a : environment();
|
|
343
|
+
const detectBranch = (_c = (_b = flag(opts.detectBranch)) != null ? _b : flag(env.RAINDROP_GIT_DETECT_BRANCH)) != null ? _c : false;
|
|
344
|
+
this.detectBranch = detectBranch;
|
|
345
|
+
const collectBranch = detectBranch || runtime.captureLegacyReplayBranch === true;
|
|
346
|
+
const autoDetect = runtime.allowDiscovery === false ? false : (_e = (_d = flag(opts.autoDetect)) != null ? _d : flag(env.RAINDROP_GIT_AUTO_DETECT)) != null ? _e : true;
|
|
347
|
+
const configuredSha = opts.commitSha;
|
|
348
|
+
const explicitSha = configuredSha === void 0 ? env.RAINDROP_COMMIT_SHA : configuredSha;
|
|
349
|
+
if (explicitSha === null) this.explicit[APP_COMMIT_SHA] = null;
|
|
350
|
+
else if (typeof explicitSha === "string" && validAppCommitSha(explicitSha))
|
|
351
|
+
this.explicit[APP_COMMIT_SHA] = explicitSha;
|
|
352
|
+
const configuredDirty = opts.commitDirty;
|
|
353
|
+
const explicitDirty = configuredDirty === void 0 ? flag(env.RAINDROP_COMMIT_DIRTY) : configuredDirty;
|
|
354
|
+
if (explicitDirty === null || typeof explicitDirty === "boolean")
|
|
355
|
+
this.explicit[APP_COMMIT_DIRTY] = explicitDirty;
|
|
356
|
+
const configuredBranch = opts.branch;
|
|
357
|
+
const explicitBranch = configuredBranch === void 0 ? env.RAINDROP_BRANCH : configuredBranch;
|
|
358
|
+
if (explicitBranch === null) this.explicit[APP_BRANCH] = null;
|
|
359
|
+
else if (typeof explicitBranch === "string" && explicitBranch.length <= 1024)
|
|
360
|
+
this.explicit[APP_BRANCH] = explicitBranch;
|
|
361
|
+
this.explicitKeys = appGitExplicitKeys(this.explicit);
|
|
362
|
+
this.defaults = { ...this.explicit };
|
|
363
|
+
if (!autoDetect || explicitSha !== void 0) return;
|
|
364
|
+
const sourceDirectory = (_f = shortString(opts.sourceDirectory)) != null ? _f : shortString(env.RAINDROP_GIT_SOURCE_DIRECTORY);
|
|
365
|
+
if (runtime.allowLocalGit === false && !sourceDirectory) return;
|
|
366
|
+
const deploy = sourceDirectory ? {} : detectedSource(env, DEPLOYMENTS, collectBranch);
|
|
367
|
+
if (deploy.commitSha) {
|
|
368
|
+
this.accept(deploy);
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
const fallback = sourceDirectory ? {} : detectedSource(env, CI_SOURCES, collectBranch);
|
|
372
|
+
if (runtime.resolveLocal && (runtime.allowLocalGit !== false || sourceDirectory)) {
|
|
373
|
+
this.cancel = runtime.resolveLocal(sourceDirectory, collectBranch, (result) => {
|
|
374
|
+
try {
|
|
375
|
+
if (!this.disposed) this.accept(result.commitSha ? result : fallback);
|
|
376
|
+
} catch (e) {
|
|
377
|
+
}
|
|
378
|
+
});
|
|
379
|
+
} else this.accept(fallback);
|
|
380
|
+
} catch (e) {
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
accept(result) {
|
|
384
|
+
const sha = validAppCommitSha(result.commitSha);
|
|
385
|
+
if (!sha) return;
|
|
386
|
+
this.replayBranch = shortString(result.branch);
|
|
387
|
+
this.defaults = {
|
|
388
|
+
[APP_COMMIT_SHA]: sha,
|
|
389
|
+
...typeof result.commitDirty === "boolean" ? { [APP_COMMIT_DIRTY]: result.commitDirty } : {},
|
|
390
|
+
...this.detectBranch && this.replayBranch ? { [APP_BRANCH]: this.replayBranch } : {},
|
|
391
|
+
...this.explicit
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
snapshot(properties) {
|
|
395
|
+
var _a;
|
|
396
|
+
try {
|
|
397
|
+
const binding = currentRoutingBinding();
|
|
398
|
+
const base = this.disabled && (binding == null ? void 0 : binding.appGitSource) !== "replay-override" ? {} : (_a = binding == null ? void 0 : binding.appGit) != null ? _a : this.defaults;
|
|
399
|
+
return this.mergeSnapshot(base, properties);
|
|
400
|
+
} catch (e) {
|
|
401
|
+
return Object.freeze({});
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
/** Safe defaults when no operation/span start was observed; never infer identity. */
|
|
405
|
+
snapshotExplicit(properties, eventId) {
|
|
406
|
+
try {
|
|
407
|
+
const base = { ...this.explicit };
|
|
408
|
+
const operation = eventId ? this.operations.get(eventId) : void 0;
|
|
409
|
+
if (operation) {
|
|
410
|
+
for (const key of operation.explicitKeys) base[key] = operation.snapshot[key];
|
|
411
|
+
}
|
|
412
|
+
return this.mergeSnapshot(base, properties, new Set(Object.keys(base)));
|
|
413
|
+
} catch (e) {
|
|
414
|
+
return mergeAppGitSnapshot({}, properties);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
/** Existing replay branch reporting stays separate from opt-in event properties. */
|
|
418
|
+
snapshotForReplay() {
|
|
419
|
+
const snapshot = this.snapshot();
|
|
420
|
+
if (this.replayBranch && !own(snapshot, APP_BRANCH) && snapshot[APP_COMMIT_SHA] === this.defaults[APP_COMMIT_SHA]) {
|
|
421
|
+
return Object.freeze({ ...snapshot, [APP_BRANCH]: this.replayBranch });
|
|
422
|
+
}
|
|
423
|
+
return snapshot;
|
|
424
|
+
}
|
|
425
|
+
/** Merge a frozen span snapshot without losing client-authored provenance. */
|
|
426
|
+
mergeSnapshot(base, properties, explicitKeys = this.explicitKeys) {
|
|
427
|
+
return mergeAppGitSnapshot(base, properties, /* @__PURE__ */ new Set([...this.explicitKeys, ...explicitKeys]));
|
|
428
|
+
}
|
|
429
|
+
/** Shippers belonging to one client share this bounded operation registry. */
|
|
430
|
+
forOperation(eventId, properties, owner) {
|
|
431
|
+
if (!eventId) return this.snapshot(properties);
|
|
432
|
+
let operation = this.operations.get(eventId);
|
|
433
|
+
if (!operation) {
|
|
434
|
+
if (this.operations.size >= 1e4) this.operationOverflow = true;
|
|
435
|
+
if (this.operationOverflow) return this.mergeSnapshot({}, properties);
|
|
436
|
+
operation = {
|
|
437
|
+
snapshot: this.snapshot(properties),
|
|
438
|
+
owners: /* @__PURE__ */ new Set(),
|
|
439
|
+
unowned: owner === void 0,
|
|
440
|
+
explicitKeys: appGitExplicitKeys(properties)
|
|
441
|
+
};
|
|
442
|
+
this.operations.set(eventId, operation);
|
|
443
|
+
} else if (properties && APP_GIT_KEYS.some((key) => own(properties, key))) {
|
|
444
|
+
const explicitKeys = /* @__PURE__ */ new Set([...this.explicitKeys, ...operation.explicitKeys]);
|
|
445
|
+
operation.snapshot = this.mergeSnapshot(operation.snapshot, properties, explicitKeys);
|
|
446
|
+
for (const key of appGitExplicitKeys(properties)) operation.explicitKeys.add(key);
|
|
447
|
+
}
|
|
448
|
+
if (!owner) operation.unowned = true;
|
|
449
|
+
if (owner) operation.owners.add(owner);
|
|
450
|
+
return operation.snapshot;
|
|
451
|
+
}
|
|
452
|
+
releaseOperation(eventId, owner) {
|
|
453
|
+
const operation = this.operations.get(eventId);
|
|
454
|
+
if (!operation) return;
|
|
455
|
+
operation.owners.delete(owner);
|
|
456
|
+
if (operation.owners.size === 0 && !operation.unowned) this.operations.delete(eventId);
|
|
457
|
+
}
|
|
458
|
+
finishOperation(eventId) {
|
|
459
|
+
this.operations.delete(eventId);
|
|
460
|
+
}
|
|
461
|
+
dispose() {
|
|
462
|
+
var _a;
|
|
463
|
+
this.disposed = true;
|
|
464
|
+
try {
|
|
465
|
+
(_a = this.cancel) == null ? void 0 : _a.call(this);
|
|
466
|
+
} catch (e) {
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
};
|
|
470
|
+
var AppGitContext = AppGitContextImpl;
|
|
471
|
+
function createAppGitContext(options, runtime = {}) {
|
|
472
|
+
return new AppGitContext(options, runtime);
|
|
473
|
+
}
|
|
474
|
+
function withAppGitProperties(properties, snapshot) {
|
|
475
|
+
try {
|
|
476
|
+
const merged = { ...properties };
|
|
477
|
+
for (const key of APP_GIT_KEYS)
|
|
478
|
+
if (!own(merged, key) && own(snapshot, key)) merged[key] = snapshot[key];
|
|
479
|
+
return merged;
|
|
480
|
+
} catch (e) {
|
|
481
|
+
return properties != null ? properties : {};
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
function withAppGitAttributes(attributes, snapshot) {
|
|
485
|
+
try {
|
|
486
|
+
const present = new Set(attributes.flatMap((attr) => attr ? [attr.key] : []));
|
|
487
|
+
const added = [];
|
|
488
|
+
for (const key of APP_GIT_KEYS) {
|
|
489
|
+
if (present.has(key) || present.has(`ai.telemetry.metadata.${key}`) || present.has(`traceloop.association.properties.${key}`))
|
|
490
|
+
continue;
|
|
491
|
+
const value = snapshot[key];
|
|
492
|
+
if (typeof value === "string") added.push({ key, value: { stringValue: value } });
|
|
493
|
+
else if (typeof value === "boolean") added.push({ key, value: { boolValue: value } });
|
|
494
|
+
}
|
|
495
|
+
return added.length ? [...attributes, ...added] : attributes;
|
|
496
|
+
} catch (e) {
|
|
497
|
+
return attributes;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
function appGitPropertiesFromAttributes(attributes) {
|
|
501
|
+
var _a, _b, _c;
|
|
502
|
+
const properties = {};
|
|
503
|
+
try {
|
|
504
|
+
for (const attr of attributes) {
|
|
505
|
+
if (!attr) continue;
|
|
506
|
+
for (const key of APP_GIT_KEYS) {
|
|
507
|
+
if (attr.key === key || attr.key === `ai.telemetry.metadata.${key}` || attr.key === `traceloop.association.properties.${key}`) {
|
|
508
|
+
properties[key] = (_c = (_b = (_a = attr.value.stringValue) != null ? _a : attr.value.boolValue) != null ? _b : attr.value.intValue) != null ? _c : null;
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
} catch (e) {
|
|
513
|
+
}
|
|
514
|
+
return properties;
|
|
515
|
+
}
|
|
2
516
|
function getCrypto() {
|
|
3
517
|
const c = globalThis.crypto;
|
|
4
518
|
return c;
|
|
@@ -13,6 +527,17 @@ function randomBytes(length) {
|
|
|
13
527
|
for (let i = 0; i < out.length; i++) out[i] = Math.floor(Math.random() * 256);
|
|
14
528
|
return out;
|
|
15
529
|
}
|
|
530
|
+
function randomUUID() {
|
|
531
|
+
const cryptoObj = getCrypto();
|
|
532
|
+
if (cryptoObj && typeof cryptoObj.randomUUID === "function") {
|
|
533
|
+
return cryptoObj.randomUUID();
|
|
534
|
+
}
|
|
535
|
+
const b = randomBytes(16);
|
|
536
|
+
b[6] = b[6] & 15 | 64;
|
|
537
|
+
b[8] = b[8] & 63 | 128;
|
|
538
|
+
const hex = [...b].map((x) => x.toString(16).padStart(2, "0")).join("");
|
|
539
|
+
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
540
|
+
}
|
|
16
541
|
function base64Encode(bytes) {
|
|
17
542
|
const maybeBuffer = globalThis.Buffer;
|
|
18
543
|
if (maybeBuffer) {
|
|
@@ -42,6 +567,39 @@ function base64Encode(bytes) {
|
|
|
42
567
|
}
|
|
43
568
|
return out;
|
|
44
569
|
}
|
|
570
|
+
function base64ToHex(value) {
|
|
571
|
+
if (!value) return "";
|
|
572
|
+
const maybeBuffer = globalThis.Buffer;
|
|
573
|
+
if (maybeBuffer) {
|
|
574
|
+
return maybeBuffer.from(value, "base64").toString("hex");
|
|
575
|
+
}
|
|
576
|
+
const atobFn = globalThis.atob;
|
|
577
|
+
if (typeof atobFn !== "function") return "";
|
|
578
|
+
try {
|
|
579
|
+
const binary = atobFn(value);
|
|
580
|
+
let hex = "";
|
|
581
|
+
for (let i = 0; i < binary.length; i++) {
|
|
582
|
+
hex += (binary.charCodeAt(i) & 255).toString(16).padStart(2, "0");
|
|
583
|
+
}
|
|
584
|
+
return hex;
|
|
585
|
+
} catch (e) {
|
|
586
|
+
return "";
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
var HANDOFF_ATTRIBUTE_SUFFIXES = {
|
|
590
|
+
mode: "raindrop.handoff.mode",
|
|
591
|
+
childEventId: "raindrop.handoff.childEventId",
|
|
592
|
+
parentEventId: "raindrop.handoff.parentEventId",
|
|
593
|
+
parentSpanId: "raindrop.handoff.parentSpanId",
|
|
594
|
+
name: "raindrop.handoff.name",
|
|
595
|
+
terminal: "raindrop.handoff.terminal",
|
|
596
|
+
agentRole: "raindrop.agent.role"
|
|
597
|
+
};
|
|
598
|
+
var HANDOFF_TERMINAL_PROPERTY_KEY = HANDOFF_ATTRIBUTE_SUFFIXES.terminal;
|
|
599
|
+
var TRACEPARENT_HEADER = "traceparent";
|
|
600
|
+
var BAGGAGE_HEADER = "baggage";
|
|
601
|
+
var HANDOFF_HEADER = "x-raindrop-handoff";
|
|
602
|
+
var UNRESOLVED_CARRIER_WARNING = `[raindrop] resume: headers were supplied but no hand-off carrier was found on them (searched ${HANDOFF_HEADER}, ${TRACEPARENT_HEADER}, ${BAGGAGE_HEADER}). This run reports as an UNLINKED event, and the launcher that dispatched it will stay on "queued" forever because nothing ever references its child. Passing headers means a parent handed off, so no carrier on them is almost certainly a defect: a gateway or proxy stripping ${HANDOFF_HEADER}, a middleware overwriting ${BAGGAGE_HEADER}, a request forwarded without its headers, or a hand-built carrier whose field names do not match. Send every header the launcher's dispatch returned. Logged once per process; pass no headers for a directly-invoked sub-agent to silence it.`;
|
|
45
603
|
function runWithTracingSuppressed(fn) {
|
|
46
604
|
const hook = globalThis.RAINDROP_SUPPRESS_TRACING;
|
|
47
605
|
if (typeof hook !== "function") return fn();
|
|
@@ -59,7 +617,7 @@ function runWithTracingSuppressed(fn) {
|
|
|
59
617
|
var DEFAULT_REQUEST_TIMEOUT_MS = 3e4;
|
|
60
618
|
var MAX_RETRY_DELAY_MS = 3e4;
|
|
61
619
|
function wait(ms) {
|
|
62
|
-
return new Promise((
|
|
620
|
+
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
63
621
|
}
|
|
64
622
|
function formatEndpoint(endpoint) {
|
|
65
623
|
if (!endpoint) return void 0;
|
|
@@ -96,9 +654,9 @@ async function raceWithTimeout(promise, timeoutMs) {
|
|
|
96
654
|
() => true,
|
|
97
655
|
() => true
|
|
98
656
|
),
|
|
99
|
-
new Promise((
|
|
657
|
+
new Promise((resolve2) => {
|
|
100
658
|
var _a;
|
|
101
|
-
timer = setTimeout(() =>
|
|
659
|
+
timer = setTimeout(() => resolve2(false), Math.max(0, timeoutMs));
|
|
102
660
|
(_a = timer.unref) == null ? void 0 : _a.call(timer);
|
|
103
661
|
})
|
|
104
662
|
]);
|
|
@@ -169,6 +727,7 @@ async function postJson(url, body, headers, opts) {
|
|
|
169
727
|
const resp = await runWithTracingSuppressed(
|
|
170
728
|
() => fetch(url, {
|
|
171
729
|
method: "POST",
|
|
730
|
+
redirect: headers["X-Raindrop-Replay-Id"] !== void 0 ? "error" : "follow",
|
|
172
731
|
headers: {
|
|
173
732
|
"Content-Type": "application/json",
|
|
174
733
|
...headers
|
|
@@ -332,26 +891,29 @@ function resolveLocalDebuggerBaseUrl(baseUrl) {
|
|
|
332
891
|
if (shouldAutoEnableLocalWorkshop()) return DEFAULT_LOCAL_WORKSHOP_URL;
|
|
333
892
|
return null;
|
|
334
893
|
}
|
|
894
|
+
var LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS = 2e3;
|
|
335
895
|
function mirrorTraceExportToLocalDebugger(body, options = {}) {
|
|
336
896
|
var _a;
|
|
337
897
|
const baseUrl = resolveLocalDebuggerBaseUrl(options.baseUrl);
|
|
338
|
-
if (!baseUrl) return;
|
|
339
|
-
|
|
898
|
+
if (!baseUrl) return Promise.resolve();
|
|
899
|
+
return postJson(`${baseUrl}traces`, body, {}, {
|
|
340
900
|
maxAttempts: 1,
|
|
341
901
|
debug: (_a = options.debug) != null ? _a : false,
|
|
342
|
-
sdkName: options.sdkName
|
|
902
|
+
sdkName: options.sdkName,
|
|
903
|
+
timeoutMs: LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS
|
|
343
904
|
}).catch(() => {
|
|
344
905
|
});
|
|
345
906
|
}
|
|
346
907
|
function mirrorPartialEventToLocalDebugger(event, options = {}) {
|
|
347
908
|
var _a;
|
|
348
909
|
const baseUrl = resolveLocalDebuggerBaseUrl(options.baseUrl);
|
|
349
|
-
if (!baseUrl) return;
|
|
910
|
+
if (!baseUrl) return Promise.resolve();
|
|
350
911
|
const headers = options.writeKey ? { Authorization: `Bearer ${options.writeKey}` } : {};
|
|
351
|
-
|
|
912
|
+
return postJson(`${baseUrl}events/track_partial`, event, headers, {
|
|
352
913
|
maxAttempts: 1,
|
|
353
914
|
debug: (_a = options.debug) != null ? _a : false,
|
|
354
|
-
sdkName: options.sdkName
|
|
915
|
+
sdkName: options.sdkName,
|
|
916
|
+
timeoutMs: LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS
|
|
355
917
|
}).catch(() => {
|
|
356
918
|
});
|
|
357
919
|
}
|
|
@@ -376,35 +938,81 @@ function projectIdHeaders(projectId) {
|
|
|
376
938
|
}
|
|
377
939
|
var SHUTDOWN_DEADLINE_MS = 1e4;
|
|
378
940
|
var POST_SHUTDOWN_TIMEOUT_MS = 5e3;
|
|
941
|
+
function appGitOwnerId(prefix) {
|
|
942
|
+
try {
|
|
943
|
+
return `${prefix}:${randomUUID()}`;
|
|
944
|
+
} catch (e) {
|
|
945
|
+
return `${prefix}:${Date.now().toString(36)}:${Math.random().toString(36).slice(2)}`;
|
|
946
|
+
}
|
|
947
|
+
}
|
|
379
948
|
function mergePatches(target, source) {
|
|
380
|
-
var _a, _b, _c, _d;
|
|
949
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
381
950
|
const out = { ...target, ...source };
|
|
382
951
|
if (target.properties || source.properties) {
|
|
383
952
|
out.properties = { ...(_a = target.properties) != null ? _a : {}, ...(_b = source.properties) != null ? _b : {} };
|
|
384
953
|
}
|
|
954
|
+
if (target.usage || source.usage) {
|
|
955
|
+
out.usage = { ...(_c = target.usage) != null ? _c : {} };
|
|
956
|
+
if (((_d = source.usage) == null ? void 0 : _d.promptTokens) !== void 0) {
|
|
957
|
+
out.usage.promptTokens = source.usage.promptTokens;
|
|
958
|
+
}
|
|
959
|
+
if (((_e = source.usage) == null ? void 0 : _e.completionTokens) !== void 0) {
|
|
960
|
+
out.usage.completionTokens = source.usage.completionTokens;
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
if (source.error === void 0) {
|
|
964
|
+
out.error = target.error;
|
|
965
|
+
}
|
|
966
|
+
if (target.featureFlags || source.featureFlags) {
|
|
967
|
+
out.featureFlags = { ...(_f = target.featureFlags) != null ? _f : {}, ...(_g = source.featureFlags) != null ? _g : {} };
|
|
968
|
+
}
|
|
385
969
|
if (target.attachments || source.attachments) {
|
|
386
|
-
out.attachments = [...(
|
|
970
|
+
out.attachments = [...(_h = target.attachments) != null ? _h : [], ...(_i = source.attachments) != null ? _i : []];
|
|
387
971
|
}
|
|
388
972
|
return out;
|
|
389
973
|
}
|
|
974
|
+
function isErrorLike(value) {
|
|
975
|
+
return value !== null && typeof value === "object";
|
|
976
|
+
}
|
|
977
|
+
function eventTelemetryProperties(patch) {
|
|
978
|
+
var _a, _b;
|
|
979
|
+
const properties = {};
|
|
980
|
+
if (((_a = patch.usage) == null ? void 0 : _a.promptTokens) !== void 0 && Number.isFinite(patch.usage.promptTokens)) {
|
|
981
|
+
properties["ai.usage.prompt_tokens"] = patch.usage.promptTokens;
|
|
982
|
+
}
|
|
983
|
+
if (((_b = patch.usage) == null ? void 0 : _b.completionTokens) !== void 0 && Number.isFinite(patch.usage.completionTokens)) {
|
|
984
|
+
properties["ai.usage.completion_tokens"] = patch.usage.completionTokens;
|
|
985
|
+
}
|
|
986
|
+
if (patch.error !== void 0 && patch.error !== null) {
|
|
987
|
+
const constructorName = patch.error instanceof Error && patch.error.constructor !== Error ? patch.error.constructor.name : void 0;
|
|
988
|
+
const errorType = patch.error instanceof Error ? patch.error.name && patch.error.name !== "Error" ? patch.error.name : constructorName || patch.error.name || "Error" : isErrorLike(patch.error) && typeof patch.error.name === "string" && patch.error.name.length > 0 ? patch.error.name : "Error";
|
|
989
|
+
const errorMessage = patch.error instanceof Error ? patch.error.message : isErrorLike(patch.error) && typeof patch.error.message === "string" ? patch.error.message : String(patch.error);
|
|
990
|
+
properties["error.type"] = errorType;
|
|
991
|
+
properties["error.message"] = errorMessage;
|
|
992
|
+
}
|
|
993
|
+
return properties;
|
|
994
|
+
}
|
|
390
995
|
var EventShipper = class {
|
|
391
996
|
constructor(opts) {
|
|
997
|
+
this.appGitOwner = appGitOwnerId("event");
|
|
392
998
|
this.buffers = /* @__PURE__ */ new Map();
|
|
393
999
|
this.sticky = /* @__PURE__ */ new Map();
|
|
394
1000
|
this.timers = /* @__PURE__ */ new Map();
|
|
395
1001
|
this.inFlight = /* @__PURE__ */ new Set();
|
|
396
1002
|
this.hasShutdown = false;
|
|
397
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
398
|
-
this.
|
|
399
|
-
this.
|
|
1003
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
1004
|
+
this.appGitContext = (_a = opts.appGitContext) != null ? _a : createAppGitContext(opts.appGit);
|
|
1005
|
+
this.ownsAppGitContext = opts.appGitContext === void 0;
|
|
1006
|
+
this.writeKey = (_b = opts.writeKey) == null ? void 0 : _b.trim();
|
|
1007
|
+
this.baseUrl = (_c = formatEndpoint(opts.endpoint)) != null ? _c : "https://api.raindrop.ai/v1/";
|
|
400
1008
|
this.enabled = opts.enabled !== false;
|
|
401
1009
|
this.debug = opts.debug;
|
|
402
|
-
this.partialFlushMs = (
|
|
403
|
-
this.sdkName = (
|
|
1010
|
+
this.partialFlushMs = (_d = opts.partialFlushMs) != null ? _d : 1e3;
|
|
1011
|
+
this.sdkName = (_e = opts.sdkName) != null ? _e : "core";
|
|
404
1012
|
this.prefix = `[raindrop-ai/${this.sdkName}]`;
|
|
405
|
-
this.defaultEventName = (
|
|
1013
|
+
this.defaultEventName = (_f = opts.defaultEventName) != null ? _f : "ai_generation";
|
|
406
1014
|
this.maxTextFieldCharsOpt = opts.maxTextFieldChars;
|
|
407
|
-
this.localDebuggerUrl = (
|
|
1015
|
+
this.localDebuggerUrl = (_g = resolveLocalDebuggerBaseUrl(opts.localDebuggerUrl)) != null ? _g : void 0;
|
|
408
1016
|
if (this.debug && this.localDebuggerUrl) {
|
|
409
1017
|
console.log(`${this.prefix} Local debugger mirroring: ${this.localDebuggerUrl}`);
|
|
410
1018
|
}
|
|
@@ -415,8 +1023,8 @@ var EventShipper = class {
|
|
|
415
1023
|
const isNode = typeof process !== "undefined" && typeof process.version === "string";
|
|
416
1024
|
this.context = {
|
|
417
1025
|
library: {
|
|
418
|
-
name: (
|
|
419
|
-
version: (
|
|
1026
|
+
name: (_h = opts.libraryName) != null ? _h : "@raindrop-ai/core",
|
|
1027
|
+
version: (_i = opts.libraryVersion) != null ? _i : "0.0.0"
|
|
420
1028
|
},
|
|
421
1029
|
metadata: {
|
|
422
1030
|
jsRuntime: isNode ? "node" : "web",
|
|
@@ -424,6 +1032,9 @@ var EventShipper = class {
|
|
|
424
1032
|
}
|
|
425
1033
|
};
|
|
426
1034
|
}
|
|
1035
|
+
ownAppGitContextForShutdown() {
|
|
1036
|
+
this.ownsAppGitContext = true;
|
|
1037
|
+
}
|
|
427
1038
|
isDebugEnabled() {
|
|
428
1039
|
return this.debug;
|
|
429
1040
|
}
|
|
@@ -472,6 +1083,15 @@ var EventShipper = class {
|
|
|
472
1083
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
473
1084
|
if (!this.enabled) return;
|
|
474
1085
|
if (!eventId || !eventId.trim()) return;
|
|
1086
|
+
const capturedSticky = this.sticky.get(eventId);
|
|
1087
|
+
const eventAlreadyKnown = capturedSticky !== void 0 || this.buffers.has(eventId);
|
|
1088
|
+
const destination = currentReplayTraceDestination();
|
|
1089
|
+
const cloudReplay = destination !== void 0 && destination.kind !== "workshop";
|
|
1090
|
+
if ((capturedSticky == null ? void 0 : capturedSticky.replayOnly) === true || !eventAlreadyKnown && cloudReplay) {
|
|
1091
|
+
if (patch.isPending === false) this.sticky.delete(eventId);
|
|
1092
|
+
else this.sticky.set(eventId, { ...capturedSticky, replayOnly: true });
|
|
1093
|
+
return;
|
|
1094
|
+
}
|
|
475
1095
|
const maxChars = resolveMaxTextFieldChars(this.maxTextFieldCharsOpt);
|
|
476
1096
|
if (typeof patch.input === "string" && patch.input.length > maxChars) {
|
|
477
1097
|
patch = { ...patch, input: capText(patch.input, maxChars) };
|
|
@@ -493,6 +1113,13 @@ var EventShipper = class {
|
|
|
493
1113
|
}
|
|
494
1114
|
const sticky = (_c = this.sticky.get(eventId)) != null ? _c : {};
|
|
495
1115
|
const existing = (_d = this.buffers.get(eventId)) != null ? _d : {};
|
|
1116
|
+
patch = {
|
|
1117
|
+
...patch,
|
|
1118
|
+
properties: withAppGitProperties(
|
|
1119
|
+
patch.properties,
|
|
1120
|
+
this.appGitContext.forOperation(eventId, patch.properties, this.appGitOwner)
|
|
1121
|
+
)
|
|
1122
|
+
};
|
|
496
1123
|
const merged = mergePatches(existing, patch);
|
|
497
1124
|
merged.isPending = (_g = (_f = (_e = patch.isPending) != null ? _e : existing.isPending) != null ? _f : sticky.isPending) != null ? _g : true;
|
|
498
1125
|
this.buffers.set(eventId, merged);
|
|
@@ -506,6 +1133,8 @@ var EventShipper = class {
|
|
|
506
1133
|
if (t) clearTimeout(t);
|
|
507
1134
|
if (merged.isPending === false) {
|
|
508
1135
|
await this.flushOne(eventId);
|
|
1136
|
+
if (this.appGitContext.releaseOperation) this.appGitContext.releaseOperation(eventId, this.appGitOwner);
|
|
1137
|
+
else this.appGitContext.finishOperation(eventId);
|
|
509
1138
|
return;
|
|
510
1139
|
}
|
|
511
1140
|
const timeout = setTimeout(() => {
|
|
@@ -530,15 +1159,21 @@ var EventShipper = class {
|
|
|
530
1159
|
try {
|
|
531
1160
|
for (const t of this.timers.values()) clearTimeout(t);
|
|
532
1161
|
this.timers.clear();
|
|
1162
|
+
for (const [eventId, sticky] of this.sticky) {
|
|
1163
|
+
if (sticky.replayOnly) this.sticky.delete(eventId);
|
|
1164
|
+
}
|
|
533
1165
|
const settled = await raceWithTimeout(this.flush(), SHUTDOWN_DEADLINE_MS);
|
|
534
1166
|
if (!settled) this.warnShutdownDrop("in-flight request(s) at shutdown");
|
|
535
1167
|
} finally {
|
|
536
1168
|
this.shutdownDeadlineAt = void 0;
|
|
1169
|
+
if (this.ownsAppGitContext) this.appGitContext.dispose();
|
|
537
1170
|
}
|
|
538
1171
|
}
|
|
539
1172
|
async trackSignal(signal) {
|
|
540
1173
|
var _a, _b;
|
|
541
1174
|
if (!this.enabled) return;
|
|
1175
|
+
const destination = currentReplayTraceDestination();
|
|
1176
|
+
if (destination && destination.kind !== "workshop") return;
|
|
542
1177
|
const body = [
|
|
543
1178
|
{
|
|
544
1179
|
event_id: signal.eventId,
|
|
@@ -573,6 +1208,8 @@ var EventShipper = class {
|
|
|
573
1208
|
}
|
|
574
1209
|
async identify(users) {
|
|
575
1210
|
if (!this.enabled) return;
|
|
1211
|
+
const destination = currentReplayTraceDestination();
|
|
1212
|
+
if (destination && destination.kind !== "workshop") return;
|
|
576
1213
|
const list = Array.isArray(users) ? users : [users];
|
|
577
1214
|
const body = list.filter((user) => {
|
|
578
1215
|
if (!(user == null ? void 0 : user.userId) || !user.userId.trim()) {
|
|
@@ -625,8 +1262,9 @@ var EventShipper = class {
|
|
|
625
1262
|
this.buffers.delete(eventId);
|
|
626
1263
|
if (!accumulated) return;
|
|
627
1264
|
const sticky = (_a = this.sticky.get(eventId)) != null ? _a : {};
|
|
628
|
-
const
|
|
629
|
-
const
|
|
1265
|
+
const isPending = (_c = (_b = accumulated.isPending) != null ? _b : sticky.isPending) != null ? _c : true;
|
|
1266
|
+
const eventName = (_e = (_d = accumulated.eventName) != null ? _d : sticky.eventName) != null ? _e : this.defaultEventName;
|
|
1267
|
+
const userId = (_f = accumulated.userId) != null ? _f : sticky.userId;
|
|
630
1268
|
if (!userId) {
|
|
631
1269
|
if (this.debug) {
|
|
632
1270
|
console.warn(`${this.prefix} skipping track_partial for ${eventId}: missing userId`);
|
|
@@ -634,9 +1272,13 @@ var EventShipper = class {
|
|
|
634
1272
|
this.sticky.delete(eventId);
|
|
635
1273
|
return;
|
|
636
1274
|
}
|
|
637
|
-
const { wizardSession, ...restProperties } = (
|
|
638
|
-
|
|
639
|
-
|
|
1275
|
+
const { wizardSession, ...restProperties } = (_g = accumulated.properties) != null ? _g : {};
|
|
1276
|
+
let telemetryProperties = {};
|
|
1277
|
+
try {
|
|
1278
|
+
telemetryProperties = eventTelemetryProperties(accumulated);
|
|
1279
|
+
} catch (e) {
|
|
1280
|
+
}
|
|
1281
|
+
const convoId = (_h = accumulated.convoId) != null ? _h : sticky.convoId;
|
|
640
1282
|
const payload = {
|
|
641
1283
|
event_id: eventId,
|
|
642
1284
|
user_id: userId,
|
|
@@ -644,15 +1286,17 @@ var EventShipper = class {
|
|
|
644
1286
|
timestamp: (_i = accumulated.timestamp) != null ? _i : (/* @__PURE__ */ new Date()).toISOString(),
|
|
645
1287
|
ai_data: {
|
|
646
1288
|
input: accumulated.input,
|
|
647
|
-
output: accumulated.output,
|
|
1289
|
+
output: accumulated.error !== void 0 && accumulated.error !== null ? void 0 : accumulated.output,
|
|
648
1290
|
model: accumulated.model,
|
|
649
1291
|
convo_id: convoId
|
|
650
1292
|
},
|
|
651
1293
|
properties: {
|
|
652
1294
|
...restProperties,
|
|
1295
|
+
...telemetryProperties,
|
|
653
1296
|
...wizardSession ? { "raindrop.wizardSession": wizardSession } : {},
|
|
654
1297
|
$context: this.context
|
|
655
1298
|
},
|
|
1299
|
+
...accumulated.featureFlags && Object.keys(accumulated.featureFlags).length > 0 ? { feature_flags: accumulated.featureFlags } : {},
|
|
656
1300
|
attachments: accumulated.attachments,
|
|
657
1301
|
is_pending: isPending
|
|
658
1302
|
};
|
|
@@ -676,29 +1320,30 @@ var EventShipper = class {
|
|
|
676
1320
|
endpoint: url
|
|
677
1321
|
});
|
|
678
1322
|
}
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
});
|
|
686
|
-
}
|
|
1323
|
+
const mirror = this.localDebuggerUrl ? mirrorPartialEventToLocalDebugger(payload, {
|
|
1324
|
+
baseUrl: this.localDebuggerUrl,
|
|
1325
|
+
writeKey: this.writeKey,
|
|
1326
|
+
debug: this.debug,
|
|
1327
|
+
sdkName: this.sdkName
|
|
1328
|
+
}) : void 0;
|
|
687
1329
|
if (!this.writeKey) {
|
|
688
1330
|
if (!isPending) this.sticky.delete(eventId);
|
|
1331
|
+
if (mirror) await mirror;
|
|
689
1332
|
return;
|
|
690
1333
|
}
|
|
691
1334
|
const opts = this.requestOpts();
|
|
692
1335
|
if (!opts) {
|
|
693
1336
|
this.warnShutdownDrop(`track_partial ${eventId}`);
|
|
694
1337
|
if (!isPending) this.sticky.delete(eventId);
|
|
1338
|
+
if (mirror) await mirror;
|
|
695
1339
|
return;
|
|
696
1340
|
}
|
|
697
1341
|
const p = postJson(url, payload, this.requestHeaders(), opts);
|
|
698
|
-
|
|
1342
|
+
const combined = mirror ? Promise.all([mirror, p]).then(() => void 0) : p;
|
|
1343
|
+
this.inFlight.add(combined);
|
|
699
1344
|
try {
|
|
700
1345
|
try {
|
|
701
|
-
await
|
|
1346
|
+
await combined;
|
|
702
1347
|
if (this.debug) {
|
|
703
1348
|
console.log(`${this.prefix} sent track_partial ${eventId} (${eventName})`);
|
|
704
1349
|
}
|
|
@@ -710,13 +1355,156 @@ var EventShipper = class {
|
|
|
710
1355
|
);
|
|
711
1356
|
}
|
|
712
1357
|
} finally {
|
|
713
|
-
this.inFlight.delete(
|
|
1358
|
+
this.inFlight.delete(combined);
|
|
714
1359
|
}
|
|
715
1360
|
if (!isPending) {
|
|
716
1361
|
this.sticky.delete(eventId);
|
|
717
1362
|
}
|
|
718
1363
|
}
|
|
719
1364
|
};
|
|
1365
|
+
var MODEL_USAGE_ATTRIBUTES = {
|
|
1366
|
+
usageSource: "raindrop.usage.source",
|
|
1367
|
+
providerName: "gen_ai.provider.name",
|
|
1368
|
+
requestModel: "gen_ai.request.model",
|
|
1369
|
+
responseModel: "gen_ai.response.model",
|
|
1370
|
+
inputTokens: "gen_ai.usage.input_tokens",
|
|
1371
|
+
outputTokens: "gen_ai.usage.output_tokens",
|
|
1372
|
+
reasoningTokens: "gen_ai.usage.reasoning_tokens",
|
|
1373
|
+
cacheReadInputTokens: "gen_ai.usage.cache_read_input_tokens",
|
|
1374
|
+
cacheWriteInputTokens: "gen_ai.usage.cache_write_input_tokens",
|
|
1375
|
+
providerReportedCost: "gen_ai.usage.provider_reported_cost",
|
|
1376
|
+
nonCachedInputTokens: "raindrop.usage.input_tokens.non_cached",
|
|
1377
|
+
nonReasoningOutputTokens: "raindrop.usage.output_tokens.non_reasoning",
|
|
1378
|
+
totalOutputTokens: "raindrop.usage.output_tokens.total",
|
|
1379
|
+
reasoningOutputTokens: "raindrop.usage.output_tokens.reasoning",
|
|
1380
|
+
cacheReadTokens: "raindrop.usage.input_tokens.cache_read",
|
|
1381
|
+
cacheWriteTokens: "raindrop.usage.input_tokens.cache_write"
|
|
1382
|
+
};
|
|
1383
|
+
var MODEL_PROVIDER_NAMES = [
|
|
1384
|
+
["google.vertex.anthropic", "google-vertex"],
|
|
1385
|
+
["google.vertex_ai", "google-vertex"],
|
|
1386
|
+
["google.vertex", "google-vertex"],
|
|
1387
|
+
["gcp.vertex_ai", "google-vertex"],
|
|
1388
|
+
["gcp.gemini", "google"],
|
|
1389
|
+
["google_vertexai", "google-vertex"],
|
|
1390
|
+
["vertex.anthropic", "google-vertex"],
|
|
1391
|
+
["amazon-bedrock", "amazon-bedrock"],
|
|
1392
|
+
["aws.bedrock", "amazon-bedrock"],
|
|
1393
|
+
["bedrock", "amazon-bedrock"],
|
|
1394
|
+
["anthropic", "anthropic"],
|
|
1395
|
+
["openai", "openai"],
|
|
1396
|
+
["google", "google"],
|
|
1397
|
+
["az.ai.openai", "azure"],
|
|
1398
|
+
["azure", "azure"],
|
|
1399
|
+
["openrouter", "openrouter"]
|
|
1400
|
+
];
|
|
1401
|
+
function canonicalModelProvider(provider) {
|
|
1402
|
+
var _a;
|
|
1403
|
+
const normalizedProvider = provider.trim().toLowerCase();
|
|
1404
|
+
if (normalizedProvider === "gateway") return "vercel";
|
|
1405
|
+
const match = MODEL_PROVIDER_NAMES.find(
|
|
1406
|
+
([family]) => normalizedProvider === family || normalizedProvider.startsWith(`${family}.`)
|
|
1407
|
+
);
|
|
1408
|
+
return (_a = match == null ? void 0 : match[1]) != null ? _a : normalizedProvider;
|
|
1409
|
+
}
|
|
1410
|
+
var STRING_ALIASES = {
|
|
1411
|
+
[MODEL_USAGE_ATTRIBUTES.requestModel]: ["ai.model.id", "ai.model"]
|
|
1412
|
+
};
|
|
1413
|
+
var NUMBER_ALIASES = {
|
|
1414
|
+
[MODEL_USAGE_ATTRIBUTES.inputTokens]: [
|
|
1415
|
+
"gen_ai.usage.prompt_tokens",
|
|
1416
|
+
"ai.usage.prompt_tokens",
|
|
1417
|
+
"ai.usage.promptTokens",
|
|
1418
|
+
"ai.usage.input_tokens",
|
|
1419
|
+
"ai.usage.inputTokens"
|
|
1420
|
+
],
|
|
1421
|
+
[MODEL_USAGE_ATTRIBUTES.outputTokens]: [
|
|
1422
|
+
"gen_ai.usage.completion_tokens",
|
|
1423
|
+
"ai.usage.completion_tokens",
|
|
1424
|
+
"ai.usage.completionTokens",
|
|
1425
|
+
"ai.usage.output_tokens",
|
|
1426
|
+
"ai.usage.outputTokens"
|
|
1427
|
+
],
|
|
1428
|
+
[MODEL_USAGE_ATTRIBUTES.reasoningTokens]: [
|
|
1429
|
+
"gen_ai.usage.reasoning.output_tokens",
|
|
1430
|
+
"ai.usage.reasoningTokens",
|
|
1431
|
+
"ai.usage.thoughts_tokens"
|
|
1432
|
+
],
|
|
1433
|
+
[MODEL_USAGE_ATTRIBUTES.cacheReadInputTokens]: [
|
|
1434
|
+
"gen_ai.usage.cache_read_tokens",
|
|
1435
|
+
"gen_ai.usage.cache_read.input_tokens",
|
|
1436
|
+
"ai.usage.cachedInputTokens",
|
|
1437
|
+
"ai.usage.cached_tokens",
|
|
1438
|
+
"ai.usage.cache_read_tokens",
|
|
1439
|
+
"ai.usage.cache_read_input_tokens",
|
|
1440
|
+
"ai.usage.cacheReadInputTokens"
|
|
1441
|
+
],
|
|
1442
|
+
[MODEL_USAGE_ATTRIBUTES.cacheWriteInputTokens]: [
|
|
1443
|
+
"gen_ai.usage.cache_creation_input_tokens",
|
|
1444
|
+
"gen_ai.usage.cache_creation.input_tokens",
|
|
1445
|
+
"ai.usage.cacheWriteInputTokens",
|
|
1446
|
+
"ai.usage.cache_creation_input_tokens",
|
|
1447
|
+
"ai.usage.cacheCreationInputTokens"
|
|
1448
|
+
]
|
|
1449
|
+
};
|
|
1450
|
+
function hasAttribute(attributes, key) {
|
|
1451
|
+
return attributes.some((attribute) => attribute.key === key);
|
|
1452
|
+
}
|
|
1453
|
+
function findStringAttribute(attributes, keys) {
|
|
1454
|
+
return attributes.find(
|
|
1455
|
+
(attribute) => keys.includes(attribute.key) && typeof attribute.value.stringValue === "string" && attribute.value.stringValue.length > 0
|
|
1456
|
+
);
|
|
1457
|
+
}
|
|
1458
|
+
function findNumberAttribute(attributes, keys) {
|
|
1459
|
+
return attributes.find((attribute) => {
|
|
1460
|
+
if (!keys.includes(attribute.key)) return false;
|
|
1461
|
+
if (typeof attribute.value.doubleValue === "number" && Number.isSafeInteger(attribute.value.doubleValue) && attribute.value.doubleValue >= 0) {
|
|
1462
|
+
return true;
|
|
1463
|
+
}
|
|
1464
|
+
const intValue = attribute.value.intValue;
|
|
1465
|
+
return integerValue(intValue) !== void 0;
|
|
1466
|
+
});
|
|
1467
|
+
}
|
|
1468
|
+
function integerValue(value) {
|
|
1469
|
+
if (typeof value === "number") {
|
|
1470
|
+
return Number.isSafeInteger(value) && value >= 0 ? value : void 0;
|
|
1471
|
+
}
|
|
1472
|
+
if (typeof value !== "string") return void 0;
|
|
1473
|
+
const parsed = Number(value);
|
|
1474
|
+
return Number.isSafeInteger(parsed) && parsed >= 0 ? parsed : void 0;
|
|
1475
|
+
}
|
|
1476
|
+
function appendAlias(attributes, target, source) {
|
|
1477
|
+
if (!source || hasAttribute(attributes, target)) return attributes;
|
|
1478
|
+
return [...attributes, { key: target, value: { ...source.value } }];
|
|
1479
|
+
}
|
|
1480
|
+
function appendProviderAlias(attributes) {
|
|
1481
|
+
if (hasAttribute(attributes, MODEL_USAGE_ATTRIBUTES.providerName)) return attributes;
|
|
1482
|
+
const source = findStringAttribute(attributes, ["gen_ai.system", "ai.model.provider"]);
|
|
1483
|
+
if (!(source == null ? void 0 : source.value.stringValue)) return attributes;
|
|
1484
|
+
const attribute = attrString(
|
|
1485
|
+
MODEL_USAGE_ATTRIBUTES.providerName,
|
|
1486
|
+
canonicalModelProvider(source.value.stringValue)
|
|
1487
|
+
);
|
|
1488
|
+
return attribute ? [...attributes, attribute] : attributes;
|
|
1489
|
+
}
|
|
1490
|
+
function normalizeModelUsageSpan(span) {
|
|
1491
|
+
const original = span.attributes;
|
|
1492
|
+
if (!original || original.length === 0) return span;
|
|
1493
|
+
const responseModel = findStringAttribute(original, [
|
|
1494
|
+
MODEL_USAGE_ATTRIBUTES.responseModel,
|
|
1495
|
+
"ai.response.model"
|
|
1496
|
+
]);
|
|
1497
|
+
if (!responseModel) return span;
|
|
1498
|
+
let attributes = appendAlias(original, MODEL_USAGE_ATTRIBUTES.responseModel, responseModel);
|
|
1499
|
+
attributes = appendProviderAlias(attributes);
|
|
1500
|
+
for (const [target, aliases] of Object.entries(STRING_ALIASES)) {
|
|
1501
|
+
attributes = appendAlias(attributes, target, findStringAttribute(attributes, aliases));
|
|
1502
|
+
}
|
|
1503
|
+
for (const [target, aliases] of Object.entries(NUMBER_ALIASES)) {
|
|
1504
|
+
attributes = appendAlias(attributes, target, findNumberAttribute(attributes, aliases));
|
|
1505
|
+
}
|
|
1506
|
+
return attributes === original ? span : { ...span, attributes };
|
|
1507
|
+
}
|
|
720
1508
|
var DEFAULT_SECRET_KEY_NAMES = [
|
|
721
1509
|
"apikey",
|
|
722
1510
|
"apisecret",
|
|
@@ -806,6 +1594,20 @@ function redactJsonAttributeValue(key, value) {
|
|
|
806
1594
|
if (scrubbedJson === json) return void 0;
|
|
807
1595
|
return { stringValue: scrubbedJson };
|
|
808
1596
|
}
|
|
1597
|
+
function appGitOwnerId2(prefix) {
|
|
1598
|
+
try {
|
|
1599
|
+
return `${prefix}:${randomUUID()}`;
|
|
1600
|
+
} catch (e) {
|
|
1601
|
+
return `${prefix}:${Date.now().toString(36)}:${Math.random().toString(36).slice(2)}`;
|
|
1602
|
+
}
|
|
1603
|
+
}
|
|
1604
|
+
function identityAttrs(args) {
|
|
1605
|
+
return [
|
|
1606
|
+
attrString("ai.telemetry.metadata.raindrop.ai.userId", args.userId),
|
|
1607
|
+
attrString("ai.telemetry.metadata.raindrop.convoId", args.convoId),
|
|
1608
|
+
attrString("ai.telemetry.metadata.raindrop.eventName", args.eventName)
|
|
1609
|
+
];
|
|
1610
|
+
}
|
|
809
1611
|
function applyOtelSpanAttributeLimit(limit) {
|
|
810
1612
|
var _a, _b;
|
|
811
1613
|
try {
|
|
@@ -821,23 +1623,30 @@ function applyOtelSpanAttributeLimit(limit) {
|
|
|
821
1623
|
}
|
|
822
1624
|
var TraceShipper = class {
|
|
823
1625
|
constructor(opts) {
|
|
1626
|
+
this.appGitOwner = appGitOwnerId2("trace");
|
|
1627
|
+
this.appGitEventIds = /* @__PURE__ */ new WeakMap();
|
|
1628
|
+
this.appGitActiveSpans = /* @__PURE__ */ new Map();
|
|
1629
|
+
this.appGitCaptured = /* @__PURE__ */ new WeakSet();
|
|
1630
|
+
this.appGitAdded = /* @__PURE__ */ new WeakMap();
|
|
824
1631
|
this.queue = [];
|
|
825
1632
|
this.inFlight = /* @__PURE__ */ new Set();
|
|
826
1633
|
this.hasShutdown = false;
|
|
827
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
828
|
-
this.
|
|
829
|
-
this.
|
|
1634
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
1635
|
+
this.appGitContext = (_a = opts.appGitContext) != null ? _a : createAppGitContext(opts.appGit);
|
|
1636
|
+
this.ownsAppGitContext = opts.appGitContext === void 0;
|
|
1637
|
+
this.writeKey = (_b = opts.writeKey) == null ? void 0 : _b.trim();
|
|
1638
|
+
this.baseUrl = (_c = formatEndpoint(opts.endpoint)) != null ? _c : "https://api.raindrop.ai/v1/";
|
|
830
1639
|
this.enabled = opts.enabled !== false;
|
|
831
1640
|
this.debug = opts.debug;
|
|
832
1641
|
this.debugSpans = opts.debugSpans === true;
|
|
833
|
-
this.flushIntervalMs = (
|
|
834
|
-
this.maxBatchSize = (
|
|
835
|
-
this.maxQueueSize = (
|
|
836
|
-
this.sdkName = (
|
|
1642
|
+
this.flushIntervalMs = (_d = opts.flushIntervalMs) != null ? _d : 1e3;
|
|
1643
|
+
this.maxBatchSize = (_e = opts.maxBatchSize) != null ? _e : 50;
|
|
1644
|
+
this.maxQueueSize = (_f = opts.maxQueueSize) != null ? _f : 5e3;
|
|
1645
|
+
this.sdkName = (_g = opts.sdkName) != null ? _g : "core";
|
|
837
1646
|
this.prefix = `[raindrop-ai/${this.sdkName}]`;
|
|
838
|
-
this.serviceName = (
|
|
839
|
-
this.serviceVersion = (
|
|
840
|
-
this.localDebuggerUrl = (
|
|
1647
|
+
this.serviceName = (_h = opts.serviceName) != null ? _h : "raindrop.core";
|
|
1648
|
+
this.serviceVersion = (_i = opts.serviceVersion) != null ? _i : "0.0.0";
|
|
1649
|
+
this.localDebuggerUrl = (_j = resolveLocalDebuggerBaseUrl(opts.localDebuggerUrl)) != null ? _j : void 0;
|
|
841
1650
|
if (this.debug && this.localDebuggerUrl) {
|
|
842
1651
|
console.log(`${this.prefix} Local debugger mirroring: ${this.localDebuggerUrl}`);
|
|
843
1652
|
}
|
|
@@ -901,7 +1710,10 @@ var TraceShipper = class {
|
|
|
901
1710
|
try {
|
|
902
1711
|
const result = this.transformSpanHook(current);
|
|
903
1712
|
if (result === null) return null;
|
|
904
|
-
if (result !== void 0)
|
|
1713
|
+
if (result !== void 0) {
|
|
1714
|
+
copyReplayTraceDestination(current, result);
|
|
1715
|
+
current = result;
|
|
1716
|
+
}
|
|
905
1717
|
} catch (err) {
|
|
906
1718
|
if (this.debug) {
|
|
907
1719
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -910,10 +1722,20 @@ var TraceShipper = class {
|
|
|
910
1722
|
return null;
|
|
911
1723
|
}
|
|
912
1724
|
}
|
|
1725
|
+
try {
|
|
1726
|
+
const normalized = normalizeModelUsageSpan(current);
|
|
1727
|
+
copyReplayTraceDestination(current, normalized);
|
|
1728
|
+
current = normalized;
|
|
1729
|
+
} catch (e) {
|
|
1730
|
+
}
|
|
913
1731
|
if (!this.disableDefaultRedaction) {
|
|
914
|
-
|
|
1732
|
+
const redacted = defaultTransformSpan(current);
|
|
1733
|
+
copyReplayTraceDestination(current, redacted);
|
|
1734
|
+
current = redacted;
|
|
915
1735
|
}
|
|
916
|
-
|
|
1736
|
+
const capped = this.capSpanAttributes(current);
|
|
1737
|
+
copyReplayTraceDestination(current, capped);
|
|
1738
|
+
return capped;
|
|
917
1739
|
}
|
|
918
1740
|
isDebugEnabled() {
|
|
919
1741
|
return this.debug;
|
|
@@ -925,45 +1747,84 @@ var TraceShipper = class {
|
|
|
925
1747
|
return { ...this.authHeaders(), ...projectIdHeaders(this.projectId) };
|
|
926
1748
|
}
|
|
927
1749
|
startSpan(args) {
|
|
928
|
-
var _a, _b;
|
|
1750
|
+
var _a, _b, _c;
|
|
929
1751
|
const ids = createSpanIds(args.parent);
|
|
930
1752
|
const started = (_a = args.startTimeUnixNano) != null ? _a : nowUnixNanoString();
|
|
931
1753
|
const attrs = [
|
|
932
1754
|
attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId),
|
|
933
|
-
|
|
1755
|
+
...identityAttrs(args),
|
|
1756
|
+
attrString("ai.operationId", args.operationId),
|
|
1757
|
+
...Object.entries(evalScopeAttributes()).map(([key, value]) => attrString(key, value))
|
|
934
1758
|
];
|
|
935
1759
|
if ((_b = args.attributes) == null ? void 0 : _b.length) attrs.push(...args.attributes);
|
|
936
|
-
const
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
);
|
|
1760
|
+
const tracksAppGit = this.appGitActiveSpans.has(args.eventId) || this.appGitActiveSpans.size < 1e4;
|
|
1761
|
+
const appGitOverrides = appGitPropertiesFromAttributes(attrs);
|
|
1762
|
+
const span = {
|
|
1763
|
+
ids,
|
|
1764
|
+
name: args.name,
|
|
1765
|
+
startTimeUnixNano: started,
|
|
1766
|
+
attributes: withAppGitAttributes(
|
|
1767
|
+
attrs,
|
|
1768
|
+
this.appGitContext.forOperation(args.eventId, appGitOverrides, this.appGitOwner)
|
|
1769
|
+
)
|
|
1770
|
+
};
|
|
1771
|
+
rememberReplayTraceDestination(span);
|
|
1772
|
+
this.appGitCaptured.add(span);
|
|
1773
|
+
this.appGitEventIds.set(span, args.eventId);
|
|
1774
|
+
if (tracksAppGit) {
|
|
1775
|
+
this.appGitActiveSpans.set(args.eventId, ((_c = this.appGitActiveSpans.get(args.eventId)) != null ? _c : 0) + 1);
|
|
1776
|
+
}
|
|
1777
|
+
this.appGitAdded.set(span, new Set(span.attributes.filter((attr) => !attrs.includes(attr))));
|
|
1778
|
+
const openSpan = buildOtlpSpan({
|
|
1779
|
+
ids: span.ids,
|
|
1780
|
+
name: span.name,
|
|
1781
|
+
startTimeUnixNano: span.startTimeUnixNano,
|
|
1782
|
+
endTimeUnixNano: span.startTimeUnixNano,
|
|
1783
|
+
// placeholder — will be updated on endSpan
|
|
1784
|
+
attributes: span.attributes,
|
|
1785
|
+
status: { code: SpanStatusCode.UNSET }
|
|
1786
|
+
});
|
|
1787
|
+
copyReplayTraceDestination(span, openSpan);
|
|
1788
|
+
this.mirrorToLocalDebugger(openSpan);
|
|
948
1789
|
return span;
|
|
949
1790
|
}
|
|
950
|
-
mirrorToLocalDebugger(span) {
|
|
951
|
-
|
|
1791
|
+
mirrorToLocalDebugger(span, completed = false) {
|
|
1792
|
+
const destination = replayTraceDestinationFor(span);
|
|
1793
|
+
if (destination && destination.kind !== "workshop") return;
|
|
1794
|
+
const localDebuggerUrl = (destination == null ? void 0 : destination.kind) === "workshop" ? destination.url : this.localDebuggerUrl;
|
|
1795
|
+
if (!localDebuggerUrl) return;
|
|
952
1796
|
const redacted = this.redactSpan(span);
|
|
953
1797
|
if (redacted === null) return;
|
|
1798
|
+
if (completed && (destination == null ? void 0 : destination.kind) === "workshop") {
|
|
1799
|
+
recordReplayExportedSpan(
|
|
1800
|
+
destination,
|
|
1801
|
+
base64ToHex(redacted.spanId),
|
|
1802
|
+
base64ToHex(redacted.traceId)
|
|
1803
|
+
);
|
|
1804
|
+
}
|
|
954
1805
|
const body = buildExportTraceServiceRequest([redacted], this.serviceName, this.serviceVersion);
|
|
955
|
-
mirrorTraceExportToLocalDebugger(body, {
|
|
956
|
-
baseUrl:
|
|
1806
|
+
const p = mirrorTraceExportToLocalDebugger(body, {
|
|
1807
|
+
baseUrl: localDebuggerUrl,
|
|
957
1808
|
debug: false,
|
|
958
1809
|
sdkName: this.sdkName
|
|
959
1810
|
});
|
|
1811
|
+
this.inFlight.add(p);
|
|
1812
|
+
void p.finally(() => {
|
|
1813
|
+
this.inFlight.delete(p);
|
|
1814
|
+
});
|
|
960
1815
|
}
|
|
961
1816
|
endSpan(span, extra) {
|
|
962
|
-
var _a, _b;
|
|
1817
|
+
var _a, _b, _c;
|
|
963
1818
|
if (span.endTimeUnixNano) return;
|
|
964
1819
|
span.endTimeUnixNano = (_a = extra == null ? void 0 : extra.endTimeUnixNano) != null ? _a : nowUnixNanoString();
|
|
965
1820
|
if ((_b = extra == null ? void 0 : extra.attributes) == null ? void 0 : _b.length) {
|
|
1821
|
+
const overrides = appGitPropertiesFromAttributes(extra.attributes);
|
|
1822
|
+
const eventId2 = this.appGitEventIds.get(span);
|
|
1823
|
+
const snapshot = eventId2 ? this.appGitContext.forOperation(eventId2, overrides, this.appGitOwner) : overrides;
|
|
1824
|
+
const added = this.appGitAdded.get(span);
|
|
1825
|
+
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));
|
|
966
1826
|
span.attributes.push(...extra.attributes);
|
|
1827
|
+
span.attributes = withAppGitAttributes(span.attributes, snapshot);
|
|
967
1828
|
}
|
|
968
1829
|
let status = extra == null ? void 0 : extra.status;
|
|
969
1830
|
if (!status && (extra == null ? void 0 : extra.error) !== void 0) {
|
|
@@ -978,29 +1839,65 @@ var TraceShipper = class {
|
|
|
978
1839
|
attributes: span.attributes,
|
|
979
1840
|
status
|
|
980
1841
|
});
|
|
1842
|
+
copyReplayTraceDestination(span, otlp);
|
|
1843
|
+
this.appGitCaptured.add(otlp);
|
|
981
1844
|
this.enqueue(otlp);
|
|
982
|
-
this.mirrorToLocalDebugger(otlp);
|
|
1845
|
+
this.mirrorToLocalDebugger(otlp, true);
|
|
1846
|
+
const eventId = this.appGitEventIds.get(span);
|
|
1847
|
+
if (eventId && this.appGitActiveSpans.has(eventId)) {
|
|
1848
|
+
const remaining = ((_c = this.appGitActiveSpans.get(eventId)) != null ? _c : 1) - 1;
|
|
1849
|
+
if (remaining > 0) this.appGitActiveSpans.set(eventId, remaining);
|
|
1850
|
+
else {
|
|
1851
|
+
this.appGitActiveSpans.delete(eventId);
|
|
1852
|
+
if (this.appGitContext.releaseOperation) this.appGitContext.releaseOperation(eventId, this.appGitOwner);
|
|
1853
|
+
else if (this.ownsAppGitContext) this.appGitContext.finishOperation(eventId);
|
|
1854
|
+
}
|
|
1855
|
+
}
|
|
983
1856
|
}
|
|
984
1857
|
createSpan(args) {
|
|
985
1858
|
var _a;
|
|
986
1859
|
const ids = createSpanIds(args.parent);
|
|
987
1860
|
const attrs = [
|
|
988
|
-
attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId)
|
|
1861
|
+
attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId),
|
|
1862
|
+
...identityAttrs(args),
|
|
1863
|
+
...Object.entries(evalScopeAttributes()).map(([key, value]) => attrString(key, value))
|
|
989
1864
|
];
|
|
990
1865
|
if ((_a = args.attributes) == null ? void 0 : _a.length) attrs.push(...args.attributes);
|
|
1866
|
+
const tracksAppGit = !this.appGitActiveSpans.has(args.eventId);
|
|
991
1867
|
const otlp = buildOtlpSpan({
|
|
992
1868
|
ids,
|
|
993
1869
|
name: args.name,
|
|
994
1870
|
startTimeUnixNano: args.startTimeUnixNano,
|
|
995
1871
|
endTimeUnixNano: args.endTimeUnixNano,
|
|
996
|
-
attributes:
|
|
1872
|
+
attributes: withAppGitAttributes(
|
|
1873
|
+
attrs,
|
|
1874
|
+
this.appGitContext.forOperation(
|
|
1875
|
+
args.eventId,
|
|
1876
|
+
appGitPropertiesFromAttributes(attrs),
|
|
1877
|
+
this.appGitOwner
|
|
1878
|
+
)
|
|
1879
|
+
),
|
|
997
1880
|
status: args.status
|
|
998
1881
|
});
|
|
1882
|
+
rememberReplayTraceDestination(otlp);
|
|
1883
|
+
this.appGitCaptured.add(otlp);
|
|
1884
|
+
if (tracksAppGit) {
|
|
1885
|
+
if (this.appGitContext.releaseOperation) this.appGitContext.releaseOperation(args.eventId, this.appGitOwner);
|
|
1886
|
+
else if (this.ownsAppGitContext) this.appGitContext.finishOperation(args.eventId);
|
|
1887
|
+
}
|
|
999
1888
|
this.enqueue(otlp);
|
|
1000
|
-
this.mirrorToLocalDebugger(otlp);
|
|
1889
|
+
this.mirrorToLocalDebugger(otlp, true);
|
|
1001
1890
|
}
|
|
1002
1891
|
enqueue(span) {
|
|
1892
|
+
var _a;
|
|
1003
1893
|
if (!this.enabled) return;
|
|
1894
|
+
const attributes = (_a = span.attributes) != null ? _a : [];
|
|
1895
|
+
const enriched = this.appGitCaptured.has(span) ? attributes : withAppGitAttributes(attributes, this.appGitContext.snapshot(appGitPropertiesFromAttributes(attributes)));
|
|
1896
|
+
if (enriched !== attributes) {
|
|
1897
|
+
const original = span;
|
|
1898
|
+
span = { ...span, attributes: enriched.filter((attr) => attr !== void 0) };
|
|
1899
|
+
copyReplayTraceDestination(original, span);
|
|
1900
|
+
}
|
|
1004
1901
|
if (this.debugSpans) {
|
|
1005
1902
|
const short = (s) => s ? s.slice(-8) : "none";
|
|
1006
1903
|
console.log(
|
|
@@ -1011,6 +1908,13 @@ var TraceShipper = class {
|
|
|
1011
1908
|
}
|
|
1012
1909
|
const redacted = this.redactSpan(span);
|
|
1013
1910
|
if (redacted === null) return;
|
|
1911
|
+
const destination = replayTraceDestinationFor(redacted);
|
|
1912
|
+
recordReplayExportedSpan(
|
|
1913
|
+
destination,
|
|
1914
|
+
base64ToHex(redacted.spanId),
|
|
1915
|
+
base64ToHex(redacted.traceId)
|
|
1916
|
+
);
|
|
1917
|
+
if ((destination == null ? void 0 : destination.kind) === "workshop") return;
|
|
1014
1918
|
if (this.queue.length >= this.maxQueueSize) {
|
|
1015
1919
|
this.queue.shift();
|
|
1016
1920
|
}
|
|
@@ -1029,47 +1933,67 @@ var TraceShipper = class {
|
|
|
1029
1933
|
}
|
|
1030
1934
|
}
|
|
1031
1935
|
async flush() {
|
|
1032
|
-
|
|
1936
|
+
var _a;
|
|
1937
|
+
if (!this.enabled) {
|
|
1938
|
+
await Promise.all([...this.inFlight].map((p) => p.catch(() => {
|
|
1939
|
+
})));
|
|
1940
|
+
return;
|
|
1941
|
+
}
|
|
1033
1942
|
if (this.timer) {
|
|
1034
1943
|
clearTimeout(this.timer);
|
|
1035
1944
|
this.timer = void 0;
|
|
1036
1945
|
}
|
|
1037
1946
|
while (this.queue.length > 0) {
|
|
1038
1947
|
const batch = this.queue.splice(0, this.maxBatchSize);
|
|
1039
|
-
|
|
1040
|
-
const
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
`${this.prefix} shutdown flush deadline exceeded; dropping ${batch.length} spans`
|
|
1046
|
-
)
|
|
1047
|
-
);
|
|
1048
|
-
continue;
|
|
1948
|
+
const groups = /* @__PURE__ */ new Map();
|
|
1949
|
+
for (const span of batch) {
|
|
1950
|
+
const destination = replayTraceDestinationFor(span);
|
|
1951
|
+
const spans = groups.get(destination);
|
|
1952
|
+
if (spans) spans.push(span);
|
|
1953
|
+
else groups.set(destination, [span]);
|
|
1049
1954
|
}
|
|
1050
|
-
const
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
endpoint: url
|
|
1056
|
-
});
|
|
1057
|
-
}
|
|
1058
|
-
const p = postJson(url, body, this.requestHeaders(), opts);
|
|
1059
|
-
this.inFlight.add(p);
|
|
1060
|
-
try {
|
|
1061
|
-
try {
|
|
1062
|
-
await p;
|
|
1063
|
-
if (this.debug) console.log(`${this.prefix} sent ${batch.length} spans`);
|
|
1064
|
-
} catch (err) {
|
|
1065
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
1955
|
+
for (const [destination, spans] of groups) {
|
|
1956
|
+
if (!destination && !this.writeKey) continue;
|
|
1957
|
+
if ((destination == null ? void 0 : destination.kind) === "workshop") continue;
|
|
1958
|
+
const opts = this.requestOpts();
|
|
1959
|
+
if (!opts) {
|
|
1066
1960
|
rateLimitedLog(
|
|
1067
|
-
`${this.prefix}.
|
|
1068
|
-
() => console.warn(
|
|
1961
|
+
`${this.prefix}.shutdown_deadline`,
|
|
1962
|
+
() => console.warn(
|
|
1963
|
+
`${this.prefix} shutdown flush deadline exceeded; dropping ${spans.length} spans`
|
|
1964
|
+
)
|
|
1069
1965
|
);
|
|
1966
|
+
continue;
|
|
1967
|
+
}
|
|
1968
|
+
const body = buildExportTraceServiceRequest(spans, this.serviceName, this.serviceVersion);
|
|
1969
|
+
const url = destination ? replayTraceUrl(destination.url) : `${this.baseUrl}traces`;
|
|
1970
|
+
const headers = destination ? {
|
|
1971
|
+
Authorization: `Bearer ${destination.apiKey}`,
|
|
1972
|
+
"X-Raindrop-Replay-Id": destination.replayId,
|
|
1973
|
+
"X-Raindrop-Project-Id": (_a = destination.projectId) != null ? _a : "default"
|
|
1974
|
+
} : this.requestHeaders();
|
|
1975
|
+
if (this.debug) {
|
|
1976
|
+
console.log(`${this.prefix} sending traces batch`, {
|
|
1977
|
+
spans: spans.length,
|
|
1978
|
+
endpoint: url
|
|
1979
|
+
});
|
|
1980
|
+
}
|
|
1981
|
+
const p = postJson(url, body, headers, opts);
|
|
1982
|
+
this.inFlight.add(p);
|
|
1983
|
+
try {
|
|
1984
|
+
try {
|
|
1985
|
+
await p;
|
|
1986
|
+
if (this.debug) console.log(`${this.prefix} sent ${spans.length} spans`);
|
|
1987
|
+
} catch (err) {
|
|
1988
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
1989
|
+
rateLimitedLog(
|
|
1990
|
+
`${this.prefix}.send_spans_failed`,
|
|
1991
|
+
() => console.warn(`${this.prefix} failed to send ${spans.length} spans: ${msg}`)
|
|
1992
|
+
);
|
|
1993
|
+
}
|
|
1994
|
+
} finally {
|
|
1995
|
+
this.inFlight.delete(p);
|
|
1070
1996
|
}
|
|
1071
|
-
} finally {
|
|
1072
|
-
this.inFlight.delete(p);
|
|
1073
1997
|
}
|
|
1074
1998
|
}
|
|
1075
1999
|
}
|
|
@@ -1112,17 +2036,165 @@ var TraceShipper = class {
|
|
|
1112
2036
|
if (!settled) {
|
|
1113
2037
|
rateLimitedLog(
|
|
1114
2038
|
`${this.prefix}.shutdown_deadline`,
|
|
1115
|
-
() => console.warn(
|
|
2039
|
+
() => console.warn(
|
|
2040
|
+
`${this.prefix} shutdown flush deadline exceeded; abandoning in-flight spans`
|
|
2041
|
+
)
|
|
1116
2042
|
);
|
|
1117
2043
|
}
|
|
1118
2044
|
} finally {
|
|
1119
2045
|
this.shutdownDeadlineAt = void 0;
|
|
2046
|
+
if (this.ownsAppGitContext) this.appGitContext.dispose();
|
|
1120
2047
|
}
|
|
1121
2048
|
}
|
|
1122
2049
|
};
|
|
1123
2050
|
|
|
1124
2051
|
// ../core/dist/index.node.js
|
|
1125
2052
|
import { AsyncLocalStorage } from "async_hooks";
|
|
2053
|
+
import { execFile } from "child_process";
|
|
2054
|
+
import { resolve } from "path";
|
|
2055
|
+
var resolveLocal = (sourceDirectory, detectBranch, completed) => {
|
|
2056
|
+
const cwd = sourceDirectory ? resolve(sourceDirectory) : process.cwd();
|
|
2057
|
+
let cancelled = false;
|
|
2058
|
+
let active;
|
|
2059
|
+
let deadlineTimer;
|
|
2060
|
+
const deadline = Date.now() + 1e3;
|
|
2061
|
+
const run = (args, done) => {
|
|
2062
|
+
if (cancelled) return;
|
|
2063
|
+
const remaining = deadline - Date.now();
|
|
2064
|
+
if (remaining <= 0) {
|
|
2065
|
+
done(void 0);
|
|
2066
|
+
return;
|
|
2067
|
+
}
|
|
2068
|
+
try {
|
|
2069
|
+
active = execFile(
|
|
2070
|
+
"git",
|
|
2071
|
+
args,
|
|
2072
|
+
{
|
|
2073
|
+
cwd,
|
|
2074
|
+
encoding: "utf8",
|
|
2075
|
+
maxBuffer: 4096,
|
|
2076
|
+
windowsHide: true,
|
|
2077
|
+
env: {
|
|
2078
|
+
...process.env,
|
|
2079
|
+
// The selected application cwd, not the invoking shell's Git plumbing, owns identity.
|
|
2080
|
+
GIT_DIR: void 0,
|
|
2081
|
+
GIT_WORK_TREE: void 0,
|
|
2082
|
+
GIT_COMMON_DIR: void 0,
|
|
2083
|
+
GIT_NAMESPACE: void 0,
|
|
2084
|
+
GIT_INDEX_FILE: void 0,
|
|
2085
|
+
GIT_OBJECT_DIRECTORY: void 0,
|
|
2086
|
+
GIT_ALTERNATE_OBJECT_DIRECTORIES: void 0,
|
|
2087
|
+
GIT_CONFIG_PARAMETERS: void 0,
|
|
2088
|
+
GIT_CONFIG_COUNT: "0",
|
|
2089
|
+
GIT_TERMINAL_PROMPT: "0",
|
|
2090
|
+
GIT_OPTIONAL_LOCKS: "0"
|
|
2091
|
+
}
|
|
2092
|
+
},
|
|
2093
|
+
(error, stdout) => {
|
|
2094
|
+
clearTimeout(deadlineTimer);
|
|
2095
|
+
deadlineTimer = void 0;
|
|
2096
|
+
active = void 0;
|
|
2097
|
+
if (!cancelled) {
|
|
2098
|
+
try {
|
|
2099
|
+
done(error ? void 0 : stdout.trim());
|
|
2100
|
+
} catch (e) {
|
|
2101
|
+
}
|
|
2102
|
+
}
|
|
2103
|
+
}
|
|
2104
|
+
);
|
|
2105
|
+
active.unref();
|
|
2106
|
+
if (active.stdout && "unref" in active.stdout && typeof active.stdout.unref === "function")
|
|
2107
|
+
active.stdout.unref();
|
|
2108
|
+
if (active.stderr && "unref" in active.stderr && typeof active.stderr.unref === "function")
|
|
2109
|
+
active.stderr.unref();
|
|
2110
|
+
deadlineTimer = setTimeout(() => {
|
|
2111
|
+
try {
|
|
2112
|
+
active == null ? void 0 : active.kill("SIGKILL");
|
|
2113
|
+
} catch (e) {
|
|
2114
|
+
}
|
|
2115
|
+
}, remaining);
|
|
2116
|
+
deadlineTimer.unref();
|
|
2117
|
+
} catch (e) {
|
|
2118
|
+
try {
|
|
2119
|
+
done(void 0);
|
|
2120
|
+
} catch (e2) {
|
|
2121
|
+
}
|
|
2122
|
+
}
|
|
2123
|
+
};
|
|
2124
|
+
const scheduled = setTimeout(() => {
|
|
2125
|
+
try {
|
|
2126
|
+
run(["rev-parse", "HEAD"], (rawSha) => {
|
|
2127
|
+
const commitSha = validAppCommitSha(rawSha);
|
|
2128
|
+
if (!commitSha) {
|
|
2129
|
+
completed({});
|
|
2130
|
+
return;
|
|
2131
|
+
}
|
|
2132
|
+
run(["-c", "core.fsmonitor=false", "status", "--porcelain"], (status) => {
|
|
2133
|
+
const finish = (branch) => {
|
|
2134
|
+
run(["rev-parse", "HEAD"], (finalSha) => {
|
|
2135
|
+
const coherent = validAppCommitSha(finalSha) === commitSha;
|
|
2136
|
+
completed({
|
|
2137
|
+
commitSha,
|
|
2138
|
+
...coherent && status !== void 0 ? { commitDirty: status !== "" } : {},
|
|
2139
|
+
...coherent && branch && branch !== "HEAD" ? { branch } : {}
|
|
2140
|
+
});
|
|
2141
|
+
});
|
|
2142
|
+
};
|
|
2143
|
+
if (detectBranch) run(["symbolic-ref", "--quiet", "--short", "HEAD"], finish);
|
|
2144
|
+
else finish();
|
|
2145
|
+
});
|
|
2146
|
+
});
|
|
2147
|
+
} catch (e) {
|
|
2148
|
+
completed({});
|
|
2149
|
+
}
|
|
2150
|
+
}, 0);
|
|
2151
|
+
scheduled.unref();
|
|
2152
|
+
return () => {
|
|
2153
|
+
cancelled = true;
|
|
2154
|
+
clearTimeout(scheduled);
|
|
2155
|
+
clearTimeout(deadlineTimer);
|
|
2156
|
+
try {
|
|
2157
|
+
active == null ? void 0 : active.kill("SIGKILL");
|
|
2158
|
+
} catch (e) {
|
|
2159
|
+
}
|
|
2160
|
+
};
|
|
2161
|
+
};
|
|
2162
|
+
function createAppGitContext2(options, runtime = {}) {
|
|
2163
|
+
return new AppGitContext(options, { ...runtime, resolveLocal });
|
|
2164
|
+
}
|
|
2165
|
+
function hasDestination(options) {
|
|
2166
|
+
var _a;
|
|
2167
|
+
if (options.enabled === false) return false;
|
|
2168
|
+
return Boolean(((_a = options.writeKey) == null ? void 0 : _a.trim()) || resolveLocalDebuggerBaseUrl(options.localDebuggerUrl));
|
|
2169
|
+
}
|
|
2170
|
+
var EventShipper2 = class extends EventShipper {
|
|
2171
|
+
constructor(options) {
|
|
2172
|
+
var _a;
|
|
2173
|
+
const ownsAppGitContext = options.appGitContext === void 0;
|
|
2174
|
+
const appGitContext = (_a = options.appGitContext) != null ? _a : createAppGitContext2(options.appGit, { allowDiscovery: hasDestination(options) });
|
|
2175
|
+
try {
|
|
2176
|
+
super({ ...options, appGitContext });
|
|
2177
|
+
} catch (error) {
|
|
2178
|
+
if (ownsAppGitContext) appGitContext.dispose();
|
|
2179
|
+
throw error;
|
|
2180
|
+
}
|
|
2181
|
+
if (ownsAppGitContext) this.ownAppGitContextForShutdown();
|
|
2182
|
+
}
|
|
2183
|
+
};
|
|
2184
|
+
var TraceShipper2 = class extends TraceShipper {
|
|
2185
|
+
constructor(options) {
|
|
2186
|
+
var _a;
|
|
2187
|
+
const ownsAppGitContext = options.appGitContext === void 0;
|
|
2188
|
+
const appGitContext = (_a = options.appGitContext) != null ? _a : createAppGitContext2(options.appGit, { allowDiscovery: hasDestination(options) });
|
|
2189
|
+
try {
|
|
2190
|
+
super({ ...options, appGitContext });
|
|
2191
|
+
} catch (error) {
|
|
2192
|
+
if (ownsAppGitContext) appGitContext.dispose();
|
|
2193
|
+
throw error;
|
|
2194
|
+
}
|
|
2195
|
+
this.ownsAppGitContext = ownsAppGitContext;
|
|
2196
|
+
}
|
|
2197
|
+
};
|
|
1126
2198
|
globalThis.RAINDROP_ASYNC_LOCAL_STORAGE = AsyncLocalStorage;
|
|
1127
2199
|
var SUPPRESS_TRACING_KEY = /* @__PURE__ */ Symbol.for(
|
|
1128
2200
|
"OpenTelemetry SDK Context Key SUPPRESS_TRACING"
|
|
@@ -1150,12 +2222,84 @@ function installTracingSuppressionHook() {
|
|
|
1150
2222
|
}
|
|
1151
2223
|
installTracingSuppressionHook();
|
|
1152
2224
|
|
|
2225
|
+
// package.json
|
|
2226
|
+
var package_default = {
|
|
2227
|
+
name: "@raindrop-ai/claude-code",
|
|
2228
|
+
version: "0.0.20",
|
|
2229
|
+
description: "Raindrop observability for Claude Code CLI \u2014 automatic session, tool call, and prompt tracing via hooks",
|
|
2230
|
+
license: "MIT",
|
|
2231
|
+
homepage: "https://www.raindrop.ai/docs/integrations/claude-code/",
|
|
2232
|
+
bugs: {
|
|
2233
|
+
url: "https://www.raindrop.ai/docs/support/"
|
|
2234
|
+
},
|
|
2235
|
+
type: "module",
|
|
2236
|
+
main: "dist/index.cjs",
|
|
2237
|
+
module: "dist/index.js",
|
|
2238
|
+
types: "dist/index.d.ts",
|
|
2239
|
+
bin: {
|
|
2240
|
+
"raindrop-claude-code": "dist/cli.js"
|
|
2241
|
+
},
|
|
2242
|
+
exports: {
|
|
2243
|
+
".": {
|
|
2244
|
+
import: {
|
|
2245
|
+
types: "./dist/index.d.ts",
|
|
2246
|
+
default: "./dist/index.js"
|
|
2247
|
+
},
|
|
2248
|
+
require: {
|
|
2249
|
+
types: "./dist/index.d.cts",
|
|
2250
|
+
default: "./dist/index.cjs"
|
|
2251
|
+
}
|
|
2252
|
+
}
|
|
2253
|
+
},
|
|
2254
|
+
sideEffects: false,
|
|
2255
|
+
files: [
|
|
2256
|
+
"dist/**",
|
|
2257
|
+
"README.md",
|
|
2258
|
+
".claude-plugin/**",
|
|
2259
|
+
"hooks/**",
|
|
2260
|
+
".mcp.json"
|
|
2261
|
+
],
|
|
2262
|
+
keywords: [
|
|
2263
|
+
"raindrop",
|
|
2264
|
+
"claude-code",
|
|
2265
|
+
"claude",
|
|
2266
|
+
"anthropic",
|
|
2267
|
+
"observability",
|
|
2268
|
+
"tracing",
|
|
2269
|
+
"hooks",
|
|
2270
|
+
"cli"
|
|
2271
|
+
],
|
|
2272
|
+
engines: {
|
|
2273
|
+
node: ">=18"
|
|
2274
|
+
},
|
|
2275
|
+
scripts: {
|
|
2276
|
+
build: "tsup",
|
|
2277
|
+
postbuild: "chmod +x ./dist/cli.js && node ./scripts/sync-plugin-version.mjs",
|
|
2278
|
+
prepack: "node ./scripts/sync-plugin-version.mjs",
|
|
2279
|
+
dev: "tsup --watch",
|
|
2280
|
+
clean: "rm -rf dist",
|
|
2281
|
+
test: "pnpm build && cd tests && pnpm test",
|
|
2282
|
+
"test:watch": "cd tests && pnpm test:watch"
|
|
2283
|
+
},
|
|
2284
|
+
devDependencies: {
|
|
2285
|
+
"@raindrop-ai/core": "workspace:*",
|
|
2286
|
+
"@types/node": "^20.11.17",
|
|
2287
|
+
msw: "^2.12.7",
|
|
2288
|
+
tsup: "^8.4.0",
|
|
2289
|
+
typescript: "^5.3.3",
|
|
2290
|
+
vitest: "^2.1.0"
|
|
2291
|
+
},
|
|
2292
|
+
publishConfig: {
|
|
2293
|
+
access: "public"
|
|
2294
|
+
}
|
|
2295
|
+
};
|
|
2296
|
+
|
|
1153
2297
|
// src/package-info.ts
|
|
1154
2298
|
var PACKAGE_NAME = "@raindrop-ai/claude-code";
|
|
1155
|
-
var PACKAGE_VERSION =
|
|
2299
|
+
var PACKAGE_VERSION = package_default.version;
|
|
1156
2300
|
|
|
1157
2301
|
// src/shipper.ts
|
|
1158
|
-
var
|
|
2302
|
+
var EventShipper3 = class extends EventShipper2 {
|
|
1159
2303
|
constructor(opts) {
|
|
1160
2304
|
var _a, _b, _c, _d;
|
|
1161
2305
|
super({
|
|
@@ -1167,7 +2311,7 @@ var EventShipper2 = class extends EventShipper {
|
|
|
1167
2311
|
});
|
|
1168
2312
|
}
|
|
1169
2313
|
};
|
|
1170
|
-
var
|
|
2314
|
+
var TraceShipper3 = class extends TraceShipper2 {
|
|
1171
2315
|
constructor(opts) {
|
|
1172
2316
|
var _a, _b, _c;
|
|
1173
2317
|
super({
|
|
@@ -1248,7 +2392,20 @@ function loadConfig() {
|
|
|
1248
2392
|
})(),
|
|
1249
2393
|
eventName: (_l = (_k = process.env["RAINDROP_EVENT_NAME"]) != null ? _k : file.event_name) != null ? _l : "claude_code_session",
|
|
1250
2394
|
customProperties,
|
|
1251
|
-
selfDiagnostics
|
|
2395
|
+
selfDiagnostics,
|
|
2396
|
+
appGit: mapAppGit(file.app_git)
|
|
2397
|
+
};
|
|
2398
|
+
}
|
|
2399
|
+
function mapAppGit(value) {
|
|
2400
|
+
if (value === false) return false;
|
|
2401
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
2402
|
+
return {
|
|
2403
|
+
commitSha: "commit_sha" in value && (typeof value.commit_sha === "string" || value.commit_sha === null) ? value.commit_sha : void 0,
|
|
2404
|
+
commitDirty: "commit_dirty" in value && (typeof value.commit_dirty === "boolean" || value.commit_dirty === null) ? value.commit_dirty : void 0,
|
|
2405
|
+
branch: "branch" in value && (typeof value.branch === "string" || value.branch === null) ? value.branch : void 0,
|
|
2406
|
+
detectBranch: "detect_branch" in value && typeof value.detect_branch === "boolean" ? value.detect_branch : void 0,
|
|
2407
|
+
sourceDirectory: "source_directory" in value && typeof value.source_directory === "string" ? value.source_directory : void 0,
|
|
2408
|
+
autoDetect: "auto_detect" in value && typeof value.auto_detect === "boolean" ? value.auto_detect : void 0
|
|
1252
2409
|
};
|
|
1253
2410
|
}
|
|
1254
2411
|
function getConfigPath() {
|
|
@@ -2202,7 +3359,6 @@ import { join as join3 } from "path";
|
|
|
2202
3359
|
var DEFAULT_PORT = 5899;
|
|
2203
3360
|
var DEFAULT_URL = `http://localhost:${DEFAULT_PORT}/v1/`;
|
|
2204
3361
|
var HEALTH_TIMEOUT_MS = 300;
|
|
2205
|
-
var MIRROR_TIMEOUT_MS = 2e3;
|
|
2206
3362
|
var CACHE_DIR = join3(tmpdir2(), "raindrop-claude-code");
|
|
2207
3363
|
var CACHE_FILE = join3(CACHE_DIR, "debugger_cache");
|
|
2208
3364
|
var CACHE_TTL_MS = 5e3;
|
|
@@ -2264,20 +3420,22 @@ async function detectLocalDebugger(debug) {
|
|
|
2264
3420
|
}
|
|
2265
3421
|
return { url: detected, autoDetected: detected !== null };
|
|
2266
3422
|
}
|
|
2267
|
-
function mirrorEventToLocalDebugger(baseUrl, payload, debug) {
|
|
3423
|
+
async function mirrorEventToLocalDebugger(baseUrl, payload, debug) {
|
|
2268
3424
|
const url = `${baseUrl}events/track_partial`;
|
|
2269
3425
|
if (debug) {
|
|
2270
3426
|
console.log(`[raindrop-ai/claude-code] Mirroring event to local debugger: ${url}`);
|
|
2271
3427
|
}
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
|
|
3428
|
+
try {
|
|
3429
|
+
await runWithTracingSuppressed(
|
|
3430
|
+
() => fetch(url, {
|
|
3431
|
+
method: "POST",
|
|
3432
|
+
headers: { "Content-Type": "application/json" },
|
|
3433
|
+
body: JSON.stringify(payload),
|
|
3434
|
+
signal: AbortSignal.timeout(LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS)
|
|
3435
|
+
})
|
|
3436
|
+
);
|
|
3437
|
+
} catch (e) {
|
|
3438
|
+
}
|
|
2281
3439
|
}
|
|
2282
3440
|
|
|
2283
3441
|
// src/mcp-serve.ts
|
|
@@ -2387,6 +3545,7 @@ function resolveCurrentEventId() {
|
|
|
2387
3545
|
}
|
|
2388
3546
|
}
|
|
2389
3547
|
async function executeTool(args) {
|
|
3548
|
+
var _a;
|
|
2390
3549
|
const category = typeof args["category"] === "string" ? args["category"] : "";
|
|
2391
3550
|
const detail = typeof args["detail"] === "string" ? args["detail"] : "";
|
|
2392
3551
|
if (!category || !activeSignals[category]) {
|
|
@@ -2412,12 +3571,17 @@ async function executeTool(args) {
|
|
|
2412
3571
|
if (!eventId) {
|
|
2413
3572
|
return { content: [{ type: "text", text: "Signal noted (no active event found)." }] };
|
|
2414
3573
|
}
|
|
2415
|
-
const
|
|
3574
|
+
const appGitContext = createAppGitContext2(
|
|
3575
|
+
((_a = config.writeKey) == null ? void 0 : _a.trim()) ? config.appGit : false,
|
|
3576
|
+
{ allowLocalGit: false }
|
|
3577
|
+
);
|
|
3578
|
+
const shipper = new EventShipper3({
|
|
2416
3579
|
writeKey: config.writeKey,
|
|
2417
3580
|
endpoint: config.endpoint,
|
|
2418
3581
|
debug: false,
|
|
2419
3582
|
projectId: config.projectId,
|
|
2420
|
-
enabled: true
|
|
3583
|
+
enabled: true,
|
|
3584
|
+
appGitContext
|
|
2421
3585
|
});
|
|
2422
3586
|
try {
|
|
2423
3587
|
const signalDef = activeSignals[category];
|
|
@@ -2444,6 +3608,11 @@ async function executeTool(args) {
|
|
|
2444
3608
|
});
|
|
2445
3609
|
await shipper.shutdown();
|
|
2446
3610
|
} catch (e) {
|
|
3611
|
+
} finally {
|
|
3612
|
+
try {
|
|
3613
|
+
appGitContext.dispose();
|
|
3614
|
+
} catch (e) {
|
|
3615
|
+
}
|
|
2447
3616
|
}
|
|
2448
3617
|
return { content: [{ type: "text", text: "Signal recorded." }] };
|
|
2449
3618
|
}
|
|
@@ -2565,11 +3734,12 @@ async function handleLine(line, toolSchema) {
|
|
|
2565
3734
|
}
|
|
2566
3735
|
export {
|
|
2567
3736
|
DEFAULT_CATEGORY_KEYS,
|
|
2568
|
-
|
|
3737
|
+
EventShipper3 as EventShipper,
|
|
2569
3738
|
PACKAGE_NAME,
|
|
2570
3739
|
PACKAGE_VERSION,
|
|
2571
3740
|
TOOL_SCHEMA,
|
|
2572
|
-
|
|
3741
|
+
TraceShipper3 as TraceShipper,
|
|
3742
|
+
createAppGitContext2 as createAppGitContext,
|
|
2573
3743
|
detectLocalDebugger,
|
|
2574
3744
|
executeTool,
|
|
2575
3745
|
extractAppendSystemPrompt,
|