@raindrop-ai/opencode-plugin 0.1.3 → 0.1.4
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 +4 -0
- package/dist/index.cjs +1126 -251
- package/dist/index.d.cts +15 -2
- package/dist/index.d.ts +15 -2
- package/dist/index.js +1126 -251
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -24,7 +24,521 @@ __export(index_exports, {
|
|
|
24
24
|
});
|
|
25
25
|
module.exports = __toCommonJS(index_exports);
|
|
26
26
|
|
|
27
|
-
// ../core/dist/chunk-
|
|
27
|
+
// ../core/dist/chunk-BYBMRLZM.js
|
|
28
|
+
var EVAL_CORRELATION_ID_ATTRIBUTE = "raindrop.eval_correlation_id";
|
|
29
|
+
var PROBE_SCOPE = { correlationId: "" };
|
|
30
|
+
var EvalScopeStorage = class {
|
|
31
|
+
constructor() {
|
|
32
|
+
this._als = null;
|
|
33
|
+
this._probed = false;
|
|
34
|
+
}
|
|
35
|
+
maybeAdoptAsyncLocalStorage() {
|
|
36
|
+
if (this._probed) return;
|
|
37
|
+
this._probed = true;
|
|
38
|
+
try {
|
|
39
|
+
const Ctor = globalThis.RAINDROP_ASYNC_LOCAL_STORAGE;
|
|
40
|
+
if (!Ctor) return;
|
|
41
|
+
const als = new Ctor();
|
|
42
|
+
als.run(PROBE_SCOPE, () => {
|
|
43
|
+
});
|
|
44
|
+
this._als = als;
|
|
45
|
+
} catch (e) {
|
|
46
|
+
this._als = null;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
run(scope, callback) {
|
|
50
|
+
this.maybeAdoptAsyncLocalStorage();
|
|
51
|
+
if (this._als) return this._als.run(scope, callback);
|
|
52
|
+
const previous = this._syncScope;
|
|
53
|
+
this._syncScope = scope;
|
|
54
|
+
try {
|
|
55
|
+
return callback();
|
|
56
|
+
} finally {
|
|
57
|
+
this._syncScope = previous;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
current() {
|
|
61
|
+
this.maybeAdoptAsyncLocalStorage();
|
|
62
|
+
if (this._als) return this._als.getStore();
|
|
63
|
+
return this._syncScope;
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
var EVAL_SCOPE_STORAGE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.evalScopeStorage");
|
|
67
|
+
function evalScopeStorage() {
|
|
68
|
+
const holder = globalThis;
|
|
69
|
+
let storage = holder[EVAL_SCOPE_STORAGE_KEY];
|
|
70
|
+
if (!storage) {
|
|
71
|
+
storage = new EvalScopeStorage();
|
|
72
|
+
holder[EVAL_SCOPE_STORAGE_KEY] = storage;
|
|
73
|
+
}
|
|
74
|
+
return storage;
|
|
75
|
+
}
|
|
76
|
+
function currentEvalScope() {
|
|
77
|
+
try {
|
|
78
|
+
return evalScopeStorage().current();
|
|
79
|
+
} catch (e) {
|
|
80
|
+
return void 0;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
function evalScopeAttributes() {
|
|
84
|
+
const scope = currentEvalScope();
|
|
85
|
+
if (!scope) return {};
|
|
86
|
+
return { [EVAL_CORRELATION_ID_ATTRIBUTE]: scope.correlationId };
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// ../core/dist/chunk-WJOR6M7H.js
|
|
90
|
+
var STATE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.replayTraceRoutingState");
|
|
91
|
+
function state() {
|
|
92
|
+
const holder = globalThis;
|
|
93
|
+
let current = holder[STATE_KEY];
|
|
94
|
+
if (!current) {
|
|
95
|
+
let storage = null;
|
|
96
|
+
try {
|
|
97
|
+
const Ctor = globalThis.RAINDROP_ASYNC_LOCAL_STORAGE;
|
|
98
|
+
if (Ctor) storage = new Ctor();
|
|
99
|
+
} catch (e) {
|
|
100
|
+
storage = null;
|
|
101
|
+
}
|
|
102
|
+
current = {
|
|
103
|
+
storage,
|
|
104
|
+
syncDestination: void 0,
|
|
105
|
+
spanDestinations: /* @__PURE__ */ new WeakMap()
|
|
106
|
+
};
|
|
107
|
+
holder[STATE_KEY] = current;
|
|
108
|
+
}
|
|
109
|
+
return current;
|
|
110
|
+
}
|
|
111
|
+
function currentReplayTraceDestination() {
|
|
112
|
+
var _a, _b;
|
|
113
|
+
const routing = state();
|
|
114
|
+
return (_b = (_a = routing.storage) == null ? void 0 : _a.getStore()) != null ? _b : routing.syncDestination;
|
|
115
|
+
}
|
|
116
|
+
function rememberReplayTraceDestination(span) {
|
|
117
|
+
const destination = currentReplayTraceDestination();
|
|
118
|
+
if (destination) state().spanDestinations.set(span, destination);
|
|
119
|
+
}
|
|
120
|
+
function copyReplayTraceDestination(source, target) {
|
|
121
|
+
const destination = state().spanDestinations.get(source);
|
|
122
|
+
if (destination) state().spanDestinations.set(target, destination);
|
|
123
|
+
}
|
|
124
|
+
function replayTraceDestinationFor(value) {
|
|
125
|
+
if (typeof value !== "object" && typeof value !== "function" || value === null) {
|
|
126
|
+
return void 0;
|
|
127
|
+
}
|
|
128
|
+
return state().spanDestinations.get(value);
|
|
129
|
+
}
|
|
130
|
+
function recordReplayExportedSpan(destination, spanId, traceId) {
|
|
131
|
+
var _a, _b;
|
|
132
|
+
if (!destination || !spanId || !traceId) return;
|
|
133
|
+
(_a = destination.exportedSpanIds) == null ? void 0 : _a.add(spanId);
|
|
134
|
+
(_b = destination.exportedTraceIds) == null ? void 0 : _b.add(traceId);
|
|
135
|
+
}
|
|
136
|
+
function replayTraceUrl(baseUrl) {
|
|
137
|
+
return `${baseUrl.replace(/\/+$/, "")}/v1/traces`;
|
|
138
|
+
}
|
|
139
|
+
function getAsyncLocalStorageCtor() {
|
|
140
|
+
return globalThis.RAINDROP_ASYNC_LOCAL_STORAGE;
|
|
141
|
+
}
|
|
142
|
+
var MAX_BINDING_STACK = 128;
|
|
143
|
+
var EMPTY_STACK = [];
|
|
144
|
+
var ContextStackStorage = class {
|
|
145
|
+
/** Emitted once when this runtime cannot support an ambient push. */
|
|
146
|
+
constructor(noAmbientBindWarning) {
|
|
147
|
+
this.noAmbientBindWarning = noAmbientBindWarning;
|
|
148
|
+
this._als = null;
|
|
149
|
+
this._enterWithUsable = false;
|
|
150
|
+
this._syncStack = EMPTY_STACK;
|
|
151
|
+
this._adoptionChecked = false;
|
|
152
|
+
this._warnedNoAmbientBind = false;
|
|
153
|
+
}
|
|
154
|
+
maybeAdoptAsyncLocalStorage() {
|
|
155
|
+
if (this._adoptionChecked) return;
|
|
156
|
+
this._adoptionChecked = true;
|
|
157
|
+
const Ctor = getAsyncLocalStorageCtor();
|
|
158
|
+
if (!Ctor) return;
|
|
159
|
+
const als = new Ctor();
|
|
160
|
+
try {
|
|
161
|
+
als.run(EMPTY_STACK, () => {
|
|
162
|
+
});
|
|
163
|
+
} catch (e) {
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
this._als = als;
|
|
167
|
+
if (typeof als.enterWith === "function") {
|
|
168
|
+
try {
|
|
169
|
+
als.enterWith(EMPTY_STACK);
|
|
170
|
+
this._enterWithUsable = true;
|
|
171
|
+
} catch (e) {
|
|
172
|
+
this._enterWithUsable = false;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
getStack() {
|
|
177
|
+
var _a;
|
|
178
|
+
this.maybeAdoptAsyncLocalStorage();
|
|
179
|
+
if (this._als) return (_a = this._als.getStore()) != null ? _a : this._syncStack;
|
|
180
|
+
return this._syncStack;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Persist an ambient stack mutation. Returns false when an ALS is adopted but
|
|
184
|
+
* `enterWith` is unusable (workerd): callers must NOT fall back to the
|
|
185
|
+
* process-shared sync stack, since concurrent isolates would cross-stamp.
|
|
186
|
+
*/
|
|
187
|
+
setAmbientStack(stack) {
|
|
188
|
+
if (this._als) {
|
|
189
|
+
if (!this._enterWithUsable) return false;
|
|
190
|
+
this._als.enterWith(stack);
|
|
191
|
+
return true;
|
|
192
|
+
}
|
|
193
|
+
this._syncStack = stack;
|
|
194
|
+
return true;
|
|
195
|
+
}
|
|
196
|
+
push(binding) {
|
|
197
|
+
this.maybeAdoptAsyncLocalStorage();
|
|
198
|
+
if (this._als && !this._enterWithUsable) {
|
|
199
|
+
this.warnNoAmbientBindOnce();
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
let stack = this.getStack();
|
|
203
|
+
if (stack.length >= MAX_BINDING_STACK) {
|
|
204
|
+
stack = stack.filter((b) => b.isLive());
|
|
205
|
+
if (stack.length >= MAX_BINDING_STACK) {
|
|
206
|
+
stack = stack.slice(stack.length - (MAX_BINDING_STACK - 1));
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
this.setAmbientStack([...stack, binding]);
|
|
210
|
+
}
|
|
211
|
+
remove(binding) {
|
|
212
|
+
binding.markDead();
|
|
213
|
+
const stack = this.getStack();
|
|
214
|
+
const pruned = stack.filter((b) => b !== binding && b.isLive());
|
|
215
|
+
if (pruned.length !== stack.length) {
|
|
216
|
+
this.setAmbientStack(pruned);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
runWith(binding, callback) {
|
|
220
|
+
this.maybeAdoptAsyncLocalStorage();
|
|
221
|
+
if (this._als) {
|
|
222
|
+
return this._als.run([...this.getStack(), binding], callback);
|
|
223
|
+
}
|
|
224
|
+
const previous = this._syncStack;
|
|
225
|
+
this._syncStack = [...previous, binding];
|
|
226
|
+
try {
|
|
227
|
+
return callback();
|
|
228
|
+
} finally {
|
|
229
|
+
this._syncStack = previous;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
current() {
|
|
233
|
+
const stack = this.getStack();
|
|
234
|
+
if (stack.length === 0) return void 0;
|
|
235
|
+
const top = stack[stack.length - 1];
|
|
236
|
+
if (top.isLive()) return top;
|
|
237
|
+
const pruned = stack.filter((b) => b.isLive());
|
|
238
|
+
this.setAmbientStack(pruned);
|
|
239
|
+
return pruned.length > 0 ? pruned[pruned.length - 1] : void 0;
|
|
240
|
+
}
|
|
241
|
+
warnNoAmbientBindOnce() {
|
|
242
|
+
if (this._warnedNoAmbientBind) return;
|
|
243
|
+
this._warnedNoAmbientBind = true;
|
|
244
|
+
console.warn(this.noAmbientBindWarning);
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
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.";
|
|
248
|
+
var ROUTING_STORAGE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.routingContextStorage");
|
|
249
|
+
function routingStorage() {
|
|
250
|
+
const holder = globalThis;
|
|
251
|
+
let storage = holder[ROUTING_STORAGE_KEY];
|
|
252
|
+
if (!storage) {
|
|
253
|
+
storage = new ContextStackStorage(NO_AMBIENT_ROUTING_BIND_WARNING);
|
|
254
|
+
holder[ROUTING_STORAGE_KEY] = storage;
|
|
255
|
+
}
|
|
256
|
+
return storage;
|
|
257
|
+
}
|
|
258
|
+
function currentRoutingBinding() {
|
|
259
|
+
const bound = routingStorage().current();
|
|
260
|
+
if (!bound) return void 0;
|
|
261
|
+
return {
|
|
262
|
+
projectId: bound.projectId,
|
|
263
|
+
authHint: bound.authHint,
|
|
264
|
+
...bound.appGit ? { appGit: bound.appGit } : {},
|
|
265
|
+
...bound.appGitSource ? { appGitSource: bound.appGitSource } : {}
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
var APP_COMMIT_SHA = "raindrop.app.commit_sha";
|
|
269
|
+
var APP_COMMIT_DIRTY = "raindrop.app.commit_dirty";
|
|
270
|
+
var APP_BRANCH = "raindrop.app.branch";
|
|
271
|
+
var APP_GIT_KEYS = [APP_COMMIT_SHA, APP_COMMIT_DIRTY, APP_BRANCH];
|
|
272
|
+
var own = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
273
|
+
function appGitExplicitKeys(properties) {
|
|
274
|
+
const keys = /* @__PURE__ */ new Set();
|
|
275
|
+
if (!properties) return keys;
|
|
276
|
+
for (const key of APP_GIT_KEYS) {
|
|
277
|
+
if (own(properties, key)) keys.add(key);
|
|
278
|
+
}
|
|
279
|
+
return keys;
|
|
280
|
+
}
|
|
281
|
+
function mergeAppGitSnapshot(base, properties, explicitKeys = /* @__PURE__ */ new Set()) {
|
|
282
|
+
try {
|
|
283
|
+
const result = { ...base };
|
|
284
|
+
if (properties && own(properties, APP_COMMIT_SHA) && properties[APP_COMMIT_SHA] !== result[APP_COMMIT_SHA]) {
|
|
285
|
+
if (!explicitKeys.has(APP_COMMIT_DIRTY) && !own(properties, APP_COMMIT_DIRTY)) {
|
|
286
|
+
delete result[APP_COMMIT_DIRTY];
|
|
287
|
+
}
|
|
288
|
+
if (!explicitKeys.has(APP_BRANCH) && !own(properties, APP_BRANCH)) {
|
|
289
|
+
delete result[APP_BRANCH];
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
for (const key of APP_GIT_KEYS) {
|
|
293
|
+
if (properties && own(properties, key)) result[key] = properties[key];
|
|
294
|
+
}
|
|
295
|
+
return Object.freeze(result);
|
|
296
|
+
} catch (e) {
|
|
297
|
+
return Object.freeze({});
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
function validAppCommitSha(value) {
|
|
301
|
+
if (typeof value !== "string" || value.length > 128) return void 0;
|
|
302
|
+
const cleaned = value.trim();
|
|
303
|
+
return /^(?:[a-fA-F0-9]{40}|[a-fA-F0-9]{64})$/.test(cleaned) ? cleaned.toLowerCase() : void 0;
|
|
304
|
+
}
|
|
305
|
+
function shortString(value) {
|
|
306
|
+
if (typeof value !== "string" || value.length > 1024) return void 0;
|
|
307
|
+
const cleaned = value.trim();
|
|
308
|
+
return cleaned.length > 0 ? cleaned : void 0;
|
|
309
|
+
}
|
|
310
|
+
function flag(value) {
|
|
311
|
+
if (value === true || value === "true" || value === "1") return true;
|
|
312
|
+
if (value === false || value === "false" || value === "0") return false;
|
|
313
|
+
return void 0;
|
|
314
|
+
}
|
|
315
|
+
function environment() {
|
|
316
|
+
try {
|
|
317
|
+
return typeof process === "undefined" ? {} : process.env;
|
|
318
|
+
} catch (e) {
|
|
319
|
+
return {};
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
var DEPLOYMENTS = [
|
|
323
|
+
["VERCEL", "VERCEL_GIT_COMMIT_SHA", "VERCEL_GIT_COMMIT_REF"],
|
|
324
|
+
["NETLIFY", "COMMIT_REF", "BRANCH"],
|
|
325
|
+
["RAILWAY_ENVIRONMENT_NAME", "RAILWAY_GIT_COMMIT_SHA", "RAILWAY_GIT_BRANCH"],
|
|
326
|
+
["RAILWAY_ENVIRONMENT", "RAILWAY_GIT_COMMIT_SHA", "RAILWAY_GIT_BRANCH"],
|
|
327
|
+
["RENDER", "RENDER_GIT_COMMIT", "RENDER_GIT_BRANCH"],
|
|
328
|
+
["DYNO", "HEROKU_BUILD_COMMIT", ""],
|
|
329
|
+
["DYNO", "HEROKU_SLUG_COMMIT", ""],
|
|
330
|
+
["AWS_APP_ID", "AWS_COMMIT_ID", "AWS_BRANCH"],
|
|
331
|
+
["WORKERS_CI", "WORKERS_CI_COMMIT_SHA", "WORKERS_CI_BRANCH"]
|
|
332
|
+
];
|
|
333
|
+
var CI_SOURCES = [
|
|
334
|
+
["GITHUB_ACTIONS", "GITHUB_SHA", "GITHUB_REF_NAME"],
|
|
335
|
+
["GITLAB_CI", "CI_COMMIT_SHA", "CI_COMMIT_REF_NAME"],
|
|
336
|
+
["CIRCLECI", "CIRCLE_SHA1", "CIRCLE_BRANCH"]
|
|
337
|
+
];
|
|
338
|
+
function detectedSource(env, table, detectBranch) {
|
|
339
|
+
for (const row of table) {
|
|
340
|
+
const [marker, shaKey, branchKey] = row;
|
|
341
|
+
if (!marker || !shaKey || !shortString(env[marker]) || flag(env[marker]) === false) continue;
|
|
342
|
+
const commitSha = validAppCommitSha(env[shaKey]);
|
|
343
|
+
if (commitSha)
|
|
344
|
+
return {
|
|
345
|
+
commitSha,
|
|
346
|
+
...detectBranch && branchKey ? { branch: shortString(env[branchKey]) } : {}
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
return {};
|
|
350
|
+
}
|
|
351
|
+
var AppGitContextImpl = class {
|
|
352
|
+
constructor(options, runtime = {}) {
|
|
353
|
+
this.defaults = {};
|
|
354
|
+
this.explicit = {};
|
|
355
|
+
this.explicitKeys = /* @__PURE__ */ new Set();
|
|
356
|
+
this.disposed = false;
|
|
357
|
+
this.operations = /* @__PURE__ */ new Map();
|
|
358
|
+
this.operationOverflow = false;
|
|
359
|
+
this.detectBranch = false;
|
|
360
|
+
this.disabled = false;
|
|
361
|
+
var _a, _b, _c, _d, _e, _f;
|
|
362
|
+
try {
|
|
363
|
+
if (options === false) {
|
|
364
|
+
this.disabled = true;
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
const opts = options != null ? options : {};
|
|
368
|
+
const env = (_a = runtime.env) != null ? _a : environment();
|
|
369
|
+
const detectBranch = (_c = (_b = flag(opts.detectBranch)) != null ? _b : flag(env.RAINDROP_GIT_DETECT_BRANCH)) != null ? _c : false;
|
|
370
|
+
this.detectBranch = detectBranch;
|
|
371
|
+
const collectBranch = detectBranch || runtime.captureLegacyReplayBranch === true;
|
|
372
|
+
const autoDetect = runtime.allowDiscovery === false ? false : (_e = (_d = flag(opts.autoDetect)) != null ? _d : flag(env.RAINDROP_GIT_AUTO_DETECT)) != null ? _e : true;
|
|
373
|
+
const configuredSha = opts.commitSha;
|
|
374
|
+
const explicitSha = configuredSha === void 0 ? env.RAINDROP_COMMIT_SHA : configuredSha;
|
|
375
|
+
if (explicitSha === null) this.explicit[APP_COMMIT_SHA] = null;
|
|
376
|
+
else if (typeof explicitSha === "string" && validAppCommitSha(explicitSha))
|
|
377
|
+
this.explicit[APP_COMMIT_SHA] = explicitSha;
|
|
378
|
+
const configuredDirty = opts.commitDirty;
|
|
379
|
+
const explicitDirty = configuredDirty === void 0 ? flag(env.RAINDROP_COMMIT_DIRTY) : configuredDirty;
|
|
380
|
+
if (explicitDirty === null || typeof explicitDirty === "boolean")
|
|
381
|
+
this.explicit[APP_COMMIT_DIRTY] = explicitDirty;
|
|
382
|
+
const configuredBranch = opts.branch;
|
|
383
|
+
const explicitBranch = configuredBranch === void 0 ? env.RAINDROP_BRANCH : configuredBranch;
|
|
384
|
+
if (explicitBranch === null) this.explicit[APP_BRANCH] = null;
|
|
385
|
+
else if (typeof explicitBranch === "string" && explicitBranch.length <= 1024)
|
|
386
|
+
this.explicit[APP_BRANCH] = explicitBranch;
|
|
387
|
+
this.explicitKeys = appGitExplicitKeys(this.explicit);
|
|
388
|
+
this.defaults = { ...this.explicit };
|
|
389
|
+
if (!autoDetect || explicitSha !== void 0) return;
|
|
390
|
+
const sourceDirectory = (_f = shortString(opts.sourceDirectory)) != null ? _f : shortString(env.RAINDROP_GIT_SOURCE_DIRECTORY);
|
|
391
|
+
if (runtime.allowLocalGit === false && !sourceDirectory) return;
|
|
392
|
+
const deploy = sourceDirectory ? {} : detectedSource(env, DEPLOYMENTS, collectBranch);
|
|
393
|
+
if (deploy.commitSha) {
|
|
394
|
+
this.accept(deploy);
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
const fallback = sourceDirectory ? {} : detectedSource(env, CI_SOURCES, collectBranch);
|
|
398
|
+
if (runtime.resolveLocal && (runtime.allowLocalGit !== false || sourceDirectory)) {
|
|
399
|
+
this.cancel = runtime.resolveLocal(sourceDirectory, collectBranch, (result) => {
|
|
400
|
+
try {
|
|
401
|
+
if (!this.disposed) this.accept(result.commitSha ? result : fallback);
|
|
402
|
+
} catch (e) {
|
|
403
|
+
}
|
|
404
|
+
});
|
|
405
|
+
} else this.accept(fallback);
|
|
406
|
+
} catch (e) {
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
accept(result) {
|
|
410
|
+
const sha = validAppCommitSha(result.commitSha);
|
|
411
|
+
if (!sha) return;
|
|
412
|
+
this.replayBranch = shortString(result.branch);
|
|
413
|
+
this.defaults = {
|
|
414
|
+
[APP_COMMIT_SHA]: sha,
|
|
415
|
+
...typeof result.commitDirty === "boolean" ? { [APP_COMMIT_DIRTY]: result.commitDirty } : {},
|
|
416
|
+
...this.detectBranch && this.replayBranch ? { [APP_BRANCH]: this.replayBranch } : {},
|
|
417
|
+
...this.explicit
|
|
418
|
+
};
|
|
419
|
+
}
|
|
420
|
+
snapshot(properties) {
|
|
421
|
+
var _a;
|
|
422
|
+
try {
|
|
423
|
+
const binding = currentRoutingBinding();
|
|
424
|
+
const base = this.disabled && (binding == null ? void 0 : binding.appGitSource) !== "replay-override" ? {} : (_a = binding == null ? void 0 : binding.appGit) != null ? _a : this.defaults;
|
|
425
|
+
return this.mergeSnapshot(base, properties);
|
|
426
|
+
} catch (e) {
|
|
427
|
+
return Object.freeze({});
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
/** Safe defaults when no operation/span start was observed; never infer identity. */
|
|
431
|
+
snapshotExplicit(properties, eventId) {
|
|
432
|
+
try {
|
|
433
|
+
const base = { ...this.explicit };
|
|
434
|
+
const operation = eventId ? this.operations.get(eventId) : void 0;
|
|
435
|
+
if (operation) {
|
|
436
|
+
for (const key of operation.explicitKeys) base[key] = operation.snapshot[key];
|
|
437
|
+
}
|
|
438
|
+
return this.mergeSnapshot(base, properties, new Set(Object.keys(base)));
|
|
439
|
+
} catch (e) {
|
|
440
|
+
return mergeAppGitSnapshot({}, properties);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
/** Existing replay branch reporting stays separate from opt-in event properties. */
|
|
444
|
+
snapshotForReplay() {
|
|
445
|
+
const snapshot = this.snapshot();
|
|
446
|
+
if (this.replayBranch && !own(snapshot, APP_BRANCH) && snapshot[APP_COMMIT_SHA] === this.defaults[APP_COMMIT_SHA]) {
|
|
447
|
+
return Object.freeze({ ...snapshot, [APP_BRANCH]: this.replayBranch });
|
|
448
|
+
}
|
|
449
|
+
return snapshot;
|
|
450
|
+
}
|
|
451
|
+
/** Merge a frozen span snapshot without losing client-authored provenance. */
|
|
452
|
+
mergeSnapshot(base, properties, explicitKeys = this.explicitKeys) {
|
|
453
|
+
return mergeAppGitSnapshot(base, properties, /* @__PURE__ */ new Set([...this.explicitKeys, ...explicitKeys]));
|
|
454
|
+
}
|
|
455
|
+
/** Shippers belonging to one client share this bounded operation registry. */
|
|
456
|
+
forOperation(eventId, properties, owner) {
|
|
457
|
+
if (!eventId) return this.snapshot(properties);
|
|
458
|
+
let operation = this.operations.get(eventId);
|
|
459
|
+
if (!operation) {
|
|
460
|
+
if (this.operations.size >= 1e4) this.operationOverflow = true;
|
|
461
|
+
if (this.operationOverflow) return this.mergeSnapshot({}, properties);
|
|
462
|
+
operation = {
|
|
463
|
+
snapshot: this.snapshot(properties),
|
|
464
|
+
owners: /* @__PURE__ */ new Set(),
|
|
465
|
+
unowned: owner === void 0,
|
|
466
|
+
explicitKeys: appGitExplicitKeys(properties)
|
|
467
|
+
};
|
|
468
|
+
this.operations.set(eventId, operation);
|
|
469
|
+
} else if (properties && APP_GIT_KEYS.some((key) => own(properties, key))) {
|
|
470
|
+
const explicitKeys = /* @__PURE__ */ new Set([...this.explicitKeys, ...operation.explicitKeys]);
|
|
471
|
+
operation.snapshot = this.mergeSnapshot(operation.snapshot, properties, explicitKeys);
|
|
472
|
+
for (const key of appGitExplicitKeys(properties)) operation.explicitKeys.add(key);
|
|
473
|
+
}
|
|
474
|
+
if (!owner) operation.unowned = true;
|
|
475
|
+
if (owner) operation.owners.add(owner);
|
|
476
|
+
return operation.snapshot;
|
|
477
|
+
}
|
|
478
|
+
releaseOperation(eventId, owner) {
|
|
479
|
+
const operation = this.operations.get(eventId);
|
|
480
|
+
if (!operation) return;
|
|
481
|
+
operation.owners.delete(owner);
|
|
482
|
+
if (operation.owners.size === 0 && !operation.unowned) this.operations.delete(eventId);
|
|
483
|
+
}
|
|
484
|
+
finishOperation(eventId) {
|
|
485
|
+
this.operations.delete(eventId);
|
|
486
|
+
}
|
|
487
|
+
dispose() {
|
|
488
|
+
var _a;
|
|
489
|
+
this.disposed = true;
|
|
490
|
+
try {
|
|
491
|
+
(_a = this.cancel) == null ? void 0 : _a.call(this);
|
|
492
|
+
} catch (e) {
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
};
|
|
496
|
+
var AppGitContext = AppGitContextImpl;
|
|
497
|
+
function createAppGitContext(options, runtime = {}) {
|
|
498
|
+
return new AppGitContext(options, runtime);
|
|
499
|
+
}
|
|
500
|
+
function withAppGitProperties(properties, snapshot) {
|
|
501
|
+
try {
|
|
502
|
+
const merged = { ...properties };
|
|
503
|
+
for (const key of APP_GIT_KEYS)
|
|
504
|
+
if (!own(merged, key) && own(snapshot, key)) merged[key] = snapshot[key];
|
|
505
|
+
return merged;
|
|
506
|
+
} catch (e) {
|
|
507
|
+
return properties != null ? properties : {};
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
function withAppGitAttributes(attributes, snapshot) {
|
|
511
|
+
try {
|
|
512
|
+
const present = new Set(attributes.flatMap((attr) => attr ? [attr.key] : []));
|
|
513
|
+
const added = [];
|
|
514
|
+
for (const key of APP_GIT_KEYS) {
|
|
515
|
+
if (present.has(key) || present.has(`ai.telemetry.metadata.${key}`) || present.has(`traceloop.association.properties.${key}`))
|
|
516
|
+
continue;
|
|
517
|
+
const value = snapshot[key];
|
|
518
|
+
if (typeof value === "string") added.push({ key, value: { stringValue: value } });
|
|
519
|
+
else if (typeof value === "boolean") added.push({ key, value: { boolValue: value } });
|
|
520
|
+
}
|
|
521
|
+
return added.length ? [...attributes, ...added] : attributes;
|
|
522
|
+
} catch (e) {
|
|
523
|
+
return attributes;
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
function appGitPropertiesFromAttributes(attributes) {
|
|
527
|
+
var _a, _b, _c;
|
|
528
|
+
const properties = {};
|
|
529
|
+
try {
|
|
530
|
+
for (const attr of attributes) {
|
|
531
|
+
if (!attr) continue;
|
|
532
|
+
for (const key of APP_GIT_KEYS) {
|
|
533
|
+
if (attr.key === key || attr.key === `ai.telemetry.metadata.${key}` || attr.key === `traceloop.association.properties.${key}`) {
|
|
534
|
+
properties[key] = (_c = (_b = (_a = attr.value.stringValue) != null ? _a : attr.value.boolValue) != null ? _b : attr.value.intValue) != null ? _c : null;
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
} catch (e) {
|
|
539
|
+
}
|
|
540
|
+
return properties;
|
|
541
|
+
}
|
|
28
542
|
function getCrypto() {
|
|
29
543
|
const c = globalThis.crypto;
|
|
30
544
|
return c;
|
|
@@ -79,6 +593,25 @@ function base64Encode(bytes) {
|
|
|
79
593
|
}
|
|
80
594
|
return out;
|
|
81
595
|
}
|
|
596
|
+
function base64ToHex(value) {
|
|
597
|
+
if (!value) return "";
|
|
598
|
+
const maybeBuffer = globalThis.Buffer;
|
|
599
|
+
if (maybeBuffer) {
|
|
600
|
+
return maybeBuffer.from(value, "base64").toString("hex");
|
|
601
|
+
}
|
|
602
|
+
const atobFn = globalThis.atob;
|
|
603
|
+
if (typeof atobFn !== "function") return "";
|
|
604
|
+
try {
|
|
605
|
+
const binary = atobFn(value);
|
|
606
|
+
let hex = "";
|
|
607
|
+
for (let i = 0; i < binary.length; i++) {
|
|
608
|
+
hex += (binary.charCodeAt(i) & 255).toString(16).padStart(2, "0");
|
|
609
|
+
}
|
|
610
|
+
return hex;
|
|
611
|
+
} catch (e) {
|
|
612
|
+
return "";
|
|
613
|
+
}
|
|
614
|
+
}
|
|
82
615
|
function generateId() {
|
|
83
616
|
return randomUUID();
|
|
84
617
|
}
|
|
@@ -113,7 +646,7 @@ function runWithTracingSuppressed(fn) {
|
|
|
113
646
|
var DEFAULT_REQUEST_TIMEOUT_MS = 3e4;
|
|
114
647
|
var MAX_RETRY_DELAY_MS = 3e4;
|
|
115
648
|
function wait(ms) {
|
|
116
|
-
return new Promise((
|
|
649
|
+
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
117
650
|
}
|
|
118
651
|
function formatEndpoint(endpoint) {
|
|
119
652
|
if (!endpoint) return void 0;
|
|
@@ -150,9 +683,9 @@ async function raceWithTimeout(promise, timeoutMs) {
|
|
|
150
683
|
() => true,
|
|
151
684
|
() => true
|
|
152
685
|
),
|
|
153
|
-
new Promise((
|
|
686
|
+
new Promise((resolve2) => {
|
|
154
687
|
var _a;
|
|
155
|
-
timer = setTimeout(() =>
|
|
688
|
+
timer = setTimeout(() => resolve2(false), Math.max(0, timeoutMs));
|
|
156
689
|
(_a = timer.unref) == null ? void 0 : _a.call(timer);
|
|
157
690
|
})
|
|
158
691
|
]);
|
|
@@ -223,6 +756,7 @@ async function postJson(url, body, headers, opts) {
|
|
|
223
756
|
const resp = await runWithTracingSuppressed(
|
|
224
757
|
() => fetch(url, {
|
|
225
758
|
method: "POST",
|
|
759
|
+
redirect: headers["X-Raindrop-Replay-Id"] !== void 0 ? "error" : "follow",
|
|
226
760
|
headers: {
|
|
227
761
|
"Content-Type": "application/json",
|
|
228
762
|
...headers
|
|
@@ -391,26 +925,29 @@ function resolveLocalDebuggerBaseUrl(baseUrl) {
|
|
|
391
925
|
if (shouldAutoEnableLocalWorkshop()) return DEFAULT_LOCAL_WORKSHOP_URL;
|
|
392
926
|
return null;
|
|
393
927
|
}
|
|
928
|
+
var LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS = 2e3;
|
|
394
929
|
function mirrorTraceExportToLocalDebugger(body, options = {}) {
|
|
395
930
|
var _a;
|
|
396
931
|
const baseUrl = resolveLocalDebuggerBaseUrl(options.baseUrl);
|
|
397
|
-
if (!baseUrl) return;
|
|
398
|
-
|
|
932
|
+
if (!baseUrl) return Promise.resolve();
|
|
933
|
+
return postJson(`${baseUrl}traces`, body, {}, {
|
|
399
934
|
maxAttempts: 1,
|
|
400
935
|
debug: (_a = options.debug) != null ? _a : false,
|
|
401
|
-
sdkName: options.sdkName
|
|
936
|
+
sdkName: options.sdkName,
|
|
937
|
+
timeoutMs: LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS
|
|
402
938
|
}).catch(() => {
|
|
403
939
|
});
|
|
404
940
|
}
|
|
405
941
|
function mirrorPartialEventToLocalDebugger(event, options = {}) {
|
|
406
942
|
var _a;
|
|
407
943
|
const baseUrl = resolveLocalDebuggerBaseUrl(options.baseUrl);
|
|
408
|
-
if (!baseUrl) return;
|
|
944
|
+
if (!baseUrl) return Promise.resolve();
|
|
409
945
|
const headers = options.writeKey ? { Authorization: `Bearer ${options.writeKey}` } : {};
|
|
410
|
-
|
|
946
|
+
return postJson(`${baseUrl}events/track_partial`, event, headers, {
|
|
411
947
|
maxAttempts: 1,
|
|
412
948
|
debug: (_a = options.debug) != null ? _a : false,
|
|
413
|
-
sdkName: options.sdkName
|
|
949
|
+
sdkName: options.sdkName,
|
|
950
|
+
timeoutMs: LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS
|
|
414
951
|
}).catch(() => {
|
|
415
952
|
});
|
|
416
953
|
}
|
|
@@ -435,6 +972,13 @@ function projectIdHeaders(projectId) {
|
|
|
435
972
|
}
|
|
436
973
|
var SHUTDOWN_DEADLINE_MS = 1e4;
|
|
437
974
|
var POST_SHUTDOWN_TIMEOUT_MS = 5e3;
|
|
975
|
+
function appGitOwnerId(prefix) {
|
|
976
|
+
try {
|
|
977
|
+
return `${prefix}:${randomUUID()}`;
|
|
978
|
+
} catch (e) {
|
|
979
|
+
return `${prefix}:${Date.now().toString(36)}:${Math.random().toString(36).slice(2)}`;
|
|
980
|
+
}
|
|
981
|
+
}
|
|
438
982
|
function mergePatches(target, source) {
|
|
439
983
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
440
984
|
const out = { ...target, ...source };
|
|
@@ -484,22 +1028,25 @@ function eventTelemetryProperties(patch) {
|
|
|
484
1028
|
}
|
|
485
1029
|
var EventShipper = class {
|
|
486
1030
|
constructor(opts) {
|
|
1031
|
+
this.appGitOwner = appGitOwnerId("event");
|
|
487
1032
|
this.buffers = /* @__PURE__ */ new Map();
|
|
488
1033
|
this.sticky = /* @__PURE__ */ new Map();
|
|
489
1034
|
this.timers = /* @__PURE__ */ new Map();
|
|
490
1035
|
this.inFlight = /* @__PURE__ */ new Set();
|
|
491
1036
|
this.hasShutdown = false;
|
|
492
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
493
|
-
this.
|
|
494
|
-
this.
|
|
1037
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
1038
|
+
this.appGitContext = (_a = opts.appGitContext) != null ? _a : createAppGitContext(opts.appGit);
|
|
1039
|
+
this.ownsAppGitContext = opts.appGitContext === void 0;
|
|
1040
|
+
this.writeKey = (_b = opts.writeKey) == null ? void 0 : _b.trim();
|
|
1041
|
+
this.baseUrl = (_c = formatEndpoint(opts.endpoint)) != null ? _c : "https://api.raindrop.ai/v1/";
|
|
495
1042
|
this.enabled = opts.enabled !== false;
|
|
496
1043
|
this.debug = opts.debug;
|
|
497
|
-
this.partialFlushMs = (
|
|
498
|
-
this.sdkName = (
|
|
1044
|
+
this.partialFlushMs = (_d = opts.partialFlushMs) != null ? _d : 1e3;
|
|
1045
|
+
this.sdkName = (_e = opts.sdkName) != null ? _e : "core";
|
|
499
1046
|
this.prefix = `[raindrop-ai/${this.sdkName}]`;
|
|
500
|
-
this.defaultEventName = (
|
|
1047
|
+
this.defaultEventName = (_f = opts.defaultEventName) != null ? _f : "ai_generation";
|
|
501
1048
|
this.maxTextFieldCharsOpt = opts.maxTextFieldChars;
|
|
502
|
-
this.localDebuggerUrl = (
|
|
1049
|
+
this.localDebuggerUrl = (_g = resolveLocalDebuggerBaseUrl(opts.localDebuggerUrl)) != null ? _g : void 0;
|
|
503
1050
|
if (this.debug && this.localDebuggerUrl) {
|
|
504
1051
|
console.log(`${this.prefix} Local debugger mirroring: ${this.localDebuggerUrl}`);
|
|
505
1052
|
}
|
|
@@ -510,8 +1057,8 @@ var EventShipper = class {
|
|
|
510
1057
|
const isNode = typeof process !== "undefined" && typeof process.version === "string";
|
|
511
1058
|
this.context = {
|
|
512
1059
|
library: {
|
|
513
|
-
name: (
|
|
514
|
-
version: (
|
|
1060
|
+
name: (_h = opts.libraryName) != null ? _h : "@raindrop-ai/core",
|
|
1061
|
+
version: (_i = opts.libraryVersion) != null ? _i : "0.0.0"
|
|
515
1062
|
},
|
|
516
1063
|
metadata: {
|
|
517
1064
|
jsRuntime: isNode ? "node" : "web",
|
|
@@ -519,6 +1066,9 @@ var EventShipper = class {
|
|
|
519
1066
|
}
|
|
520
1067
|
};
|
|
521
1068
|
}
|
|
1069
|
+
ownAppGitContextForShutdown() {
|
|
1070
|
+
this.ownsAppGitContext = true;
|
|
1071
|
+
}
|
|
522
1072
|
isDebugEnabled() {
|
|
523
1073
|
return this.debug;
|
|
524
1074
|
}
|
|
@@ -567,6 +1117,15 @@ var EventShipper = class {
|
|
|
567
1117
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
568
1118
|
if (!this.enabled) return;
|
|
569
1119
|
if (!eventId || !eventId.trim()) return;
|
|
1120
|
+
const capturedSticky = this.sticky.get(eventId);
|
|
1121
|
+
const eventAlreadyKnown = capturedSticky !== void 0 || this.buffers.has(eventId);
|
|
1122
|
+
const destination = currentReplayTraceDestination();
|
|
1123
|
+
const cloudReplay = destination !== void 0 && destination.kind !== "workshop";
|
|
1124
|
+
if ((capturedSticky == null ? void 0 : capturedSticky.replayOnly) === true || !eventAlreadyKnown && cloudReplay) {
|
|
1125
|
+
if (patch.isPending === false) this.sticky.delete(eventId);
|
|
1126
|
+
else this.sticky.set(eventId, { ...capturedSticky, replayOnly: true });
|
|
1127
|
+
return;
|
|
1128
|
+
}
|
|
570
1129
|
const maxChars = resolveMaxTextFieldChars(this.maxTextFieldCharsOpt);
|
|
571
1130
|
if (typeof patch.input === "string" && patch.input.length > maxChars) {
|
|
572
1131
|
patch = { ...patch, input: capText(patch.input, maxChars) };
|
|
@@ -588,6 +1147,13 @@ var EventShipper = class {
|
|
|
588
1147
|
}
|
|
589
1148
|
const sticky = (_c = this.sticky.get(eventId)) != null ? _c : {};
|
|
590
1149
|
const existing = (_d = this.buffers.get(eventId)) != null ? _d : {};
|
|
1150
|
+
patch = {
|
|
1151
|
+
...patch,
|
|
1152
|
+
properties: withAppGitProperties(
|
|
1153
|
+
patch.properties,
|
|
1154
|
+
this.appGitContext.forOperation(eventId, patch.properties, this.appGitOwner)
|
|
1155
|
+
)
|
|
1156
|
+
};
|
|
591
1157
|
const merged = mergePatches(existing, patch);
|
|
592
1158
|
merged.isPending = (_g = (_f = (_e = patch.isPending) != null ? _e : existing.isPending) != null ? _f : sticky.isPending) != null ? _g : true;
|
|
593
1159
|
this.buffers.set(eventId, merged);
|
|
@@ -601,6 +1167,8 @@ var EventShipper = class {
|
|
|
601
1167
|
if (t) clearTimeout(t);
|
|
602
1168
|
if (merged.isPending === false) {
|
|
603
1169
|
await this.flushOne(eventId);
|
|
1170
|
+
if (this.appGitContext.releaseOperation) this.appGitContext.releaseOperation(eventId, this.appGitOwner);
|
|
1171
|
+
else this.appGitContext.finishOperation(eventId);
|
|
604
1172
|
return;
|
|
605
1173
|
}
|
|
606
1174
|
const timeout = setTimeout(() => {
|
|
@@ -625,15 +1193,21 @@ var EventShipper = class {
|
|
|
625
1193
|
try {
|
|
626
1194
|
for (const t of this.timers.values()) clearTimeout(t);
|
|
627
1195
|
this.timers.clear();
|
|
1196
|
+
for (const [eventId, sticky] of this.sticky) {
|
|
1197
|
+
if (sticky.replayOnly) this.sticky.delete(eventId);
|
|
1198
|
+
}
|
|
628
1199
|
const settled = await raceWithTimeout(this.flush(), SHUTDOWN_DEADLINE_MS);
|
|
629
1200
|
if (!settled) this.warnShutdownDrop("in-flight request(s) at shutdown");
|
|
630
1201
|
} finally {
|
|
631
1202
|
this.shutdownDeadlineAt = void 0;
|
|
1203
|
+
if (this.ownsAppGitContext) this.appGitContext.dispose();
|
|
632
1204
|
}
|
|
633
1205
|
}
|
|
634
1206
|
async trackSignal(signal) {
|
|
635
1207
|
var _a, _b;
|
|
636
1208
|
if (!this.enabled) return;
|
|
1209
|
+
const destination = currentReplayTraceDestination();
|
|
1210
|
+
if (destination && destination.kind !== "workshop") return;
|
|
637
1211
|
const body = [
|
|
638
1212
|
{
|
|
639
1213
|
event_id: signal.eventId,
|
|
@@ -668,6 +1242,8 @@ var EventShipper = class {
|
|
|
668
1242
|
}
|
|
669
1243
|
async identify(users) {
|
|
670
1244
|
if (!this.enabled) return;
|
|
1245
|
+
const destination = currentReplayTraceDestination();
|
|
1246
|
+
if (destination && destination.kind !== "workshop") return;
|
|
671
1247
|
const list = Array.isArray(users) ? users : [users];
|
|
672
1248
|
const body = list.filter((user) => {
|
|
673
1249
|
if (!(user == null ? void 0 : user.userId) || !user.userId.trim()) {
|
|
@@ -720,8 +1296,9 @@ var EventShipper = class {
|
|
|
720
1296
|
this.buffers.delete(eventId);
|
|
721
1297
|
if (!accumulated) return;
|
|
722
1298
|
const sticky = (_a = this.sticky.get(eventId)) != null ? _a : {};
|
|
723
|
-
const
|
|
724
|
-
const
|
|
1299
|
+
const isPending = (_c = (_b = accumulated.isPending) != null ? _b : sticky.isPending) != null ? _c : true;
|
|
1300
|
+
const eventName = (_e = (_d = accumulated.eventName) != null ? _d : sticky.eventName) != null ? _e : this.defaultEventName;
|
|
1301
|
+
const userId = (_f = accumulated.userId) != null ? _f : sticky.userId;
|
|
725
1302
|
if (!userId) {
|
|
726
1303
|
if (this.debug) {
|
|
727
1304
|
console.warn(`${this.prefix} skipping track_partial for ${eventId}: missing userId`);
|
|
@@ -729,14 +1306,13 @@ var EventShipper = class {
|
|
|
729
1306
|
this.sticky.delete(eventId);
|
|
730
1307
|
return;
|
|
731
1308
|
}
|
|
732
|
-
const { wizardSession, ...restProperties } = (
|
|
1309
|
+
const { wizardSession, ...restProperties } = (_g = accumulated.properties) != null ? _g : {};
|
|
733
1310
|
let telemetryProperties = {};
|
|
734
1311
|
try {
|
|
735
1312
|
telemetryProperties = eventTelemetryProperties(accumulated);
|
|
736
1313
|
} catch (e) {
|
|
737
1314
|
}
|
|
738
|
-
const convoId = (
|
|
739
|
-
const isPending = (_h = (_g = accumulated.isPending) != null ? _g : sticky.isPending) != null ? _h : true;
|
|
1315
|
+
const convoId = (_h = accumulated.convoId) != null ? _h : sticky.convoId;
|
|
740
1316
|
const payload = {
|
|
741
1317
|
event_id: eventId,
|
|
742
1318
|
user_id: userId,
|
|
@@ -778,29 +1354,30 @@ var EventShipper = class {
|
|
|
778
1354
|
endpoint: url
|
|
779
1355
|
});
|
|
780
1356
|
}
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
});
|
|
788
|
-
}
|
|
1357
|
+
const mirror = this.localDebuggerUrl ? mirrorPartialEventToLocalDebugger(payload, {
|
|
1358
|
+
baseUrl: this.localDebuggerUrl,
|
|
1359
|
+
writeKey: this.writeKey,
|
|
1360
|
+
debug: this.debug,
|
|
1361
|
+
sdkName: this.sdkName
|
|
1362
|
+
}) : void 0;
|
|
789
1363
|
if (!this.writeKey) {
|
|
790
1364
|
if (!isPending) this.sticky.delete(eventId);
|
|
1365
|
+
if (mirror) await mirror;
|
|
791
1366
|
return;
|
|
792
1367
|
}
|
|
793
1368
|
const opts = this.requestOpts();
|
|
794
1369
|
if (!opts) {
|
|
795
1370
|
this.warnShutdownDrop(`track_partial ${eventId}`);
|
|
796
1371
|
if (!isPending) this.sticky.delete(eventId);
|
|
1372
|
+
if (mirror) await mirror;
|
|
797
1373
|
return;
|
|
798
1374
|
}
|
|
799
1375
|
const p = postJson(url, payload, this.requestHeaders(), opts);
|
|
800
|
-
|
|
1376
|
+
const combined = mirror ? Promise.all([mirror, p]).then(() => void 0) : p;
|
|
1377
|
+
this.inFlight.add(combined);
|
|
801
1378
|
try {
|
|
802
1379
|
try {
|
|
803
|
-
await
|
|
1380
|
+
await combined;
|
|
804
1381
|
if (this.debug) {
|
|
805
1382
|
console.log(`${this.prefix} sent track_partial ${eventId} (${eventName})`);
|
|
806
1383
|
}
|
|
@@ -812,7 +1389,7 @@ var EventShipper = class {
|
|
|
812
1389
|
);
|
|
813
1390
|
}
|
|
814
1391
|
} finally {
|
|
815
|
-
this.inFlight.delete(
|
|
1392
|
+
this.inFlight.delete(combined);
|
|
816
1393
|
}
|
|
817
1394
|
if (!isPending) {
|
|
818
1395
|
this.sticky.delete(eventId);
|
|
@@ -1065,6 +1642,13 @@ function redactJsonAttributeValue(key, value) {
|
|
|
1065
1642
|
if (scrubbedJson === json) return void 0;
|
|
1066
1643
|
return { stringValue: scrubbedJson };
|
|
1067
1644
|
}
|
|
1645
|
+
function appGitOwnerId2(prefix) {
|
|
1646
|
+
try {
|
|
1647
|
+
return `${prefix}:${randomUUID()}`;
|
|
1648
|
+
} catch (e) {
|
|
1649
|
+
return `${prefix}:${Date.now().toString(36)}:${Math.random().toString(36).slice(2)}`;
|
|
1650
|
+
}
|
|
1651
|
+
}
|
|
1068
1652
|
function identityAttrs(args) {
|
|
1069
1653
|
return [
|
|
1070
1654
|
attrString("ai.telemetry.metadata.raindrop.ai.userId", args.userId),
|
|
@@ -1087,23 +1671,30 @@ function applyOtelSpanAttributeLimit(limit) {
|
|
|
1087
1671
|
}
|
|
1088
1672
|
var TraceShipper = class {
|
|
1089
1673
|
constructor(opts) {
|
|
1674
|
+
this.appGitOwner = appGitOwnerId2("trace");
|
|
1675
|
+
this.appGitEventIds = /* @__PURE__ */ new WeakMap();
|
|
1676
|
+
this.appGitActiveSpans = /* @__PURE__ */ new Map();
|
|
1677
|
+
this.appGitCaptured = /* @__PURE__ */ new WeakSet();
|
|
1678
|
+
this.appGitAdded = /* @__PURE__ */ new WeakMap();
|
|
1090
1679
|
this.queue = [];
|
|
1091
1680
|
this.inFlight = /* @__PURE__ */ new Set();
|
|
1092
1681
|
this.hasShutdown = false;
|
|
1093
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
1094
|
-
this.
|
|
1095
|
-
this.
|
|
1682
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
1683
|
+
this.appGitContext = (_a = opts.appGitContext) != null ? _a : createAppGitContext(opts.appGit);
|
|
1684
|
+
this.ownsAppGitContext = opts.appGitContext === void 0;
|
|
1685
|
+
this.writeKey = (_b = opts.writeKey) == null ? void 0 : _b.trim();
|
|
1686
|
+
this.baseUrl = (_c = formatEndpoint(opts.endpoint)) != null ? _c : "https://api.raindrop.ai/v1/";
|
|
1096
1687
|
this.enabled = opts.enabled !== false;
|
|
1097
1688
|
this.debug = opts.debug;
|
|
1098
1689
|
this.debugSpans = opts.debugSpans === true;
|
|
1099
|
-
this.flushIntervalMs = (
|
|
1100
|
-
this.maxBatchSize = (
|
|
1101
|
-
this.maxQueueSize = (
|
|
1102
|
-
this.sdkName = (
|
|
1690
|
+
this.flushIntervalMs = (_d = opts.flushIntervalMs) != null ? _d : 1e3;
|
|
1691
|
+
this.maxBatchSize = (_e = opts.maxBatchSize) != null ? _e : 50;
|
|
1692
|
+
this.maxQueueSize = (_f = opts.maxQueueSize) != null ? _f : 5e3;
|
|
1693
|
+
this.sdkName = (_g = opts.sdkName) != null ? _g : "core";
|
|
1103
1694
|
this.prefix = `[raindrop-ai/${this.sdkName}]`;
|
|
1104
|
-
this.serviceName = (
|
|
1105
|
-
this.serviceVersion = (
|
|
1106
|
-
this.localDebuggerUrl = (
|
|
1695
|
+
this.serviceName = (_h = opts.serviceName) != null ? _h : "raindrop.core";
|
|
1696
|
+
this.serviceVersion = (_i = opts.serviceVersion) != null ? _i : "0.0.0";
|
|
1697
|
+
this.localDebuggerUrl = (_j = resolveLocalDebuggerBaseUrl(opts.localDebuggerUrl)) != null ? _j : void 0;
|
|
1107
1698
|
if (this.debug && this.localDebuggerUrl) {
|
|
1108
1699
|
console.log(`${this.prefix} Local debugger mirroring: ${this.localDebuggerUrl}`);
|
|
1109
1700
|
}
|
|
@@ -1167,7 +1758,10 @@ var TraceShipper = class {
|
|
|
1167
1758
|
try {
|
|
1168
1759
|
const result = this.transformSpanHook(current);
|
|
1169
1760
|
if (result === null) return null;
|
|
1170
|
-
if (result !== void 0)
|
|
1761
|
+
if (result !== void 0) {
|
|
1762
|
+
copyReplayTraceDestination(current, result);
|
|
1763
|
+
current = result;
|
|
1764
|
+
}
|
|
1171
1765
|
} catch (err) {
|
|
1172
1766
|
if (this.debug) {
|
|
1173
1767
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -1177,13 +1771,19 @@ var TraceShipper = class {
|
|
|
1177
1771
|
}
|
|
1178
1772
|
}
|
|
1179
1773
|
try {
|
|
1180
|
-
|
|
1774
|
+
const normalized = normalizeModelUsageSpan(current);
|
|
1775
|
+
copyReplayTraceDestination(current, normalized);
|
|
1776
|
+
current = normalized;
|
|
1181
1777
|
} catch (e) {
|
|
1182
1778
|
}
|
|
1183
1779
|
if (!this.disableDefaultRedaction) {
|
|
1184
|
-
|
|
1780
|
+
const redacted = defaultTransformSpan(current);
|
|
1781
|
+
copyReplayTraceDestination(current, redacted);
|
|
1782
|
+
current = redacted;
|
|
1185
1783
|
}
|
|
1186
|
-
|
|
1784
|
+
const capped = this.capSpanAttributes(current);
|
|
1785
|
+
copyReplayTraceDestination(current, capped);
|
|
1786
|
+
return capped;
|
|
1187
1787
|
}
|
|
1188
1788
|
isDebugEnabled() {
|
|
1189
1789
|
return this.debug;
|
|
@@ -1195,46 +1795,84 @@ var TraceShipper = class {
|
|
|
1195
1795
|
return { ...this.authHeaders(), ...projectIdHeaders(this.projectId) };
|
|
1196
1796
|
}
|
|
1197
1797
|
startSpan(args) {
|
|
1198
|
-
var _a, _b;
|
|
1798
|
+
var _a, _b, _c;
|
|
1199
1799
|
const ids = createSpanIds(args.parent);
|
|
1200
1800
|
const started = (_a = args.startTimeUnixNano) != null ? _a : nowUnixNanoString();
|
|
1201
1801
|
const attrs = [
|
|
1202
1802
|
attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId),
|
|
1203
1803
|
...identityAttrs(args),
|
|
1204
|
-
attrString("ai.operationId", args.operationId)
|
|
1804
|
+
attrString("ai.operationId", args.operationId),
|
|
1805
|
+
...Object.entries(evalScopeAttributes()).map(([key, value]) => attrString(key, value))
|
|
1205
1806
|
];
|
|
1206
1807
|
if ((_b = args.attributes) == null ? void 0 : _b.length) attrs.push(...args.attributes);
|
|
1207
|
-
const
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
);
|
|
1808
|
+
const tracksAppGit = this.appGitActiveSpans.has(args.eventId) || this.appGitActiveSpans.size < 1e4;
|
|
1809
|
+
const appGitOverrides = appGitPropertiesFromAttributes(attrs);
|
|
1810
|
+
const span = {
|
|
1811
|
+
ids,
|
|
1812
|
+
name: args.name,
|
|
1813
|
+
startTimeUnixNano: started,
|
|
1814
|
+
attributes: withAppGitAttributes(
|
|
1815
|
+
attrs,
|
|
1816
|
+
this.appGitContext.forOperation(args.eventId, appGitOverrides, this.appGitOwner)
|
|
1817
|
+
)
|
|
1818
|
+
};
|
|
1819
|
+
rememberReplayTraceDestination(span);
|
|
1820
|
+
this.appGitCaptured.add(span);
|
|
1821
|
+
this.appGitEventIds.set(span, args.eventId);
|
|
1822
|
+
if (tracksAppGit) {
|
|
1823
|
+
this.appGitActiveSpans.set(args.eventId, ((_c = this.appGitActiveSpans.get(args.eventId)) != null ? _c : 0) + 1);
|
|
1824
|
+
}
|
|
1825
|
+
this.appGitAdded.set(span, new Set(span.attributes.filter((attr) => !attrs.includes(attr))));
|
|
1826
|
+
const openSpan = buildOtlpSpan({
|
|
1827
|
+
ids: span.ids,
|
|
1828
|
+
name: span.name,
|
|
1829
|
+
startTimeUnixNano: span.startTimeUnixNano,
|
|
1830
|
+
endTimeUnixNano: span.startTimeUnixNano,
|
|
1831
|
+
// placeholder — will be updated on endSpan
|
|
1832
|
+
attributes: span.attributes,
|
|
1833
|
+
status: { code: SpanStatusCode.UNSET }
|
|
1834
|
+
});
|
|
1835
|
+
copyReplayTraceDestination(span, openSpan);
|
|
1836
|
+
this.mirrorToLocalDebugger(openSpan);
|
|
1219
1837
|
return span;
|
|
1220
1838
|
}
|
|
1221
|
-
mirrorToLocalDebugger(span) {
|
|
1222
|
-
|
|
1839
|
+
mirrorToLocalDebugger(span, completed = false) {
|
|
1840
|
+
const destination = replayTraceDestinationFor(span);
|
|
1841
|
+
if (destination && destination.kind !== "workshop") return;
|
|
1842
|
+
const localDebuggerUrl = (destination == null ? void 0 : destination.kind) === "workshop" ? destination.url : this.localDebuggerUrl;
|
|
1843
|
+
if (!localDebuggerUrl) return;
|
|
1223
1844
|
const redacted = this.redactSpan(span);
|
|
1224
1845
|
if (redacted === null) return;
|
|
1846
|
+
if (completed && (destination == null ? void 0 : destination.kind) === "workshop") {
|
|
1847
|
+
recordReplayExportedSpan(
|
|
1848
|
+
destination,
|
|
1849
|
+
base64ToHex(redacted.spanId),
|
|
1850
|
+
base64ToHex(redacted.traceId)
|
|
1851
|
+
);
|
|
1852
|
+
}
|
|
1225
1853
|
const body = buildExportTraceServiceRequest([redacted], this.serviceName, this.serviceVersion);
|
|
1226
|
-
mirrorTraceExportToLocalDebugger(body, {
|
|
1227
|
-
baseUrl:
|
|
1854
|
+
const p = mirrorTraceExportToLocalDebugger(body, {
|
|
1855
|
+
baseUrl: localDebuggerUrl,
|
|
1228
1856
|
debug: false,
|
|
1229
1857
|
sdkName: this.sdkName
|
|
1230
1858
|
});
|
|
1859
|
+
this.inFlight.add(p);
|
|
1860
|
+
void p.finally(() => {
|
|
1861
|
+
this.inFlight.delete(p);
|
|
1862
|
+
});
|
|
1231
1863
|
}
|
|
1232
1864
|
endSpan(span, extra) {
|
|
1233
|
-
var _a, _b;
|
|
1865
|
+
var _a, _b, _c;
|
|
1234
1866
|
if (span.endTimeUnixNano) return;
|
|
1235
1867
|
span.endTimeUnixNano = (_a = extra == null ? void 0 : extra.endTimeUnixNano) != null ? _a : nowUnixNanoString();
|
|
1236
1868
|
if ((_b = extra == null ? void 0 : extra.attributes) == null ? void 0 : _b.length) {
|
|
1869
|
+
const overrides = appGitPropertiesFromAttributes(extra.attributes);
|
|
1870
|
+
const eventId2 = this.appGitEventIds.get(span);
|
|
1871
|
+
const snapshot = eventId2 ? this.appGitContext.forOperation(eventId2, overrides, this.appGitOwner) : overrides;
|
|
1872
|
+
const added = this.appGitAdded.get(span);
|
|
1873
|
+
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));
|
|
1237
1874
|
span.attributes.push(...extra.attributes);
|
|
1875
|
+
span.attributes = withAppGitAttributes(span.attributes, snapshot);
|
|
1238
1876
|
}
|
|
1239
1877
|
let status = extra == null ? void 0 : extra.status;
|
|
1240
1878
|
if (!status && (extra == null ? void 0 : extra.error) !== void 0) {
|
|
@@ -1249,30 +1887,65 @@ var TraceShipper = class {
|
|
|
1249
1887
|
attributes: span.attributes,
|
|
1250
1888
|
status
|
|
1251
1889
|
});
|
|
1890
|
+
copyReplayTraceDestination(span, otlp);
|
|
1891
|
+
this.appGitCaptured.add(otlp);
|
|
1252
1892
|
this.enqueue(otlp);
|
|
1253
|
-
this.mirrorToLocalDebugger(otlp);
|
|
1893
|
+
this.mirrorToLocalDebugger(otlp, true);
|
|
1894
|
+
const eventId = this.appGitEventIds.get(span);
|
|
1895
|
+
if (eventId && this.appGitActiveSpans.has(eventId)) {
|
|
1896
|
+
const remaining = ((_c = this.appGitActiveSpans.get(eventId)) != null ? _c : 1) - 1;
|
|
1897
|
+
if (remaining > 0) this.appGitActiveSpans.set(eventId, remaining);
|
|
1898
|
+
else {
|
|
1899
|
+
this.appGitActiveSpans.delete(eventId);
|
|
1900
|
+
if (this.appGitContext.releaseOperation) this.appGitContext.releaseOperation(eventId, this.appGitOwner);
|
|
1901
|
+
else if (this.ownsAppGitContext) this.appGitContext.finishOperation(eventId);
|
|
1902
|
+
}
|
|
1903
|
+
}
|
|
1254
1904
|
}
|
|
1255
1905
|
createSpan(args) {
|
|
1256
1906
|
var _a;
|
|
1257
1907
|
const ids = createSpanIds(args.parent);
|
|
1258
1908
|
const attrs = [
|
|
1259
1909
|
attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId),
|
|
1260
|
-
...identityAttrs(args)
|
|
1910
|
+
...identityAttrs(args),
|
|
1911
|
+
...Object.entries(evalScopeAttributes()).map(([key, value]) => attrString(key, value))
|
|
1261
1912
|
];
|
|
1262
1913
|
if ((_a = args.attributes) == null ? void 0 : _a.length) attrs.push(...args.attributes);
|
|
1914
|
+
const tracksAppGit = !this.appGitActiveSpans.has(args.eventId);
|
|
1263
1915
|
const otlp = buildOtlpSpan({
|
|
1264
1916
|
ids,
|
|
1265
1917
|
name: args.name,
|
|
1266
1918
|
startTimeUnixNano: args.startTimeUnixNano,
|
|
1267
1919
|
endTimeUnixNano: args.endTimeUnixNano,
|
|
1268
|
-
attributes:
|
|
1920
|
+
attributes: withAppGitAttributes(
|
|
1921
|
+
attrs,
|
|
1922
|
+
this.appGitContext.forOperation(
|
|
1923
|
+
args.eventId,
|
|
1924
|
+
appGitPropertiesFromAttributes(attrs),
|
|
1925
|
+
this.appGitOwner
|
|
1926
|
+
)
|
|
1927
|
+
),
|
|
1269
1928
|
status: args.status
|
|
1270
1929
|
});
|
|
1930
|
+
rememberReplayTraceDestination(otlp);
|
|
1931
|
+
this.appGitCaptured.add(otlp);
|
|
1932
|
+
if (tracksAppGit) {
|
|
1933
|
+
if (this.appGitContext.releaseOperation) this.appGitContext.releaseOperation(args.eventId, this.appGitOwner);
|
|
1934
|
+
else if (this.ownsAppGitContext) this.appGitContext.finishOperation(args.eventId);
|
|
1935
|
+
}
|
|
1271
1936
|
this.enqueue(otlp);
|
|
1272
|
-
this.mirrorToLocalDebugger(otlp);
|
|
1937
|
+
this.mirrorToLocalDebugger(otlp, true);
|
|
1273
1938
|
}
|
|
1274
1939
|
enqueue(span) {
|
|
1940
|
+
var _a;
|
|
1275
1941
|
if (!this.enabled) return;
|
|
1942
|
+
const attributes = (_a = span.attributes) != null ? _a : [];
|
|
1943
|
+
const enriched = this.appGitCaptured.has(span) ? attributes : withAppGitAttributes(attributes, this.appGitContext.snapshot(appGitPropertiesFromAttributes(attributes)));
|
|
1944
|
+
if (enriched !== attributes) {
|
|
1945
|
+
const original = span;
|
|
1946
|
+
span = { ...span, attributes: enriched.filter((attr) => attr !== void 0) };
|
|
1947
|
+
copyReplayTraceDestination(original, span);
|
|
1948
|
+
}
|
|
1276
1949
|
if (this.debugSpans) {
|
|
1277
1950
|
const short = (s) => s ? s.slice(-8) : "none";
|
|
1278
1951
|
console.log(
|
|
@@ -1283,6 +1956,13 @@ var TraceShipper = class {
|
|
|
1283
1956
|
}
|
|
1284
1957
|
const redacted = this.redactSpan(span);
|
|
1285
1958
|
if (redacted === null) return;
|
|
1959
|
+
const destination = replayTraceDestinationFor(redacted);
|
|
1960
|
+
recordReplayExportedSpan(
|
|
1961
|
+
destination,
|
|
1962
|
+
base64ToHex(redacted.spanId),
|
|
1963
|
+
base64ToHex(redacted.traceId)
|
|
1964
|
+
);
|
|
1965
|
+
if ((destination == null ? void 0 : destination.kind) === "workshop") return;
|
|
1286
1966
|
if (this.queue.length >= this.maxQueueSize) {
|
|
1287
1967
|
this.queue.shift();
|
|
1288
1968
|
}
|
|
@@ -1301,47 +1981,67 @@ var TraceShipper = class {
|
|
|
1301
1981
|
}
|
|
1302
1982
|
}
|
|
1303
1983
|
async flush() {
|
|
1304
|
-
|
|
1984
|
+
var _a;
|
|
1985
|
+
if (!this.enabled) {
|
|
1986
|
+
await Promise.all([...this.inFlight].map((p) => p.catch(() => {
|
|
1987
|
+
})));
|
|
1988
|
+
return;
|
|
1989
|
+
}
|
|
1305
1990
|
if (this.timer) {
|
|
1306
1991
|
clearTimeout(this.timer);
|
|
1307
1992
|
this.timer = void 0;
|
|
1308
1993
|
}
|
|
1309
1994
|
while (this.queue.length > 0) {
|
|
1310
1995
|
const batch = this.queue.splice(0, this.maxBatchSize);
|
|
1311
|
-
|
|
1312
|
-
const
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
`${this.prefix} shutdown flush deadline exceeded; dropping ${batch.length} spans`
|
|
1318
|
-
)
|
|
1319
|
-
);
|
|
1320
|
-
continue;
|
|
1996
|
+
const groups = /* @__PURE__ */ new Map();
|
|
1997
|
+
for (const span of batch) {
|
|
1998
|
+
const destination = replayTraceDestinationFor(span);
|
|
1999
|
+
const spans = groups.get(destination);
|
|
2000
|
+
if (spans) spans.push(span);
|
|
2001
|
+
else groups.set(destination, [span]);
|
|
1321
2002
|
}
|
|
1322
|
-
const
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
endpoint: url
|
|
1328
|
-
});
|
|
1329
|
-
}
|
|
1330
|
-
const p = postJson(url, body, this.requestHeaders(), opts);
|
|
1331
|
-
this.inFlight.add(p);
|
|
1332
|
-
try {
|
|
1333
|
-
try {
|
|
1334
|
-
await p;
|
|
1335
|
-
if (this.debug) console.log(`${this.prefix} sent ${batch.length} spans`);
|
|
1336
|
-
} catch (err) {
|
|
1337
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
2003
|
+
for (const [destination, spans] of groups) {
|
|
2004
|
+
if (!destination && !this.writeKey) continue;
|
|
2005
|
+
if ((destination == null ? void 0 : destination.kind) === "workshop") continue;
|
|
2006
|
+
const opts = this.requestOpts();
|
|
2007
|
+
if (!opts) {
|
|
1338
2008
|
rateLimitedLog(
|
|
1339
|
-
`${this.prefix}.
|
|
1340
|
-
() => console.warn(
|
|
2009
|
+
`${this.prefix}.shutdown_deadline`,
|
|
2010
|
+
() => console.warn(
|
|
2011
|
+
`${this.prefix} shutdown flush deadline exceeded; dropping ${spans.length} spans`
|
|
2012
|
+
)
|
|
1341
2013
|
);
|
|
2014
|
+
continue;
|
|
2015
|
+
}
|
|
2016
|
+
const body = buildExportTraceServiceRequest(spans, this.serviceName, this.serviceVersion);
|
|
2017
|
+
const url = destination ? replayTraceUrl(destination.url) : `${this.baseUrl}traces`;
|
|
2018
|
+
const headers = destination ? {
|
|
2019
|
+
Authorization: `Bearer ${destination.apiKey}`,
|
|
2020
|
+
"X-Raindrop-Replay-Id": destination.replayId,
|
|
2021
|
+
"X-Raindrop-Project-Id": (_a = destination.projectId) != null ? _a : "default"
|
|
2022
|
+
} : this.requestHeaders();
|
|
2023
|
+
if (this.debug) {
|
|
2024
|
+
console.log(`${this.prefix} sending traces batch`, {
|
|
2025
|
+
spans: spans.length,
|
|
2026
|
+
endpoint: url
|
|
2027
|
+
});
|
|
2028
|
+
}
|
|
2029
|
+
const p = postJson(url, body, headers, opts);
|
|
2030
|
+
this.inFlight.add(p);
|
|
2031
|
+
try {
|
|
2032
|
+
try {
|
|
2033
|
+
await p;
|
|
2034
|
+
if (this.debug) console.log(`${this.prefix} sent ${spans.length} spans`);
|
|
2035
|
+
} catch (err) {
|
|
2036
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2037
|
+
rateLimitedLog(
|
|
2038
|
+
`${this.prefix}.send_spans_failed`,
|
|
2039
|
+
() => console.warn(`${this.prefix} failed to send ${spans.length} spans: ${msg}`)
|
|
2040
|
+
);
|
|
2041
|
+
}
|
|
2042
|
+
} finally {
|
|
2043
|
+
this.inFlight.delete(p);
|
|
1342
2044
|
}
|
|
1343
|
-
} finally {
|
|
1344
|
-
this.inFlight.delete(p);
|
|
1345
2045
|
}
|
|
1346
2046
|
}
|
|
1347
2047
|
}
|
|
@@ -1384,17 +2084,165 @@ var TraceShipper = class {
|
|
|
1384
2084
|
if (!settled) {
|
|
1385
2085
|
rateLimitedLog(
|
|
1386
2086
|
`${this.prefix}.shutdown_deadline`,
|
|
1387
|
-
() => console.warn(
|
|
2087
|
+
() => console.warn(
|
|
2088
|
+
`${this.prefix} shutdown flush deadline exceeded; abandoning in-flight spans`
|
|
2089
|
+
)
|
|
1388
2090
|
);
|
|
1389
2091
|
}
|
|
1390
2092
|
} finally {
|
|
1391
2093
|
this.shutdownDeadlineAt = void 0;
|
|
2094
|
+
if (this.ownsAppGitContext) this.appGitContext.dispose();
|
|
1392
2095
|
}
|
|
1393
2096
|
}
|
|
1394
2097
|
};
|
|
1395
2098
|
|
|
1396
2099
|
// ../core/dist/index.node.js
|
|
1397
2100
|
var import_async_hooks = require("async_hooks");
|
|
2101
|
+
var import_child_process = require("child_process");
|
|
2102
|
+
var import_path = require("path");
|
|
2103
|
+
var resolveLocal = (sourceDirectory, detectBranch, completed) => {
|
|
2104
|
+
const cwd = sourceDirectory ? (0, import_path.resolve)(sourceDirectory) : process.cwd();
|
|
2105
|
+
let cancelled = false;
|
|
2106
|
+
let active;
|
|
2107
|
+
let deadlineTimer;
|
|
2108
|
+
const deadline = Date.now() + 1e3;
|
|
2109
|
+
const run = (args, done) => {
|
|
2110
|
+
if (cancelled) return;
|
|
2111
|
+
const remaining = deadline - Date.now();
|
|
2112
|
+
if (remaining <= 0) {
|
|
2113
|
+
done(void 0);
|
|
2114
|
+
return;
|
|
2115
|
+
}
|
|
2116
|
+
try {
|
|
2117
|
+
active = (0, import_child_process.execFile)(
|
|
2118
|
+
"git",
|
|
2119
|
+
args,
|
|
2120
|
+
{
|
|
2121
|
+
cwd,
|
|
2122
|
+
encoding: "utf8",
|
|
2123
|
+
maxBuffer: 4096,
|
|
2124
|
+
windowsHide: true,
|
|
2125
|
+
env: {
|
|
2126
|
+
...process.env,
|
|
2127
|
+
// The selected application cwd, not the invoking shell's Git plumbing, owns identity.
|
|
2128
|
+
GIT_DIR: void 0,
|
|
2129
|
+
GIT_WORK_TREE: void 0,
|
|
2130
|
+
GIT_COMMON_DIR: void 0,
|
|
2131
|
+
GIT_NAMESPACE: void 0,
|
|
2132
|
+
GIT_INDEX_FILE: void 0,
|
|
2133
|
+
GIT_OBJECT_DIRECTORY: void 0,
|
|
2134
|
+
GIT_ALTERNATE_OBJECT_DIRECTORIES: void 0,
|
|
2135
|
+
GIT_CONFIG_PARAMETERS: void 0,
|
|
2136
|
+
GIT_CONFIG_COUNT: "0",
|
|
2137
|
+
GIT_TERMINAL_PROMPT: "0",
|
|
2138
|
+
GIT_OPTIONAL_LOCKS: "0"
|
|
2139
|
+
}
|
|
2140
|
+
},
|
|
2141
|
+
(error, stdout) => {
|
|
2142
|
+
clearTimeout(deadlineTimer);
|
|
2143
|
+
deadlineTimer = void 0;
|
|
2144
|
+
active = void 0;
|
|
2145
|
+
if (!cancelled) {
|
|
2146
|
+
try {
|
|
2147
|
+
done(error ? void 0 : stdout.trim());
|
|
2148
|
+
} catch (e) {
|
|
2149
|
+
}
|
|
2150
|
+
}
|
|
2151
|
+
}
|
|
2152
|
+
);
|
|
2153
|
+
active.unref();
|
|
2154
|
+
if (active.stdout && "unref" in active.stdout && typeof active.stdout.unref === "function")
|
|
2155
|
+
active.stdout.unref();
|
|
2156
|
+
if (active.stderr && "unref" in active.stderr && typeof active.stderr.unref === "function")
|
|
2157
|
+
active.stderr.unref();
|
|
2158
|
+
deadlineTimer = setTimeout(() => {
|
|
2159
|
+
try {
|
|
2160
|
+
active == null ? void 0 : active.kill("SIGKILL");
|
|
2161
|
+
} catch (e) {
|
|
2162
|
+
}
|
|
2163
|
+
}, remaining);
|
|
2164
|
+
deadlineTimer.unref();
|
|
2165
|
+
} catch (e) {
|
|
2166
|
+
try {
|
|
2167
|
+
done(void 0);
|
|
2168
|
+
} catch (e2) {
|
|
2169
|
+
}
|
|
2170
|
+
}
|
|
2171
|
+
};
|
|
2172
|
+
const scheduled = setTimeout(() => {
|
|
2173
|
+
try {
|
|
2174
|
+
run(["rev-parse", "HEAD"], (rawSha) => {
|
|
2175
|
+
const commitSha = validAppCommitSha(rawSha);
|
|
2176
|
+
if (!commitSha) {
|
|
2177
|
+
completed({});
|
|
2178
|
+
return;
|
|
2179
|
+
}
|
|
2180
|
+
run(["-c", "core.fsmonitor=false", "status", "--porcelain"], (status) => {
|
|
2181
|
+
const finish = (branch) => {
|
|
2182
|
+
run(["rev-parse", "HEAD"], (finalSha) => {
|
|
2183
|
+
const coherent = validAppCommitSha(finalSha) === commitSha;
|
|
2184
|
+
completed({
|
|
2185
|
+
commitSha,
|
|
2186
|
+
...coherent && status !== void 0 ? { commitDirty: status !== "" } : {},
|
|
2187
|
+
...coherent && branch && branch !== "HEAD" ? { branch } : {}
|
|
2188
|
+
});
|
|
2189
|
+
});
|
|
2190
|
+
};
|
|
2191
|
+
if (detectBranch) run(["symbolic-ref", "--quiet", "--short", "HEAD"], finish);
|
|
2192
|
+
else finish();
|
|
2193
|
+
});
|
|
2194
|
+
});
|
|
2195
|
+
} catch (e) {
|
|
2196
|
+
completed({});
|
|
2197
|
+
}
|
|
2198
|
+
}, 0);
|
|
2199
|
+
scheduled.unref();
|
|
2200
|
+
return () => {
|
|
2201
|
+
cancelled = true;
|
|
2202
|
+
clearTimeout(scheduled);
|
|
2203
|
+
clearTimeout(deadlineTimer);
|
|
2204
|
+
try {
|
|
2205
|
+
active == null ? void 0 : active.kill("SIGKILL");
|
|
2206
|
+
} catch (e) {
|
|
2207
|
+
}
|
|
2208
|
+
};
|
|
2209
|
+
};
|
|
2210
|
+
function createAppGitContext2(options, runtime = {}) {
|
|
2211
|
+
return new AppGitContext(options, { ...runtime, resolveLocal });
|
|
2212
|
+
}
|
|
2213
|
+
function hasDestination(options) {
|
|
2214
|
+
var _a;
|
|
2215
|
+
if (options.enabled === false) return false;
|
|
2216
|
+
return Boolean(((_a = options.writeKey) == null ? void 0 : _a.trim()) || resolveLocalDebuggerBaseUrl(options.localDebuggerUrl));
|
|
2217
|
+
}
|
|
2218
|
+
var EventShipper2 = class extends EventShipper {
|
|
2219
|
+
constructor(options) {
|
|
2220
|
+
var _a;
|
|
2221
|
+
const ownsAppGitContext = options.appGitContext === void 0;
|
|
2222
|
+
const appGitContext = (_a = options.appGitContext) != null ? _a : createAppGitContext2(options.appGit, { allowDiscovery: hasDestination(options) });
|
|
2223
|
+
try {
|
|
2224
|
+
super({ ...options, appGitContext });
|
|
2225
|
+
} catch (error) {
|
|
2226
|
+
if (ownsAppGitContext) appGitContext.dispose();
|
|
2227
|
+
throw error;
|
|
2228
|
+
}
|
|
2229
|
+
if (ownsAppGitContext) this.ownAppGitContextForShutdown();
|
|
2230
|
+
}
|
|
2231
|
+
};
|
|
2232
|
+
var TraceShipper2 = class extends TraceShipper {
|
|
2233
|
+
constructor(options) {
|
|
2234
|
+
var _a;
|
|
2235
|
+
const ownsAppGitContext = options.appGitContext === void 0;
|
|
2236
|
+
const appGitContext = (_a = options.appGitContext) != null ? _a : createAppGitContext2(options.appGit, { allowDiscovery: hasDestination(options) });
|
|
2237
|
+
try {
|
|
2238
|
+
super({ ...options, appGitContext });
|
|
2239
|
+
} catch (error) {
|
|
2240
|
+
if (ownsAppGitContext) appGitContext.dispose();
|
|
2241
|
+
throw error;
|
|
2242
|
+
}
|
|
2243
|
+
this.ownsAppGitContext = ownsAppGitContext;
|
|
2244
|
+
}
|
|
2245
|
+
};
|
|
1398
2246
|
globalThis.RAINDROP_ASYNC_LOCAL_STORAGE = import_async_hooks.AsyncLocalStorage;
|
|
1399
2247
|
var SUPPRESS_TRACING_KEY = /* @__PURE__ */ Symbol.for(
|
|
1400
2248
|
"OpenTelemetry SDK Context Key SUPPRESS_TRACING"
|
|
@@ -1459,7 +2307,20 @@ function loadConfig(projectDirectory) {
|
|
|
1459
2307
|
debug: process.env["RAINDROP_DEBUG"] === "true" ? true : (_g = merged.debug) != null ? _g : false,
|
|
1460
2308
|
captureSystemPrompt: process.env["RAINDROP_CAPTURE_SYSTEM_PROMPT"] !== void 0 ? process.env["RAINDROP_CAPTURE_SYSTEM_PROMPT"] === "true" : (_h = merged.capture_system_prompt) != null ? _h : false,
|
|
1461
2309
|
eventMetadata,
|
|
1462
|
-
localWorkshopUrl: resolveLocalWorkshopUrl(merged.local_workshop_url)
|
|
2310
|
+
localWorkshopUrl: resolveLocalWorkshopUrl(merged.local_workshop_url),
|
|
2311
|
+
appGit: mapAppGit(merged.app_git)
|
|
2312
|
+
};
|
|
2313
|
+
}
|
|
2314
|
+
function mapAppGit(value) {
|
|
2315
|
+
if (value === false) return false;
|
|
2316
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
2317
|
+
return {
|
|
2318
|
+
commitSha: "commit_sha" in value && (typeof value.commit_sha === "string" || value.commit_sha === null) ? value.commit_sha : void 0,
|
|
2319
|
+
commitDirty: "commit_dirty" in value && (typeof value.commit_dirty === "boolean" || value.commit_dirty === null) ? value.commit_dirty : void 0,
|
|
2320
|
+
branch: "branch" in value && (typeof value.branch === "string" || value.branch === null) ? value.branch : void 0,
|
|
2321
|
+
detectBranch: "detect_branch" in value && typeof value.detect_branch === "boolean" ? value.detect_branch : void 0,
|
|
2322
|
+
sourceDirectory: "source_directory" in value && typeof value.source_directory === "string" ? value.source_directory : void 0,
|
|
2323
|
+
autoDetect: "auto_detect" in value && typeof value.auto_detect === "boolean" ? value.auto_detect : void 0
|
|
1463
2324
|
};
|
|
1464
2325
|
}
|
|
1465
2326
|
function resolveLocalWorkshopUrl(fileValue) {
|
|
@@ -1476,7 +2337,7 @@ function resolveLocalWorkshopUrl(fileValue) {
|
|
|
1476
2337
|
// package.json
|
|
1477
2338
|
var package_default = {
|
|
1478
2339
|
name: "@raindrop-ai/opencode-plugin",
|
|
1479
|
-
version: "0.1.
|
|
2340
|
+
version: "0.1.4",
|
|
1480
2341
|
description: "Raindrop observability plugin for OpenCode \u2014 automatic session/event/span tracing",
|
|
1481
2342
|
type: "module",
|
|
1482
2343
|
main: "dist/index.js",
|
|
@@ -1547,7 +2408,7 @@ var PLUGIN_NAME = package_default.name;
|
|
|
1547
2408
|
var PLUGIN_VERSION = package_default.version;
|
|
1548
2409
|
|
|
1549
2410
|
// src/shipper.ts
|
|
1550
|
-
var
|
|
2411
|
+
var EventShipper3 = class extends EventShipper2 {
|
|
1551
2412
|
constructor(opts) {
|
|
1552
2413
|
var _a, _b, _c, _d;
|
|
1553
2414
|
super({
|
|
@@ -1559,7 +2420,7 @@ var EventShipper2 = class extends EventShipper {
|
|
|
1559
2420
|
});
|
|
1560
2421
|
}
|
|
1561
2422
|
};
|
|
1562
|
-
var
|
|
2423
|
+
var TraceShipper3 = class extends TraceShipper2 {
|
|
1563
2424
|
constructor(opts) {
|
|
1564
2425
|
var _a, _b, _c;
|
|
1565
2426
|
super({
|
|
@@ -1717,11 +2578,11 @@ function createSessionParentMapHelpers({
|
|
|
1717
2578
|
}) {
|
|
1718
2579
|
function applyChildSessionParentToState(childSessionId) {
|
|
1719
2580
|
const parentInfo = mapChildSessionToParent2.get(childSessionId);
|
|
1720
|
-
const
|
|
1721
|
-
if (!parentInfo || !
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
2581
|
+
const state2 = sessions2.get(childSessionId);
|
|
2582
|
+
if (!parentInfo || !state2) return;
|
|
2583
|
+
state2.parentId = parentInfo.parentId;
|
|
2584
|
+
state2.parentTaskSpanIds = parentInfo.parentTaskSpanIds;
|
|
2585
|
+
state2.parentEventContext = parentInfo.eventContext;
|
|
1725
2586
|
}
|
|
1726
2587
|
function queuePendingChildByCallKey(key, childSessionId) {
|
|
1727
2588
|
var _a;
|
|
@@ -1817,10 +2678,10 @@ function markTaskCallFinished(sessionID, callID) {
|
|
|
1817
2678
|
running.delete(callID);
|
|
1818
2679
|
if (running.size === 0) runningTaskCallsBySession.delete(sessionID);
|
|
1819
2680
|
}
|
|
1820
|
-
function endPendingToolSpanWithError(
|
|
1821
|
-
const startInfo =
|
|
2681
|
+
function endPendingToolSpanWithError(state2, callID, tool, toolCallArgs, errorMessage, traceShipper) {
|
|
2682
|
+
const startInfo = state2.toolSpanStarts.get(callID);
|
|
1822
2683
|
if (!startInfo) return false;
|
|
1823
|
-
|
|
2684
|
+
state2.toolSpanStarts.delete(callID);
|
|
1824
2685
|
const error = new Error(errorMessage);
|
|
1825
2686
|
const endAttrs = [
|
|
1826
2687
|
attrString("ai.toolCall.args", toolCallArgs),
|
|
@@ -1920,17 +2781,17 @@ function createHooks(config, worktree, directory, eventShipper, traceShipper) {
|
|
|
1920
2781
|
if (info == null || typeof info !== "object")
|
|
1921
2782
|
throw new Error("session.created: props.info is required");
|
|
1922
2783
|
const parentID = info["parentID"];
|
|
1923
|
-
let
|
|
1924
|
-
if (!
|
|
1925
|
-
|
|
1926
|
-
sessions.set(sessionID,
|
|
2784
|
+
let state2 = sessions.get(sessionID);
|
|
2785
|
+
if (!state2) {
|
|
2786
|
+
state2 = createSessionState(sessionID);
|
|
2787
|
+
sessions.set(sessionID, state2);
|
|
1927
2788
|
}
|
|
1928
|
-
|
|
1929
|
-
if (
|
|
2789
|
+
state2.parentId = parentID;
|
|
2790
|
+
if (state2.parentId) mapChildSessionToParent.set(sessionID, { parentId: state2.parentId });
|
|
1930
2791
|
} else if (event.type === "session.compacted") {
|
|
1931
|
-
const
|
|
1932
|
-
if (!
|
|
1933
|
-
|
|
2792
|
+
const state2 = sessions.get(String(sessionID));
|
|
2793
|
+
if (!state2) return;
|
|
2794
|
+
state2.isCompacting = true;
|
|
1934
2795
|
} else if (event.type === "message.part.updated") {
|
|
1935
2796
|
const part = props["part"];
|
|
1936
2797
|
if (part == null || typeof part !== "object")
|
|
@@ -1942,10 +2803,10 @@ function createHooks(config, worktree, directory, eventShipper, traceShipper) {
|
|
|
1942
2803
|
throw new Error("message.part.updated: part.sessionID is required");
|
|
1943
2804
|
if (messageId == null || messageId === "")
|
|
1944
2805
|
throw new Error("message.part.updated: part.messageID is required");
|
|
1945
|
-
const
|
|
1946
|
-
if (!
|
|
2806
|
+
const state2 = sessions.get(partSessionID);
|
|
2807
|
+
if (!state2) return;
|
|
1947
2808
|
if (partObj["type"] === "text" && typeof partObj["text"] === "string") {
|
|
1948
|
-
|
|
2809
|
+
state2.outputParts.set(messageId, capText2(partObj["text"]));
|
|
1949
2810
|
} else if (partObj["type"] === "tool" && messageId) {
|
|
1950
2811
|
const tool = partObj["tool"];
|
|
1951
2812
|
const callID = partObj["callID"];
|
|
@@ -1977,7 +2838,7 @@ function createHooks(config, worktree, directory, eventShipper, traceShipper) {
|
|
|
1977
2838
|
const input = toolState["input"];
|
|
1978
2839
|
const toolCallArgs = input === void 0 ? void 0 : typeof input === "string" ? capText2(input) : boundedStringify(input);
|
|
1979
2840
|
if (endPendingToolSpanWithError(
|
|
1980
|
-
|
|
2841
|
+
state2,
|
|
1981
2842
|
callID,
|
|
1982
2843
|
tool,
|
|
1983
2844
|
toolCallArgs,
|
|
@@ -1988,7 +2849,7 @@ function createHooks(config, worktree, directory, eventShipper, traceShipper) {
|
|
|
1988
2849
|
}
|
|
1989
2850
|
}
|
|
1990
2851
|
} else if (partObj["type"] === "reasoning" && typeof partObj["text"] === "string") {
|
|
1991
|
-
|
|
2852
|
+
state2.reasoningParts.set(messageId, capText2(partObj["text"]));
|
|
1992
2853
|
}
|
|
1993
2854
|
} else if (event.type === "message.updated") {
|
|
1994
2855
|
const msgInfo = props["info"];
|
|
@@ -2008,10 +2869,10 @@ function createHooks(config, worktree, directory, eventShipper, traceShipper) {
|
|
|
2008
2869
|
throw new Error("message.updated: info.time is required");
|
|
2009
2870
|
const timeObj = time;
|
|
2010
2871
|
if (timeObj["completed"] == null) return;
|
|
2011
|
-
const
|
|
2012
|
-
if (!
|
|
2013
|
-
if (
|
|
2014
|
-
|
|
2872
|
+
const state2 = sessions.get(msgSessionID);
|
|
2873
|
+
if (!state2 || !state2.currentEventId || !state2.currentRootSpan) return;
|
|
2874
|
+
if (state2.processedMessages.has(messageId)) return;
|
|
2875
|
+
state2.processedMessages.add(messageId);
|
|
2015
2876
|
const tokens = info2["tokens"];
|
|
2016
2877
|
if (tokens == null || typeof tokens !== "object")
|
|
2017
2878
|
throw new Error("message.updated: info.tokens is required");
|
|
@@ -2028,13 +2889,13 @@ function createHooks(config, worktree, directory, eventShipper, traceShipper) {
|
|
|
2028
2889
|
);
|
|
2029
2890
|
const modelName = `${providerID}/${modelID}`;
|
|
2030
2891
|
const finishReason = info2["finish"];
|
|
2031
|
-
const outputText =
|
|
2032
|
-
const reasoningText =
|
|
2892
|
+
const outputText = state2.outputParts.get(messageId);
|
|
2893
|
+
const reasoningText = state2.reasoningParts.get(messageId);
|
|
2033
2894
|
const isToolCallsCompletion = finishReason === "tool-calls";
|
|
2034
2895
|
if (outputText !== void 0 && outputText.trim().length > 0) {
|
|
2035
|
-
|
|
2896
|
+
state2.turnOutputParts.push(outputText);
|
|
2036
2897
|
}
|
|
2037
|
-
|
|
2898
|
+
state2.turnOutputTokens += outputTokens;
|
|
2038
2899
|
if (outputText === void 0 && !isToolCallsCompletion) return;
|
|
2039
2900
|
const msgError = info2["error"];
|
|
2040
2901
|
const errorForSpan = msgError ? (() => {
|
|
@@ -2054,17 +2915,17 @@ type: ${name != null ? name : "UnknownError"}`;
|
|
|
2054
2915
|
attrString("ai.response.text", responseText),
|
|
2055
2916
|
...buildLlmGenAiAttributes({ providerID, modelID, tokens: tokensObj })
|
|
2056
2917
|
];
|
|
2057
|
-
if (
|
|
2918
|
+
if (state2.currentSystemPrompt) {
|
|
2058
2919
|
llmAttrs.push(
|
|
2059
2920
|
attrString("gen_ai.prompt.0.role", "system"),
|
|
2060
|
-
attrString("gen_ai.prompt.0.content",
|
|
2921
|
+
attrString("gen_ai.prompt.0.content", state2.currentSystemPrompt)
|
|
2061
2922
|
);
|
|
2062
2923
|
}
|
|
2063
|
-
const llmParent =
|
|
2924
|
+
const llmParent = state2.parentId && state2.parentTaskSpanIds ? state2.parentTaskSpanIds : state2.currentRootSpan.ids;
|
|
2064
2925
|
const llmSpan = traceShipper.startSpan({
|
|
2065
2926
|
name: modelName,
|
|
2066
2927
|
parent: llmParent,
|
|
2067
|
-
eventId:
|
|
2928
|
+
eventId: state2.currentEventId,
|
|
2068
2929
|
attributes: llmAttrs
|
|
2069
2930
|
});
|
|
2070
2931
|
if (typeof timeObj["created"] === "number") {
|
|
@@ -2075,40 +2936,40 @@ type: ${name != null ? name : "UnknownError"}`;
|
|
|
2075
2936
|
return;
|
|
2076
2937
|
}
|
|
2077
2938
|
if (outputText === void 0) return;
|
|
2078
|
-
const turnOutputText = capText2(
|
|
2079
|
-
const rootSpan =
|
|
2080
|
-
const isCompaction =
|
|
2081
|
-
if (
|
|
2082
|
-
const userInput = unwrapQuotes(
|
|
2939
|
+
const turnOutputText = capText2(state2.turnOutputParts.join("\n\n"));
|
|
2940
|
+
const rootSpan = state2.currentRootSpan;
|
|
2941
|
+
const isCompaction = state2.isCompacting === true;
|
|
2942
|
+
if (state2.parentId) {
|
|
2943
|
+
const userInput = unwrapQuotes(state2.currentInput);
|
|
2083
2944
|
const llmAttrs = [
|
|
2084
2945
|
attrString("ai.operationId", "generateText"),
|
|
2085
2946
|
attrString("ai.prompt", userInput),
|
|
2086
2947
|
attrString(
|
|
2087
2948
|
"ai.prompt.messages",
|
|
2088
|
-
buildPromptMessages(
|
|
2949
|
+
buildPromptMessages(state2.currentSystemPrompt, state2.currentInput)
|
|
2089
2950
|
),
|
|
2090
2951
|
attrString("ai.response.text", turnOutputText),
|
|
2091
2952
|
...buildLlmGenAiAttributes({ providerID, modelID, tokens: tokensObj })
|
|
2092
2953
|
];
|
|
2093
|
-
if (
|
|
2954
|
+
if (state2.currentSystemPrompt) {
|
|
2094
2955
|
llmAttrs.push(
|
|
2095
2956
|
attrString("gen_ai.prompt.0.role", "system"),
|
|
2096
|
-
attrString("gen_ai.prompt.0.content",
|
|
2957
|
+
attrString("gen_ai.prompt.0.content", state2.currentSystemPrompt)
|
|
2097
2958
|
);
|
|
2098
2959
|
}
|
|
2099
|
-
if (!
|
|
2960
|
+
if (!state2.parentTaskSpanIds) {
|
|
2100
2961
|
traceShipper.endSpan(rootSpan, {
|
|
2101
2962
|
error: "Missing strict parent task for child session"
|
|
2102
2963
|
});
|
|
2103
|
-
|
|
2104
|
-
|
|
2964
|
+
state2.currentRootSpan = void 0;
|
|
2965
|
+
state2.currentEventId = void 0;
|
|
2105
2966
|
await traceShipper.flush();
|
|
2106
2967
|
return;
|
|
2107
2968
|
}
|
|
2108
2969
|
const finalLlmSpan = traceShipper.startSpan({
|
|
2109
2970
|
name: modelName,
|
|
2110
|
-
parent:
|
|
2111
|
-
eventId:
|
|
2971
|
+
parent: state2.parentTaskSpanIds,
|
|
2972
|
+
eventId: state2.currentEventId,
|
|
2112
2973
|
attributes: llmAttrs
|
|
2113
2974
|
});
|
|
2114
2975
|
if (typeof timeObj["created"] === "number") {
|
|
@@ -2118,19 +2979,19 @@ type: ${name != null ? name : "UnknownError"}`;
|
|
|
2118
2979
|
traceShipper.endSpan(rootSpan, {
|
|
2119
2980
|
attributes: [
|
|
2120
2981
|
attrString("is_subagent", "true"),
|
|
2121
|
-
attrString("parent_session_id",
|
|
2982
|
+
attrString("parent_session_id", state2.parentId)
|
|
2122
2983
|
],
|
|
2123
2984
|
error: errorForSpan
|
|
2124
2985
|
});
|
|
2125
2986
|
} else {
|
|
2126
2987
|
rootSpan.name = isCompaction ? "ai.compaction" : modelName;
|
|
2127
|
-
const userInput = unwrapQuotes(
|
|
2988
|
+
const userInput = unwrapQuotes(state2.currentInput);
|
|
2128
2989
|
const rootAttrs = [
|
|
2129
2990
|
attrString("ai.operationId", "generateText"),
|
|
2130
2991
|
attrString("ai.prompt", userInput),
|
|
2131
2992
|
attrString(
|
|
2132
2993
|
"ai.prompt.messages",
|
|
2133
|
-
buildPromptMessages(
|
|
2994
|
+
buildPromptMessages(state2.currentSystemPrompt, state2.currentInput)
|
|
2134
2995
|
),
|
|
2135
2996
|
attrString("ai.response.text", turnOutputText),
|
|
2136
2997
|
...buildLlmGenAiAttributes({ providerID, modelID, tokens: tokensObj })
|
|
@@ -2139,10 +3000,10 @@ type: ${name != null ? name : "UnknownError"}`;
|
|
|
2139
3000
|
rootAttrs.push(attrString("is_compaction", "true"));
|
|
2140
3001
|
}
|
|
2141
3002
|
rootAttrs.push(attrString("message_id", messageId));
|
|
2142
|
-
if (
|
|
3003
|
+
if (state2.currentSystemPrompt) {
|
|
2143
3004
|
rootAttrs.push(
|
|
2144
3005
|
attrString("gen_ai.prompt.0.role", "system"),
|
|
2145
|
-
attrString("gen_ai.prompt.0.content",
|
|
3006
|
+
attrString("gen_ai.prompt.0.content", state2.currentSystemPrompt)
|
|
2146
3007
|
);
|
|
2147
3008
|
}
|
|
2148
3009
|
traceShipper.endSpan(rootSpan, {
|
|
@@ -2150,24 +3011,24 @@ type: ${name != null ? name : "UnknownError"}`;
|
|
|
2150
3011
|
error: errorForSpan
|
|
2151
3012
|
});
|
|
2152
3013
|
if (isCompaction) {
|
|
2153
|
-
|
|
3014
|
+
state2.isCompacting = false;
|
|
2154
3015
|
}
|
|
2155
3016
|
}
|
|
2156
|
-
|
|
3017
|
+
state2.currentRootSpan = void 0;
|
|
2157
3018
|
const hasAssistantResponse = turnOutputText.trim().length > 0;
|
|
2158
3019
|
if (!hasAssistantResponse && !msgError) {
|
|
2159
3020
|
await traceShipper.flush();
|
|
2160
|
-
|
|
3021
|
+
state2.currentEventId = void 0;
|
|
2161
3022
|
return;
|
|
2162
3023
|
}
|
|
2163
|
-
if (!
|
|
2164
|
-
await eventShipper.finish(
|
|
2165
|
-
userId: (_d = (_c =
|
|
3024
|
+
if (!state2.parentId) {
|
|
3025
|
+
await eventShipper.finish(state2.currentEventId, {
|
|
3026
|
+
userId: (_d = (_c = state2.eventMetadata) == null ? void 0 : _c.userId) != null ? _d : state2.sessionId,
|
|
2166
3027
|
model: modelID,
|
|
2167
3028
|
output: msgError ? void 0 : turnOutputText,
|
|
2168
3029
|
usage: {
|
|
2169
3030
|
promptTokens: inputTokens,
|
|
2170
|
-
completionTokens:
|
|
3031
|
+
completionTokens: state2.turnOutputTokens
|
|
2171
3032
|
},
|
|
2172
3033
|
error: msgError ? {
|
|
2173
3034
|
name: msgError.name,
|
|
@@ -2182,35 +3043,35 @@ type: ${name != null ? name : "UnknownError"}`;
|
|
|
2182
3043
|
});
|
|
2183
3044
|
}
|
|
2184
3045
|
await traceShipper.flush();
|
|
2185
|
-
|
|
3046
|
+
state2.currentEventId = void 0;
|
|
2186
3047
|
} else if (event.type === "session.idle") {
|
|
2187
3048
|
if (!sessionID) return;
|
|
2188
|
-
const
|
|
2189
|
-
if (!
|
|
2190
|
-
if (
|
|
2191
|
-
traceShipper.endSpan(
|
|
2192
|
-
|
|
3049
|
+
const state2 = sessions.get(String(sessionID));
|
|
3050
|
+
if (!state2) return;
|
|
3051
|
+
if (state2.currentRootSpan) {
|
|
3052
|
+
traceShipper.endSpan(state2.currentRootSpan);
|
|
3053
|
+
state2.currentRootSpan = void 0;
|
|
2193
3054
|
}
|
|
2194
|
-
if (
|
|
2195
|
-
|
|
3055
|
+
if (state2.currentEventId) {
|
|
3056
|
+
state2.currentEventId = void 0;
|
|
2196
3057
|
}
|
|
2197
|
-
|
|
3058
|
+
state2.isCompacting = false;
|
|
2198
3059
|
await Promise.all([eventShipper.flush(), traceShipper.flush()]);
|
|
2199
|
-
if (
|
|
3060
|
+
if (state2.parentId) {
|
|
2200
3061
|
cleanupSessionParentMap(String(sessionID));
|
|
2201
3062
|
sessions.delete(String(sessionID));
|
|
2202
3063
|
} else {
|
|
2203
3064
|
}
|
|
2204
3065
|
} else if (event.type === "session.deleted") {
|
|
2205
3066
|
if (!sessionID) return;
|
|
2206
|
-
const
|
|
2207
|
-
if (!
|
|
2208
|
-
if (
|
|
2209
|
-
traceShipper.endSpan(
|
|
2210
|
-
|
|
3067
|
+
const state2 = sessions.get(String(sessionID));
|
|
3068
|
+
if (!state2) return;
|
|
3069
|
+
if (state2.currentRootSpan) {
|
|
3070
|
+
traceShipper.endSpan(state2.currentRootSpan);
|
|
3071
|
+
state2.currentRootSpan = void 0;
|
|
2211
3072
|
}
|
|
2212
|
-
if (
|
|
2213
|
-
|
|
3073
|
+
if (state2.currentEventId) {
|
|
3074
|
+
state2.currentEventId = void 0;
|
|
2214
3075
|
}
|
|
2215
3076
|
cleanupSessionParentMap(String(sessionID));
|
|
2216
3077
|
await Promise.all([eventShipper.flush(), traceShipper.flush()]);
|
|
@@ -2219,8 +3080,8 @@ type: ${name != null ? name : "UnknownError"}`;
|
|
|
2219
3080
|
const errorSessionID = (_h = props["sessionID"]) != null ? _h : sessionID;
|
|
2220
3081
|
if (errorSessionID === void 0 || errorSessionID === "")
|
|
2221
3082
|
throw new Error("session.error: missing sessionID");
|
|
2222
|
-
const
|
|
2223
|
-
if (!
|
|
3083
|
+
const state2 = sessions.get(String(errorSessionID));
|
|
3084
|
+
if (!state2) return;
|
|
2224
3085
|
const errorObj = props["error"];
|
|
2225
3086
|
if (errorObj == null) throw new Error("session.error: missing error object");
|
|
2226
3087
|
const errorName = errorObj.name;
|
|
@@ -2230,12 +3091,12 @@ type: ${name != null ? name : "UnknownError"}`;
|
|
|
2230
3091
|
const errorStr = `${errorMessage != null ? errorMessage : errorName}
|
|
2231
3092
|
|
|
2232
3093
|
type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
2233
|
-
if (
|
|
2234
|
-
traceShipper.endSpan(
|
|
2235
|
-
|
|
3094
|
+
if (state2.currentRootSpan) {
|
|
3095
|
+
traceShipper.endSpan(state2.currentRootSpan, { error: errorStr });
|
|
3096
|
+
state2.currentRootSpan = void 0;
|
|
2236
3097
|
}
|
|
2237
|
-
if (
|
|
2238
|
-
|
|
3098
|
+
if (state2.currentEventId) {
|
|
3099
|
+
state2.currentEventId = void 0;
|
|
2239
3100
|
}
|
|
2240
3101
|
cleanupSessionParentMap(String(errorSessionID));
|
|
2241
3102
|
await Promise.all([eventShipper.flush(), traceShipper.flush()]);
|
|
@@ -2255,15 +3116,15 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
2255
3116
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
2256
3117
|
try {
|
|
2257
3118
|
const { sessionID } = messageInput;
|
|
2258
|
-
let
|
|
2259
|
-
if (!
|
|
2260
|
-
|
|
2261
|
-
sessions.set(sessionID,
|
|
3119
|
+
let state2 = sessions.get(sessionID);
|
|
3120
|
+
if (!state2) {
|
|
3121
|
+
state2 = createSessionState(sessionID);
|
|
3122
|
+
sessions.set(sessionID, state2);
|
|
2262
3123
|
}
|
|
2263
3124
|
applyChildSessionParentToState(sessionID);
|
|
2264
|
-
if (
|
|
2265
|
-
traceShipper.endSpan(
|
|
2266
|
-
|
|
3125
|
+
if (state2.currentRootSpan) {
|
|
3126
|
+
traceShipper.endSpan(state2.currentRootSpan);
|
|
3127
|
+
state2.currentRootSpan = void 0;
|
|
2267
3128
|
}
|
|
2268
3129
|
if (output == null) throw new Error("chat.message: output is required");
|
|
2269
3130
|
const parts = output.parts;
|
|
@@ -2294,39 +3155,39 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
2294
3155
|
}
|
|
2295
3156
|
}
|
|
2296
3157
|
}
|
|
2297
|
-
|
|
3158
|
+
state2.eventMetadata = {
|
|
2298
3159
|
...baseMeta,
|
|
2299
3160
|
...promptMeta,
|
|
2300
3161
|
properties: baseMeta.properties || promptMeta.properties ? { ...(_a = baseMeta.properties) != null ? _a : {}, ...(_b = promptMeta.properties) != null ? _b : {} } : void 0
|
|
2301
3162
|
};
|
|
2302
3163
|
const userText = capText2(textParts.join("\n"));
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
|
|
2306
|
-
if (
|
|
2307
|
-
if (!
|
|
3164
|
+
state2.currentInput = userText;
|
|
3165
|
+
state2.turnOutputParts = [];
|
|
3166
|
+
state2.turnOutputTokens = 0;
|
|
3167
|
+
if (state2.parentId) {
|
|
3168
|
+
if (!state2.parentTaskSpanIds || !state2.parentEventContext) {
|
|
2308
3169
|
return;
|
|
2309
3170
|
}
|
|
2310
|
-
|
|
2311
|
-
|
|
3171
|
+
state2.currentEventId = state2.parentEventContext.eventId;
|
|
3172
|
+
state2.currentRootSpan = traceShipper.startSpan({
|
|
2312
3173
|
name: "Subagent",
|
|
2313
|
-
parent:
|
|
2314
|
-
eventId:
|
|
3174
|
+
parent: state2.parentTaskSpanIds,
|
|
3175
|
+
eventId: state2.currentEventId,
|
|
2315
3176
|
attributes: [
|
|
2316
3177
|
attrString("workspace", worktree),
|
|
2317
3178
|
attrString("directory", directory),
|
|
2318
3179
|
attrString("hostname", hostname),
|
|
2319
3180
|
attrString("os", os),
|
|
2320
3181
|
attrString("is_subagent", "true"),
|
|
2321
|
-
attrString("parent_session_id",
|
|
3182
|
+
attrString("parent_session_id", state2.parentId)
|
|
2322
3183
|
]
|
|
2323
3184
|
});
|
|
2324
3185
|
return;
|
|
2325
3186
|
}
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
name:
|
|
2329
|
-
eventId:
|
|
3187
|
+
state2.currentEventId = generateId();
|
|
3188
|
+
state2.currentRootSpan = traceShipper.startSpan({
|
|
3189
|
+
name: state2.isCompacting ? "ai.compaction" : "ai.event",
|
|
3190
|
+
eventId: state2.currentEventId,
|
|
2330
3191
|
attributes: [
|
|
2331
3192
|
attrString("workspace", worktree),
|
|
2332
3193
|
attrString("directory", directory),
|
|
@@ -2334,11 +3195,11 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
2334
3195
|
attrString("os", os)
|
|
2335
3196
|
]
|
|
2336
3197
|
});
|
|
2337
|
-
await eventShipper.patch(
|
|
3198
|
+
await eventShipper.patch(state2.currentEventId, {
|
|
2338
3199
|
isPending: true,
|
|
2339
|
-
userId: (_d = (_c =
|
|
2340
|
-
convoId:
|
|
2341
|
-
eventName: (_f = (_e =
|
|
3200
|
+
userId: (_d = (_c = state2.eventMetadata) == null ? void 0 : _c.userId) != null ? _d : state2.sessionId,
|
|
3201
|
+
convoId: state2.sessionId,
|
|
3202
|
+
eventName: (_f = (_e = state2.eventMetadata) == null ? void 0 : _e.eventName) != null ? _f : config.eventName,
|
|
2342
3203
|
input: userText,
|
|
2343
3204
|
...newAttachments.length > 0 ? { attachments: newAttachments } : {},
|
|
2344
3205
|
properties: {
|
|
@@ -2347,7 +3208,7 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
2347
3208
|
hostname,
|
|
2348
3209
|
os,
|
|
2349
3210
|
plugin_version: PLUGIN_VERSION,
|
|
2350
|
-
...(_g =
|
|
3211
|
+
...(_g = state2.eventMetadata) == null ? void 0 : _g.properties
|
|
2351
3212
|
}
|
|
2352
3213
|
});
|
|
2353
3214
|
} catch (err) {
|
|
@@ -2361,16 +3222,16 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
2361
3222
|
var _a, _b, _c;
|
|
2362
3223
|
try {
|
|
2363
3224
|
const { tool, sessionID, callID } = toolInput;
|
|
2364
|
-
const
|
|
2365
|
-
if (!
|
|
2366
|
-
const spanParent =
|
|
3225
|
+
const state2 = sessions.get(sessionID);
|
|
3226
|
+
if (!state2 || !state2.currentEventId) return;
|
|
3227
|
+
const spanParent = state2.parentId && state2.parentTaskSpanIds ? state2.parentTaskSpanIds : (_a = state2.currentRootSpan) == null ? void 0 : _a.ids;
|
|
2367
3228
|
if (!spanParent) return;
|
|
2368
3229
|
const startTimeUnixNano = nowUnixNanoString();
|
|
2369
3230
|
if (tool === "task") {
|
|
2370
3231
|
const liveTaskSpan = traceShipper.startSpan({
|
|
2371
3232
|
name: "ai.toolCall",
|
|
2372
3233
|
parent: spanParent,
|
|
2373
|
-
eventId:
|
|
3234
|
+
eventId: state2.currentEventId,
|
|
2374
3235
|
attributes: [
|
|
2375
3236
|
attrString("ai.operationId", "ai.toolCall"),
|
|
2376
3237
|
attrString("ai.toolCall.name", tool),
|
|
@@ -2381,9 +3242,9 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
2381
3242
|
const ctx = {
|
|
2382
3243
|
ids: liveTaskSpan.ids,
|
|
2383
3244
|
eventContext: {
|
|
2384
|
-
eventId:
|
|
2385
|
-
userId: (_c = (_b =
|
|
2386
|
-
convoId:
|
|
3245
|
+
eventId: state2.currentEventId,
|
|
3246
|
+
userId: (_c = (_b = state2.eventMetadata) == null ? void 0 : _b.userId) != null ? _c : state2.sessionId,
|
|
3247
|
+
convoId: state2.sessionId
|
|
2387
3248
|
}
|
|
2388
3249
|
};
|
|
2389
3250
|
taskContexts.set(callKey(sessionID, callID), ctx);
|
|
@@ -2394,18 +3255,18 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
2394
3255
|
}
|
|
2395
3256
|
running.add(callID);
|
|
2396
3257
|
resolvePendingChildrenForCall(sessionID, callID, "tool.execute.before");
|
|
2397
|
-
|
|
3258
|
+
state2.toolSpanStarts.set(callID, {
|
|
2398
3259
|
startTimeUnixNano,
|
|
2399
3260
|
parent: spanParent,
|
|
2400
|
-
eventId:
|
|
3261
|
+
eventId: state2.currentEventId,
|
|
2401
3262
|
name: tool,
|
|
2402
3263
|
liveSpan: liveTaskSpan
|
|
2403
3264
|
});
|
|
2404
3265
|
} else {
|
|
2405
|
-
|
|
3266
|
+
state2.toolSpanStarts.set(callID, {
|
|
2406
3267
|
startTimeUnixNano,
|
|
2407
3268
|
parent: spanParent,
|
|
2408
|
-
eventId:
|
|
3269
|
+
eventId: state2.currentEventId,
|
|
2409
3270
|
name: tool
|
|
2410
3271
|
});
|
|
2411
3272
|
}
|
|
@@ -2422,13 +3283,13 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
2422
3283
|
"tool.execute.after": async (toolInput, result) => {
|
|
2423
3284
|
try {
|
|
2424
3285
|
const { tool, sessionID, callID, args } = toolInput;
|
|
2425
|
-
const
|
|
2426
|
-
if (!
|
|
3286
|
+
const state2 = sessions.get(sessionID);
|
|
3287
|
+
if (!state2 || !state2.currentEventId) return;
|
|
2427
3288
|
if (args === void 0 || args === null)
|
|
2428
3289
|
throw new Error("tool.execute.after: args is required");
|
|
2429
3290
|
const toolCallArgs = typeof args === "string" ? capText2(args) : boundedStringify(args);
|
|
2430
|
-
const startInfo =
|
|
2431
|
-
|
|
3291
|
+
const startInfo = state2.toolSpanStarts.get(callID);
|
|
3292
|
+
state2.toolSpanStarts.delete(callID);
|
|
2432
3293
|
const resultMetadata = result.metadata;
|
|
2433
3294
|
const childSessionId = resultMetadata == null ? void 0 : resultMetadata["sessionId"];
|
|
2434
3295
|
if (tool === "task" && childSessionId) {
|
|
@@ -2481,9 +3342,9 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
2481
3342
|
try {
|
|
2482
3343
|
const sessionID = input.sessionID;
|
|
2483
3344
|
if (!sessionID) return;
|
|
2484
|
-
const
|
|
2485
|
-
if (
|
|
2486
|
-
|
|
3345
|
+
const state2 = sessions.get(sessionID);
|
|
3346
|
+
if (state2) {
|
|
3347
|
+
state2.isCompacting = true;
|
|
2487
3348
|
}
|
|
2488
3349
|
} catch (err) {
|
|
2489
3350
|
rateLimitedErrorLog(
|
|
@@ -2500,15 +3361,15 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
2500
3361
|
if (!config.captureSystemPrompt) return;
|
|
2501
3362
|
const sessionID = input.sessionID;
|
|
2502
3363
|
if (!sessionID) return;
|
|
2503
|
-
let
|
|
2504
|
-
if (!
|
|
2505
|
-
|
|
2506
|
-
sessions.set(sessionID,
|
|
3364
|
+
let state2 = sessions.get(sessionID);
|
|
3365
|
+
if (!state2) {
|
|
3366
|
+
state2 = createSessionState(sessionID);
|
|
3367
|
+
sessions.set(sessionID, state2);
|
|
2507
3368
|
}
|
|
2508
3369
|
const MAX_SYSTEM_PROMPT_LENGTH = 32768;
|
|
2509
3370
|
const TRUNCATION_MARKER3 = "\n...[truncated]";
|
|
2510
3371
|
const joined = output.system.join("\n\n");
|
|
2511
|
-
|
|
3372
|
+
state2.currentSystemPrompt = joined.length > MAX_SYSTEM_PROMPT_LENGTH ? joined.slice(0, MAX_SYSTEM_PROMPT_LENGTH - TRUNCATION_MARKER3.length) + TRUNCATION_MARKER3 : joined;
|
|
2512
3373
|
} catch (err) {
|
|
2513
3374
|
rateLimitedErrorLog(
|
|
2514
3375
|
"experimental.chat.system.transform",
|
|
@@ -2520,7 +3381,7 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
2520
3381
|
}
|
|
2521
3382
|
|
|
2522
3383
|
// src/index.ts
|
|
2523
|
-
function createRaindropHandle(eventShipper, traceShipper) {
|
|
3384
|
+
function createRaindropHandle(eventShipper, traceShipper, appGitContext) {
|
|
2524
3385
|
return {
|
|
2525
3386
|
users: {
|
|
2526
3387
|
async identify(users) {
|
|
@@ -2531,12 +3392,19 @@ function createRaindropHandle(eventShipper, traceShipper) {
|
|
|
2531
3392
|
await Promise.all([eventShipper.flush(), traceShipper.flush()]);
|
|
2532
3393
|
},
|
|
2533
3394
|
async shutdown() {
|
|
2534
|
-
|
|
3395
|
+
try {
|
|
3396
|
+
await Promise.all([eventShipper.shutdown(), traceShipper.shutdown()]);
|
|
3397
|
+
} finally {
|
|
3398
|
+
try {
|
|
3399
|
+
appGitContext.dispose();
|
|
3400
|
+
} catch (e) {
|
|
3401
|
+
}
|
|
3402
|
+
}
|
|
2535
3403
|
}
|
|
2536
3404
|
};
|
|
2537
3405
|
}
|
|
2538
|
-
async function plugin(input) {
|
|
2539
|
-
var _a;
|
|
3406
|
+
async function plugin(input, opts = {}) {
|
|
3407
|
+
var _a, _b, _c;
|
|
2540
3408
|
const config = loadConfig(input.directory);
|
|
2541
3409
|
function appLog(level, message) {
|
|
2542
3410
|
console.log(`[raindrop-ai/opencode-plugin] [${level}] ${message}`);
|
|
@@ -2558,21 +3426,28 @@ async function plugin(input) {
|
|
|
2558
3426
|
].filter(Boolean);
|
|
2559
3427
|
appLog("info", `Raindrop tracing enabled \u2014 destinations: ${destinations.join(", ")}`);
|
|
2560
3428
|
}
|
|
2561
|
-
const
|
|
3429
|
+
const configuredAppGit = (_a = opts.appGit) != null ? _a : config.appGit;
|
|
3430
|
+
const appGitContext = createAppGitContext2(
|
|
3431
|
+
((_b = config.writeKey) == null ? void 0 : _b.trim()) || hasLocalDestination ? configuredAppGit : false,
|
|
3432
|
+
{ allowLocalGit: false }
|
|
3433
|
+
);
|
|
3434
|
+
const eventShipper = new EventShipper3({
|
|
2562
3435
|
writeKey: config.writeKey,
|
|
2563
3436
|
endpoint: config.endpoint,
|
|
2564
3437
|
debug: config.debug,
|
|
2565
3438
|
projectId: config.projectId,
|
|
2566
|
-
localDebuggerUrl: config.localWorkshopUrl
|
|
3439
|
+
localDebuggerUrl: config.localWorkshopUrl,
|
|
3440
|
+
appGitContext
|
|
2567
3441
|
});
|
|
2568
|
-
const traceShipper = new
|
|
3442
|
+
const traceShipper = new TraceShipper3({
|
|
2569
3443
|
writeKey: config.writeKey,
|
|
2570
3444
|
endpoint: config.endpoint,
|
|
2571
3445
|
debug: config.debug,
|
|
2572
3446
|
projectId: config.projectId,
|
|
2573
|
-
localDebuggerUrl: config.localWorkshopUrl
|
|
3447
|
+
localDebuggerUrl: config.localWorkshopUrl,
|
|
3448
|
+
appGitContext
|
|
2574
3449
|
});
|
|
2575
|
-
const worktree = (
|
|
3450
|
+
const worktree = (_c = input.worktree) != null ? _c : input.directory;
|
|
2576
3451
|
const hooks = createHooks(
|
|
2577
3452
|
config,
|
|
2578
3453
|
worktree,
|
|
@@ -2580,5 +3455,5 @@ async function plugin(input) {
|
|
|
2580
3455
|
eventShipper,
|
|
2581
3456
|
traceShipper
|
|
2582
3457
|
);
|
|
2583
|
-
return { ...hooks, raindrop: createRaindropHandle(eventShipper, traceShipper) };
|
|
3458
|
+
return { ...hooks, raindrop: createRaindropHandle(eventShipper, traceShipper, appGitContext) };
|
|
2584
3459
|
}
|