@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.js
CHANGED
|
@@ -1,4 +1,518 @@
|
|
|
1
|
-
// ../core/dist/chunk-
|
|
1
|
+
// ../core/dist/chunk-BYBMRLZM.js
|
|
2
|
+
var EVAL_CORRELATION_ID_ATTRIBUTE = "raindrop.eval_correlation_id";
|
|
3
|
+
var PROBE_SCOPE = { correlationId: "" };
|
|
4
|
+
var EvalScopeStorage = class {
|
|
5
|
+
constructor() {
|
|
6
|
+
this._als = null;
|
|
7
|
+
this._probed = false;
|
|
8
|
+
}
|
|
9
|
+
maybeAdoptAsyncLocalStorage() {
|
|
10
|
+
if (this._probed) return;
|
|
11
|
+
this._probed = true;
|
|
12
|
+
try {
|
|
13
|
+
const Ctor = globalThis.RAINDROP_ASYNC_LOCAL_STORAGE;
|
|
14
|
+
if (!Ctor) return;
|
|
15
|
+
const als = new Ctor();
|
|
16
|
+
als.run(PROBE_SCOPE, () => {
|
|
17
|
+
});
|
|
18
|
+
this._als = als;
|
|
19
|
+
} catch (e) {
|
|
20
|
+
this._als = null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
run(scope, callback) {
|
|
24
|
+
this.maybeAdoptAsyncLocalStorage();
|
|
25
|
+
if (this._als) return this._als.run(scope, callback);
|
|
26
|
+
const previous = this._syncScope;
|
|
27
|
+
this._syncScope = scope;
|
|
28
|
+
try {
|
|
29
|
+
return callback();
|
|
30
|
+
} finally {
|
|
31
|
+
this._syncScope = previous;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
current() {
|
|
35
|
+
this.maybeAdoptAsyncLocalStorage();
|
|
36
|
+
if (this._als) return this._als.getStore();
|
|
37
|
+
return this._syncScope;
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
var EVAL_SCOPE_STORAGE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.evalScopeStorage");
|
|
41
|
+
function evalScopeStorage() {
|
|
42
|
+
const holder = globalThis;
|
|
43
|
+
let storage = holder[EVAL_SCOPE_STORAGE_KEY];
|
|
44
|
+
if (!storage) {
|
|
45
|
+
storage = new EvalScopeStorage();
|
|
46
|
+
holder[EVAL_SCOPE_STORAGE_KEY] = storage;
|
|
47
|
+
}
|
|
48
|
+
return storage;
|
|
49
|
+
}
|
|
50
|
+
function currentEvalScope() {
|
|
51
|
+
try {
|
|
52
|
+
return evalScopeStorage().current();
|
|
53
|
+
} catch (e) {
|
|
54
|
+
return void 0;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function evalScopeAttributes() {
|
|
58
|
+
const scope = currentEvalScope();
|
|
59
|
+
if (!scope) return {};
|
|
60
|
+
return { [EVAL_CORRELATION_ID_ATTRIBUTE]: scope.correlationId };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// ../core/dist/chunk-WJOR6M7H.js
|
|
64
|
+
var STATE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.replayTraceRoutingState");
|
|
65
|
+
function state() {
|
|
66
|
+
const holder = globalThis;
|
|
67
|
+
let current = holder[STATE_KEY];
|
|
68
|
+
if (!current) {
|
|
69
|
+
let storage = null;
|
|
70
|
+
try {
|
|
71
|
+
const Ctor = globalThis.RAINDROP_ASYNC_LOCAL_STORAGE;
|
|
72
|
+
if (Ctor) storage = new Ctor();
|
|
73
|
+
} catch (e) {
|
|
74
|
+
storage = null;
|
|
75
|
+
}
|
|
76
|
+
current = {
|
|
77
|
+
storage,
|
|
78
|
+
syncDestination: void 0,
|
|
79
|
+
spanDestinations: /* @__PURE__ */ new WeakMap()
|
|
80
|
+
};
|
|
81
|
+
holder[STATE_KEY] = current;
|
|
82
|
+
}
|
|
83
|
+
return current;
|
|
84
|
+
}
|
|
85
|
+
function currentReplayTraceDestination() {
|
|
86
|
+
var _a, _b;
|
|
87
|
+
const routing = state();
|
|
88
|
+
return (_b = (_a = routing.storage) == null ? void 0 : _a.getStore()) != null ? _b : routing.syncDestination;
|
|
89
|
+
}
|
|
90
|
+
function rememberReplayTraceDestination(span) {
|
|
91
|
+
const destination = currentReplayTraceDestination();
|
|
92
|
+
if (destination) state().spanDestinations.set(span, destination);
|
|
93
|
+
}
|
|
94
|
+
function copyReplayTraceDestination(source, target) {
|
|
95
|
+
const destination = state().spanDestinations.get(source);
|
|
96
|
+
if (destination) state().spanDestinations.set(target, destination);
|
|
97
|
+
}
|
|
98
|
+
function replayTraceDestinationFor(value) {
|
|
99
|
+
if (typeof value !== "object" && typeof value !== "function" || value === null) {
|
|
100
|
+
return void 0;
|
|
101
|
+
}
|
|
102
|
+
return state().spanDestinations.get(value);
|
|
103
|
+
}
|
|
104
|
+
function recordReplayExportedSpan(destination, spanId, traceId) {
|
|
105
|
+
var _a, _b;
|
|
106
|
+
if (!destination || !spanId || !traceId) return;
|
|
107
|
+
(_a = destination.exportedSpanIds) == null ? void 0 : _a.add(spanId);
|
|
108
|
+
(_b = destination.exportedTraceIds) == null ? void 0 : _b.add(traceId);
|
|
109
|
+
}
|
|
110
|
+
function replayTraceUrl(baseUrl) {
|
|
111
|
+
return `${baseUrl.replace(/\/+$/, "")}/v1/traces`;
|
|
112
|
+
}
|
|
113
|
+
function getAsyncLocalStorageCtor() {
|
|
114
|
+
return globalThis.RAINDROP_ASYNC_LOCAL_STORAGE;
|
|
115
|
+
}
|
|
116
|
+
var MAX_BINDING_STACK = 128;
|
|
117
|
+
var EMPTY_STACK = [];
|
|
118
|
+
var ContextStackStorage = class {
|
|
119
|
+
/** Emitted once when this runtime cannot support an ambient push. */
|
|
120
|
+
constructor(noAmbientBindWarning) {
|
|
121
|
+
this.noAmbientBindWarning = noAmbientBindWarning;
|
|
122
|
+
this._als = null;
|
|
123
|
+
this._enterWithUsable = false;
|
|
124
|
+
this._syncStack = EMPTY_STACK;
|
|
125
|
+
this._adoptionChecked = false;
|
|
126
|
+
this._warnedNoAmbientBind = false;
|
|
127
|
+
}
|
|
128
|
+
maybeAdoptAsyncLocalStorage() {
|
|
129
|
+
if (this._adoptionChecked) return;
|
|
130
|
+
this._adoptionChecked = true;
|
|
131
|
+
const Ctor = getAsyncLocalStorageCtor();
|
|
132
|
+
if (!Ctor) return;
|
|
133
|
+
const als = new Ctor();
|
|
134
|
+
try {
|
|
135
|
+
als.run(EMPTY_STACK, () => {
|
|
136
|
+
});
|
|
137
|
+
} catch (e) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
this._als = als;
|
|
141
|
+
if (typeof als.enterWith === "function") {
|
|
142
|
+
try {
|
|
143
|
+
als.enterWith(EMPTY_STACK);
|
|
144
|
+
this._enterWithUsable = true;
|
|
145
|
+
} catch (e) {
|
|
146
|
+
this._enterWithUsable = false;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
getStack() {
|
|
151
|
+
var _a;
|
|
152
|
+
this.maybeAdoptAsyncLocalStorage();
|
|
153
|
+
if (this._als) return (_a = this._als.getStore()) != null ? _a : this._syncStack;
|
|
154
|
+
return this._syncStack;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Persist an ambient stack mutation. Returns false when an ALS is adopted but
|
|
158
|
+
* `enterWith` is unusable (workerd): callers must NOT fall back to the
|
|
159
|
+
* process-shared sync stack, since concurrent isolates would cross-stamp.
|
|
160
|
+
*/
|
|
161
|
+
setAmbientStack(stack) {
|
|
162
|
+
if (this._als) {
|
|
163
|
+
if (!this._enterWithUsable) return false;
|
|
164
|
+
this._als.enterWith(stack);
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
167
|
+
this._syncStack = stack;
|
|
168
|
+
return true;
|
|
169
|
+
}
|
|
170
|
+
push(binding) {
|
|
171
|
+
this.maybeAdoptAsyncLocalStorage();
|
|
172
|
+
if (this._als && !this._enterWithUsable) {
|
|
173
|
+
this.warnNoAmbientBindOnce();
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
let stack = this.getStack();
|
|
177
|
+
if (stack.length >= MAX_BINDING_STACK) {
|
|
178
|
+
stack = stack.filter((b) => b.isLive());
|
|
179
|
+
if (stack.length >= MAX_BINDING_STACK) {
|
|
180
|
+
stack = stack.slice(stack.length - (MAX_BINDING_STACK - 1));
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
this.setAmbientStack([...stack, binding]);
|
|
184
|
+
}
|
|
185
|
+
remove(binding) {
|
|
186
|
+
binding.markDead();
|
|
187
|
+
const stack = this.getStack();
|
|
188
|
+
const pruned = stack.filter((b) => b !== binding && b.isLive());
|
|
189
|
+
if (pruned.length !== stack.length) {
|
|
190
|
+
this.setAmbientStack(pruned);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
runWith(binding, callback) {
|
|
194
|
+
this.maybeAdoptAsyncLocalStorage();
|
|
195
|
+
if (this._als) {
|
|
196
|
+
return this._als.run([...this.getStack(), binding], callback);
|
|
197
|
+
}
|
|
198
|
+
const previous = this._syncStack;
|
|
199
|
+
this._syncStack = [...previous, binding];
|
|
200
|
+
try {
|
|
201
|
+
return callback();
|
|
202
|
+
} finally {
|
|
203
|
+
this._syncStack = previous;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
current() {
|
|
207
|
+
const stack = this.getStack();
|
|
208
|
+
if (stack.length === 0) return void 0;
|
|
209
|
+
const top = stack[stack.length - 1];
|
|
210
|
+
if (top.isLive()) return top;
|
|
211
|
+
const pruned = stack.filter((b) => b.isLive());
|
|
212
|
+
this.setAmbientStack(pruned);
|
|
213
|
+
return pruned.length > 0 ? pruned[pruned.length - 1] : void 0;
|
|
214
|
+
}
|
|
215
|
+
warnNoAmbientBindOnce() {
|
|
216
|
+
if (this._warnedNoAmbientBind) return;
|
|
217
|
+
this._warnedNoAmbientBind = true;
|
|
218
|
+
console.warn(this.noAmbientBindWarning);
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
var NO_AMBIENT_ROUTING_BIND_WARNING = "[raindrop] This runtime's AsyncLocalStorage does not implement enterWith (e.g. Cloudflare Workers), so begin()/finish() cannot scope auto-instrumented spans to a project without cross-contaminating concurrent requests. Manual events and explicit span routing are unaffected; use asCurrent()/withSpan (run-based) to route auto-instrumented spans on this runtime.";
|
|
222
|
+
var ROUTING_STORAGE_KEY = /* @__PURE__ */ Symbol.for("raindrop.tracing.routingContextStorage");
|
|
223
|
+
function routingStorage() {
|
|
224
|
+
const holder = globalThis;
|
|
225
|
+
let storage = holder[ROUTING_STORAGE_KEY];
|
|
226
|
+
if (!storage) {
|
|
227
|
+
storage = new ContextStackStorage(NO_AMBIENT_ROUTING_BIND_WARNING);
|
|
228
|
+
holder[ROUTING_STORAGE_KEY] = storage;
|
|
229
|
+
}
|
|
230
|
+
return storage;
|
|
231
|
+
}
|
|
232
|
+
function currentRoutingBinding() {
|
|
233
|
+
const bound = routingStorage().current();
|
|
234
|
+
if (!bound) return void 0;
|
|
235
|
+
return {
|
|
236
|
+
projectId: bound.projectId,
|
|
237
|
+
authHint: bound.authHint,
|
|
238
|
+
...bound.appGit ? { appGit: bound.appGit } : {},
|
|
239
|
+
...bound.appGitSource ? { appGitSource: bound.appGitSource } : {}
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
var APP_COMMIT_SHA = "raindrop.app.commit_sha";
|
|
243
|
+
var APP_COMMIT_DIRTY = "raindrop.app.commit_dirty";
|
|
244
|
+
var APP_BRANCH = "raindrop.app.branch";
|
|
245
|
+
var APP_GIT_KEYS = [APP_COMMIT_SHA, APP_COMMIT_DIRTY, APP_BRANCH];
|
|
246
|
+
var own = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
247
|
+
function appGitExplicitKeys(properties) {
|
|
248
|
+
const keys = /* @__PURE__ */ new Set();
|
|
249
|
+
if (!properties) return keys;
|
|
250
|
+
for (const key of APP_GIT_KEYS) {
|
|
251
|
+
if (own(properties, key)) keys.add(key);
|
|
252
|
+
}
|
|
253
|
+
return keys;
|
|
254
|
+
}
|
|
255
|
+
function mergeAppGitSnapshot(base, properties, explicitKeys = /* @__PURE__ */ new Set()) {
|
|
256
|
+
try {
|
|
257
|
+
const result = { ...base };
|
|
258
|
+
if (properties && own(properties, APP_COMMIT_SHA) && properties[APP_COMMIT_SHA] !== result[APP_COMMIT_SHA]) {
|
|
259
|
+
if (!explicitKeys.has(APP_COMMIT_DIRTY) && !own(properties, APP_COMMIT_DIRTY)) {
|
|
260
|
+
delete result[APP_COMMIT_DIRTY];
|
|
261
|
+
}
|
|
262
|
+
if (!explicitKeys.has(APP_BRANCH) && !own(properties, APP_BRANCH)) {
|
|
263
|
+
delete result[APP_BRANCH];
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
for (const key of APP_GIT_KEYS) {
|
|
267
|
+
if (properties && own(properties, key)) result[key] = properties[key];
|
|
268
|
+
}
|
|
269
|
+
return Object.freeze(result);
|
|
270
|
+
} catch (e) {
|
|
271
|
+
return Object.freeze({});
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
function validAppCommitSha(value) {
|
|
275
|
+
if (typeof value !== "string" || value.length > 128) return void 0;
|
|
276
|
+
const cleaned = value.trim();
|
|
277
|
+
return /^(?:[a-fA-F0-9]{40}|[a-fA-F0-9]{64})$/.test(cleaned) ? cleaned.toLowerCase() : void 0;
|
|
278
|
+
}
|
|
279
|
+
function shortString(value) {
|
|
280
|
+
if (typeof value !== "string" || value.length > 1024) return void 0;
|
|
281
|
+
const cleaned = value.trim();
|
|
282
|
+
return cleaned.length > 0 ? cleaned : void 0;
|
|
283
|
+
}
|
|
284
|
+
function flag(value) {
|
|
285
|
+
if (value === true || value === "true" || value === "1") return true;
|
|
286
|
+
if (value === false || value === "false" || value === "0") return false;
|
|
287
|
+
return void 0;
|
|
288
|
+
}
|
|
289
|
+
function environment() {
|
|
290
|
+
try {
|
|
291
|
+
return typeof process === "undefined" ? {} : process.env;
|
|
292
|
+
} catch (e) {
|
|
293
|
+
return {};
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
var DEPLOYMENTS = [
|
|
297
|
+
["VERCEL", "VERCEL_GIT_COMMIT_SHA", "VERCEL_GIT_COMMIT_REF"],
|
|
298
|
+
["NETLIFY", "COMMIT_REF", "BRANCH"],
|
|
299
|
+
["RAILWAY_ENVIRONMENT_NAME", "RAILWAY_GIT_COMMIT_SHA", "RAILWAY_GIT_BRANCH"],
|
|
300
|
+
["RAILWAY_ENVIRONMENT", "RAILWAY_GIT_COMMIT_SHA", "RAILWAY_GIT_BRANCH"],
|
|
301
|
+
["RENDER", "RENDER_GIT_COMMIT", "RENDER_GIT_BRANCH"],
|
|
302
|
+
["DYNO", "HEROKU_BUILD_COMMIT", ""],
|
|
303
|
+
["DYNO", "HEROKU_SLUG_COMMIT", ""],
|
|
304
|
+
["AWS_APP_ID", "AWS_COMMIT_ID", "AWS_BRANCH"],
|
|
305
|
+
["WORKERS_CI", "WORKERS_CI_COMMIT_SHA", "WORKERS_CI_BRANCH"]
|
|
306
|
+
];
|
|
307
|
+
var CI_SOURCES = [
|
|
308
|
+
["GITHUB_ACTIONS", "GITHUB_SHA", "GITHUB_REF_NAME"],
|
|
309
|
+
["GITLAB_CI", "CI_COMMIT_SHA", "CI_COMMIT_REF_NAME"],
|
|
310
|
+
["CIRCLECI", "CIRCLE_SHA1", "CIRCLE_BRANCH"]
|
|
311
|
+
];
|
|
312
|
+
function detectedSource(env, table, detectBranch) {
|
|
313
|
+
for (const row of table) {
|
|
314
|
+
const [marker, shaKey, branchKey] = row;
|
|
315
|
+
if (!marker || !shaKey || !shortString(env[marker]) || flag(env[marker]) === false) continue;
|
|
316
|
+
const commitSha = validAppCommitSha(env[shaKey]);
|
|
317
|
+
if (commitSha)
|
|
318
|
+
return {
|
|
319
|
+
commitSha,
|
|
320
|
+
...detectBranch && branchKey ? { branch: shortString(env[branchKey]) } : {}
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
return {};
|
|
324
|
+
}
|
|
325
|
+
var AppGitContextImpl = class {
|
|
326
|
+
constructor(options, runtime = {}) {
|
|
327
|
+
this.defaults = {};
|
|
328
|
+
this.explicit = {};
|
|
329
|
+
this.explicitKeys = /* @__PURE__ */ new Set();
|
|
330
|
+
this.disposed = false;
|
|
331
|
+
this.operations = /* @__PURE__ */ new Map();
|
|
332
|
+
this.operationOverflow = false;
|
|
333
|
+
this.detectBranch = false;
|
|
334
|
+
this.disabled = false;
|
|
335
|
+
var _a, _b, _c, _d, _e, _f;
|
|
336
|
+
try {
|
|
337
|
+
if (options === false) {
|
|
338
|
+
this.disabled = true;
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
const opts = options != null ? options : {};
|
|
342
|
+
const env = (_a = runtime.env) != null ? _a : environment();
|
|
343
|
+
const detectBranch = (_c = (_b = flag(opts.detectBranch)) != null ? _b : flag(env.RAINDROP_GIT_DETECT_BRANCH)) != null ? _c : false;
|
|
344
|
+
this.detectBranch = detectBranch;
|
|
345
|
+
const collectBranch = detectBranch || runtime.captureLegacyReplayBranch === true;
|
|
346
|
+
const autoDetect = runtime.allowDiscovery === false ? false : (_e = (_d = flag(opts.autoDetect)) != null ? _d : flag(env.RAINDROP_GIT_AUTO_DETECT)) != null ? _e : true;
|
|
347
|
+
const configuredSha = opts.commitSha;
|
|
348
|
+
const explicitSha = configuredSha === void 0 ? env.RAINDROP_COMMIT_SHA : configuredSha;
|
|
349
|
+
if (explicitSha === null) this.explicit[APP_COMMIT_SHA] = null;
|
|
350
|
+
else if (typeof explicitSha === "string" && validAppCommitSha(explicitSha))
|
|
351
|
+
this.explicit[APP_COMMIT_SHA] = explicitSha;
|
|
352
|
+
const configuredDirty = opts.commitDirty;
|
|
353
|
+
const explicitDirty = configuredDirty === void 0 ? flag(env.RAINDROP_COMMIT_DIRTY) : configuredDirty;
|
|
354
|
+
if (explicitDirty === null || typeof explicitDirty === "boolean")
|
|
355
|
+
this.explicit[APP_COMMIT_DIRTY] = explicitDirty;
|
|
356
|
+
const configuredBranch = opts.branch;
|
|
357
|
+
const explicitBranch = configuredBranch === void 0 ? env.RAINDROP_BRANCH : configuredBranch;
|
|
358
|
+
if (explicitBranch === null) this.explicit[APP_BRANCH] = null;
|
|
359
|
+
else if (typeof explicitBranch === "string" && explicitBranch.length <= 1024)
|
|
360
|
+
this.explicit[APP_BRANCH] = explicitBranch;
|
|
361
|
+
this.explicitKeys = appGitExplicitKeys(this.explicit);
|
|
362
|
+
this.defaults = { ...this.explicit };
|
|
363
|
+
if (!autoDetect || explicitSha !== void 0) return;
|
|
364
|
+
const sourceDirectory = (_f = shortString(opts.sourceDirectory)) != null ? _f : shortString(env.RAINDROP_GIT_SOURCE_DIRECTORY);
|
|
365
|
+
if (runtime.allowLocalGit === false && !sourceDirectory) return;
|
|
366
|
+
const deploy = sourceDirectory ? {} : detectedSource(env, DEPLOYMENTS, collectBranch);
|
|
367
|
+
if (deploy.commitSha) {
|
|
368
|
+
this.accept(deploy);
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
const fallback = sourceDirectory ? {} : detectedSource(env, CI_SOURCES, collectBranch);
|
|
372
|
+
if (runtime.resolveLocal && (runtime.allowLocalGit !== false || sourceDirectory)) {
|
|
373
|
+
this.cancel = runtime.resolveLocal(sourceDirectory, collectBranch, (result) => {
|
|
374
|
+
try {
|
|
375
|
+
if (!this.disposed) this.accept(result.commitSha ? result : fallback);
|
|
376
|
+
} catch (e) {
|
|
377
|
+
}
|
|
378
|
+
});
|
|
379
|
+
} else this.accept(fallback);
|
|
380
|
+
} catch (e) {
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
accept(result) {
|
|
384
|
+
const sha = validAppCommitSha(result.commitSha);
|
|
385
|
+
if (!sha) return;
|
|
386
|
+
this.replayBranch = shortString(result.branch);
|
|
387
|
+
this.defaults = {
|
|
388
|
+
[APP_COMMIT_SHA]: sha,
|
|
389
|
+
...typeof result.commitDirty === "boolean" ? { [APP_COMMIT_DIRTY]: result.commitDirty } : {},
|
|
390
|
+
...this.detectBranch && this.replayBranch ? { [APP_BRANCH]: this.replayBranch } : {},
|
|
391
|
+
...this.explicit
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
snapshot(properties) {
|
|
395
|
+
var _a;
|
|
396
|
+
try {
|
|
397
|
+
const binding = currentRoutingBinding();
|
|
398
|
+
const base = this.disabled && (binding == null ? void 0 : binding.appGitSource) !== "replay-override" ? {} : (_a = binding == null ? void 0 : binding.appGit) != null ? _a : this.defaults;
|
|
399
|
+
return this.mergeSnapshot(base, properties);
|
|
400
|
+
} catch (e) {
|
|
401
|
+
return Object.freeze({});
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
/** Safe defaults when no operation/span start was observed; never infer identity. */
|
|
405
|
+
snapshotExplicit(properties, eventId) {
|
|
406
|
+
try {
|
|
407
|
+
const base = { ...this.explicit };
|
|
408
|
+
const operation = eventId ? this.operations.get(eventId) : void 0;
|
|
409
|
+
if (operation) {
|
|
410
|
+
for (const key of operation.explicitKeys) base[key] = operation.snapshot[key];
|
|
411
|
+
}
|
|
412
|
+
return this.mergeSnapshot(base, properties, new Set(Object.keys(base)));
|
|
413
|
+
} catch (e) {
|
|
414
|
+
return mergeAppGitSnapshot({}, properties);
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
/** Existing replay branch reporting stays separate from opt-in event properties. */
|
|
418
|
+
snapshotForReplay() {
|
|
419
|
+
const snapshot = this.snapshot();
|
|
420
|
+
if (this.replayBranch && !own(snapshot, APP_BRANCH) && snapshot[APP_COMMIT_SHA] === this.defaults[APP_COMMIT_SHA]) {
|
|
421
|
+
return Object.freeze({ ...snapshot, [APP_BRANCH]: this.replayBranch });
|
|
422
|
+
}
|
|
423
|
+
return snapshot;
|
|
424
|
+
}
|
|
425
|
+
/** Merge a frozen span snapshot without losing client-authored provenance. */
|
|
426
|
+
mergeSnapshot(base, properties, explicitKeys = this.explicitKeys) {
|
|
427
|
+
return mergeAppGitSnapshot(base, properties, /* @__PURE__ */ new Set([...this.explicitKeys, ...explicitKeys]));
|
|
428
|
+
}
|
|
429
|
+
/** Shippers belonging to one client share this bounded operation registry. */
|
|
430
|
+
forOperation(eventId, properties, owner) {
|
|
431
|
+
if (!eventId) return this.snapshot(properties);
|
|
432
|
+
let operation = this.operations.get(eventId);
|
|
433
|
+
if (!operation) {
|
|
434
|
+
if (this.operations.size >= 1e4) this.operationOverflow = true;
|
|
435
|
+
if (this.operationOverflow) return this.mergeSnapshot({}, properties);
|
|
436
|
+
operation = {
|
|
437
|
+
snapshot: this.snapshot(properties),
|
|
438
|
+
owners: /* @__PURE__ */ new Set(),
|
|
439
|
+
unowned: owner === void 0,
|
|
440
|
+
explicitKeys: appGitExplicitKeys(properties)
|
|
441
|
+
};
|
|
442
|
+
this.operations.set(eventId, operation);
|
|
443
|
+
} else if (properties && APP_GIT_KEYS.some((key) => own(properties, key))) {
|
|
444
|
+
const explicitKeys = /* @__PURE__ */ new Set([...this.explicitKeys, ...operation.explicitKeys]);
|
|
445
|
+
operation.snapshot = this.mergeSnapshot(operation.snapshot, properties, explicitKeys);
|
|
446
|
+
for (const key of appGitExplicitKeys(properties)) operation.explicitKeys.add(key);
|
|
447
|
+
}
|
|
448
|
+
if (!owner) operation.unowned = true;
|
|
449
|
+
if (owner) operation.owners.add(owner);
|
|
450
|
+
return operation.snapshot;
|
|
451
|
+
}
|
|
452
|
+
releaseOperation(eventId, owner) {
|
|
453
|
+
const operation = this.operations.get(eventId);
|
|
454
|
+
if (!operation) return;
|
|
455
|
+
operation.owners.delete(owner);
|
|
456
|
+
if (operation.owners.size === 0 && !operation.unowned) this.operations.delete(eventId);
|
|
457
|
+
}
|
|
458
|
+
finishOperation(eventId) {
|
|
459
|
+
this.operations.delete(eventId);
|
|
460
|
+
}
|
|
461
|
+
dispose() {
|
|
462
|
+
var _a;
|
|
463
|
+
this.disposed = true;
|
|
464
|
+
try {
|
|
465
|
+
(_a = this.cancel) == null ? void 0 : _a.call(this);
|
|
466
|
+
} catch (e) {
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
};
|
|
470
|
+
var AppGitContext = AppGitContextImpl;
|
|
471
|
+
function createAppGitContext(options, runtime = {}) {
|
|
472
|
+
return new AppGitContext(options, runtime);
|
|
473
|
+
}
|
|
474
|
+
function withAppGitProperties(properties, snapshot) {
|
|
475
|
+
try {
|
|
476
|
+
const merged = { ...properties };
|
|
477
|
+
for (const key of APP_GIT_KEYS)
|
|
478
|
+
if (!own(merged, key) && own(snapshot, key)) merged[key] = snapshot[key];
|
|
479
|
+
return merged;
|
|
480
|
+
} catch (e) {
|
|
481
|
+
return properties != null ? properties : {};
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
function withAppGitAttributes(attributes, snapshot) {
|
|
485
|
+
try {
|
|
486
|
+
const present = new Set(attributes.flatMap((attr) => attr ? [attr.key] : []));
|
|
487
|
+
const added = [];
|
|
488
|
+
for (const key of APP_GIT_KEYS) {
|
|
489
|
+
if (present.has(key) || present.has(`ai.telemetry.metadata.${key}`) || present.has(`traceloop.association.properties.${key}`))
|
|
490
|
+
continue;
|
|
491
|
+
const value = snapshot[key];
|
|
492
|
+
if (typeof value === "string") added.push({ key, value: { stringValue: value } });
|
|
493
|
+
else if (typeof value === "boolean") added.push({ key, value: { boolValue: value } });
|
|
494
|
+
}
|
|
495
|
+
return added.length ? [...attributes, ...added] : attributes;
|
|
496
|
+
} catch (e) {
|
|
497
|
+
return attributes;
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
function appGitPropertiesFromAttributes(attributes) {
|
|
501
|
+
var _a, _b, _c;
|
|
502
|
+
const properties = {};
|
|
503
|
+
try {
|
|
504
|
+
for (const attr of attributes) {
|
|
505
|
+
if (!attr) continue;
|
|
506
|
+
for (const key of APP_GIT_KEYS) {
|
|
507
|
+
if (attr.key === key || attr.key === `ai.telemetry.metadata.${key}` || attr.key === `traceloop.association.properties.${key}`) {
|
|
508
|
+
properties[key] = (_c = (_b = (_a = attr.value.stringValue) != null ? _a : attr.value.boolValue) != null ? _b : attr.value.intValue) != null ? _c : null;
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
} catch (e) {
|
|
513
|
+
}
|
|
514
|
+
return properties;
|
|
515
|
+
}
|
|
2
516
|
function getCrypto() {
|
|
3
517
|
const c = globalThis.crypto;
|
|
4
518
|
return c;
|
|
@@ -53,6 +567,25 @@ function base64Encode(bytes) {
|
|
|
53
567
|
}
|
|
54
568
|
return out;
|
|
55
569
|
}
|
|
570
|
+
function base64ToHex(value) {
|
|
571
|
+
if (!value) return "";
|
|
572
|
+
const maybeBuffer = globalThis.Buffer;
|
|
573
|
+
if (maybeBuffer) {
|
|
574
|
+
return maybeBuffer.from(value, "base64").toString("hex");
|
|
575
|
+
}
|
|
576
|
+
const atobFn = globalThis.atob;
|
|
577
|
+
if (typeof atobFn !== "function") return "";
|
|
578
|
+
try {
|
|
579
|
+
const binary = atobFn(value);
|
|
580
|
+
let hex = "";
|
|
581
|
+
for (let i = 0; i < binary.length; i++) {
|
|
582
|
+
hex += (binary.charCodeAt(i) & 255).toString(16).padStart(2, "0");
|
|
583
|
+
}
|
|
584
|
+
return hex;
|
|
585
|
+
} catch (e) {
|
|
586
|
+
return "";
|
|
587
|
+
}
|
|
588
|
+
}
|
|
56
589
|
function generateId() {
|
|
57
590
|
return randomUUID();
|
|
58
591
|
}
|
|
@@ -87,7 +620,7 @@ function runWithTracingSuppressed(fn) {
|
|
|
87
620
|
var DEFAULT_REQUEST_TIMEOUT_MS = 3e4;
|
|
88
621
|
var MAX_RETRY_DELAY_MS = 3e4;
|
|
89
622
|
function wait(ms) {
|
|
90
|
-
return new Promise((
|
|
623
|
+
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
91
624
|
}
|
|
92
625
|
function formatEndpoint(endpoint) {
|
|
93
626
|
if (!endpoint) return void 0;
|
|
@@ -124,9 +657,9 @@ async function raceWithTimeout(promise, timeoutMs) {
|
|
|
124
657
|
() => true,
|
|
125
658
|
() => true
|
|
126
659
|
),
|
|
127
|
-
new Promise((
|
|
660
|
+
new Promise((resolve2) => {
|
|
128
661
|
var _a;
|
|
129
|
-
timer = setTimeout(() =>
|
|
662
|
+
timer = setTimeout(() => resolve2(false), Math.max(0, timeoutMs));
|
|
130
663
|
(_a = timer.unref) == null ? void 0 : _a.call(timer);
|
|
131
664
|
})
|
|
132
665
|
]);
|
|
@@ -197,6 +730,7 @@ async function postJson(url, body, headers, opts) {
|
|
|
197
730
|
const resp = await runWithTracingSuppressed(
|
|
198
731
|
() => fetch(url, {
|
|
199
732
|
method: "POST",
|
|
733
|
+
redirect: headers["X-Raindrop-Replay-Id"] !== void 0 ? "error" : "follow",
|
|
200
734
|
headers: {
|
|
201
735
|
"Content-Type": "application/json",
|
|
202
736
|
...headers
|
|
@@ -365,26 +899,29 @@ function resolveLocalDebuggerBaseUrl(baseUrl) {
|
|
|
365
899
|
if (shouldAutoEnableLocalWorkshop()) return DEFAULT_LOCAL_WORKSHOP_URL;
|
|
366
900
|
return null;
|
|
367
901
|
}
|
|
902
|
+
var LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS = 2e3;
|
|
368
903
|
function mirrorTraceExportToLocalDebugger(body, options = {}) {
|
|
369
904
|
var _a;
|
|
370
905
|
const baseUrl = resolveLocalDebuggerBaseUrl(options.baseUrl);
|
|
371
|
-
if (!baseUrl) return;
|
|
372
|
-
|
|
906
|
+
if (!baseUrl) return Promise.resolve();
|
|
907
|
+
return postJson(`${baseUrl}traces`, body, {}, {
|
|
373
908
|
maxAttempts: 1,
|
|
374
909
|
debug: (_a = options.debug) != null ? _a : false,
|
|
375
|
-
sdkName: options.sdkName
|
|
910
|
+
sdkName: options.sdkName,
|
|
911
|
+
timeoutMs: LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS
|
|
376
912
|
}).catch(() => {
|
|
377
913
|
});
|
|
378
914
|
}
|
|
379
915
|
function mirrorPartialEventToLocalDebugger(event, options = {}) {
|
|
380
916
|
var _a;
|
|
381
917
|
const baseUrl = resolveLocalDebuggerBaseUrl(options.baseUrl);
|
|
382
|
-
if (!baseUrl) return;
|
|
918
|
+
if (!baseUrl) return Promise.resolve();
|
|
383
919
|
const headers = options.writeKey ? { Authorization: `Bearer ${options.writeKey}` } : {};
|
|
384
|
-
|
|
920
|
+
return postJson(`${baseUrl}events/track_partial`, event, headers, {
|
|
385
921
|
maxAttempts: 1,
|
|
386
922
|
debug: (_a = options.debug) != null ? _a : false,
|
|
387
|
-
sdkName: options.sdkName
|
|
923
|
+
sdkName: options.sdkName,
|
|
924
|
+
timeoutMs: LOCAL_DEBUGGER_MIRROR_TIMEOUT_MS
|
|
388
925
|
}).catch(() => {
|
|
389
926
|
});
|
|
390
927
|
}
|
|
@@ -409,6 +946,13 @@ function projectIdHeaders(projectId) {
|
|
|
409
946
|
}
|
|
410
947
|
var SHUTDOWN_DEADLINE_MS = 1e4;
|
|
411
948
|
var POST_SHUTDOWN_TIMEOUT_MS = 5e3;
|
|
949
|
+
function appGitOwnerId(prefix) {
|
|
950
|
+
try {
|
|
951
|
+
return `${prefix}:${randomUUID()}`;
|
|
952
|
+
} catch (e) {
|
|
953
|
+
return `${prefix}:${Date.now().toString(36)}:${Math.random().toString(36).slice(2)}`;
|
|
954
|
+
}
|
|
955
|
+
}
|
|
412
956
|
function mergePatches(target, source) {
|
|
413
957
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
414
958
|
const out = { ...target, ...source };
|
|
@@ -458,22 +1002,25 @@ function eventTelemetryProperties(patch) {
|
|
|
458
1002
|
}
|
|
459
1003
|
var EventShipper = class {
|
|
460
1004
|
constructor(opts) {
|
|
1005
|
+
this.appGitOwner = appGitOwnerId("event");
|
|
461
1006
|
this.buffers = /* @__PURE__ */ new Map();
|
|
462
1007
|
this.sticky = /* @__PURE__ */ new Map();
|
|
463
1008
|
this.timers = /* @__PURE__ */ new Map();
|
|
464
1009
|
this.inFlight = /* @__PURE__ */ new Set();
|
|
465
1010
|
this.hasShutdown = false;
|
|
466
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
467
|
-
this.
|
|
468
|
-
this.
|
|
1011
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
1012
|
+
this.appGitContext = (_a = opts.appGitContext) != null ? _a : createAppGitContext(opts.appGit);
|
|
1013
|
+
this.ownsAppGitContext = opts.appGitContext === void 0;
|
|
1014
|
+
this.writeKey = (_b = opts.writeKey) == null ? void 0 : _b.trim();
|
|
1015
|
+
this.baseUrl = (_c = formatEndpoint(opts.endpoint)) != null ? _c : "https://api.raindrop.ai/v1/";
|
|
469
1016
|
this.enabled = opts.enabled !== false;
|
|
470
1017
|
this.debug = opts.debug;
|
|
471
|
-
this.partialFlushMs = (
|
|
472
|
-
this.sdkName = (
|
|
1018
|
+
this.partialFlushMs = (_d = opts.partialFlushMs) != null ? _d : 1e3;
|
|
1019
|
+
this.sdkName = (_e = opts.sdkName) != null ? _e : "core";
|
|
473
1020
|
this.prefix = `[raindrop-ai/${this.sdkName}]`;
|
|
474
|
-
this.defaultEventName = (
|
|
1021
|
+
this.defaultEventName = (_f = opts.defaultEventName) != null ? _f : "ai_generation";
|
|
475
1022
|
this.maxTextFieldCharsOpt = opts.maxTextFieldChars;
|
|
476
|
-
this.localDebuggerUrl = (
|
|
1023
|
+
this.localDebuggerUrl = (_g = resolveLocalDebuggerBaseUrl(opts.localDebuggerUrl)) != null ? _g : void 0;
|
|
477
1024
|
if (this.debug && this.localDebuggerUrl) {
|
|
478
1025
|
console.log(`${this.prefix} Local debugger mirroring: ${this.localDebuggerUrl}`);
|
|
479
1026
|
}
|
|
@@ -484,8 +1031,8 @@ var EventShipper = class {
|
|
|
484
1031
|
const isNode = typeof process !== "undefined" && typeof process.version === "string";
|
|
485
1032
|
this.context = {
|
|
486
1033
|
library: {
|
|
487
|
-
name: (
|
|
488
|
-
version: (
|
|
1034
|
+
name: (_h = opts.libraryName) != null ? _h : "@raindrop-ai/core",
|
|
1035
|
+
version: (_i = opts.libraryVersion) != null ? _i : "0.0.0"
|
|
489
1036
|
},
|
|
490
1037
|
metadata: {
|
|
491
1038
|
jsRuntime: isNode ? "node" : "web",
|
|
@@ -493,6 +1040,9 @@ var EventShipper = class {
|
|
|
493
1040
|
}
|
|
494
1041
|
};
|
|
495
1042
|
}
|
|
1043
|
+
ownAppGitContextForShutdown() {
|
|
1044
|
+
this.ownsAppGitContext = true;
|
|
1045
|
+
}
|
|
496
1046
|
isDebugEnabled() {
|
|
497
1047
|
return this.debug;
|
|
498
1048
|
}
|
|
@@ -541,6 +1091,15 @@ var EventShipper = class {
|
|
|
541
1091
|
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
542
1092
|
if (!this.enabled) return;
|
|
543
1093
|
if (!eventId || !eventId.trim()) return;
|
|
1094
|
+
const capturedSticky = this.sticky.get(eventId);
|
|
1095
|
+
const eventAlreadyKnown = capturedSticky !== void 0 || this.buffers.has(eventId);
|
|
1096
|
+
const destination = currentReplayTraceDestination();
|
|
1097
|
+
const cloudReplay = destination !== void 0 && destination.kind !== "workshop";
|
|
1098
|
+
if ((capturedSticky == null ? void 0 : capturedSticky.replayOnly) === true || !eventAlreadyKnown && cloudReplay) {
|
|
1099
|
+
if (patch.isPending === false) this.sticky.delete(eventId);
|
|
1100
|
+
else this.sticky.set(eventId, { ...capturedSticky, replayOnly: true });
|
|
1101
|
+
return;
|
|
1102
|
+
}
|
|
544
1103
|
const maxChars = resolveMaxTextFieldChars(this.maxTextFieldCharsOpt);
|
|
545
1104
|
if (typeof patch.input === "string" && patch.input.length > maxChars) {
|
|
546
1105
|
patch = { ...patch, input: capText(patch.input, maxChars) };
|
|
@@ -562,6 +1121,13 @@ var EventShipper = class {
|
|
|
562
1121
|
}
|
|
563
1122
|
const sticky = (_c = this.sticky.get(eventId)) != null ? _c : {};
|
|
564
1123
|
const existing = (_d = this.buffers.get(eventId)) != null ? _d : {};
|
|
1124
|
+
patch = {
|
|
1125
|
+
...patch,
|
|
1126
|
+
properties: withAppGitProperties(
|
|
1127
|
+
patch.properties,
|
|
1128
|
+
this.appGitContext.forOperation(eventId, patch.properties, this.appGitOwner)
|
|
1129
|
+
)
|
|
1130
|
+
};
|
|
565
1131
|
const merged = mergePatches(existing, patch);
|
|
566
1132
|
merged.isPending = (_g = (_f = (_e = patch.isPending) != null ? _e : existing.isPending) != null ? _f : sticky.isPending) != null ? _g : true;
|
|
567
1133
|
this.buffers.set(eventId, merged);
|
|
@@ -575,6 +1141,8 @@ var EventShipper = class {
|
|
|
575
1141
|
if (t) clearTimeout(t);
|
|
576
1142
|
if (merged.isPending === false) {
|
|
577
1143
|
await this.flushOne(eventId);
|
|
1144
|
+
if (this.appGitContext.releaseOperation) this.appGitContext.releaseOperation(eventId, this.appGitOwner);
|
|
1145
|
+
else this.appGitContext.finishOperation(eventId);
|
|
578
1146
|
return;
|
|
579
1147
|
}
|
|
580
1148
|
const timeout = setTimeout(() => {
|
|
@@ -599,15 +1167,21 @@ var EventShipper = class {
|
|
|
599
1167
|
try {
|
|
600
1168
|
for (const t of this.timers.values()) clearTimeout(t);
|
|
601
1169
|
this.timers.clear();
|
|
1170
|
+
for (const [eventId, sticky] of this.sticky) {
|
|
1171
|
+
if (sticky.replayOnly) this.sticky.delete(eventId);
|
|
1172
|
+
}
|
|
602
1173
|
const settled = await raceWithTimeout(this.flush(), SHUTDOWN_DEADLINE_MS);
|
|
603
1174
|
if (!settled) this.warnShutdownDrop("in-flight request(s) at shutdown");
|
|
604
1175
|
} finally {
|
|
605
1176
|
this.shutdownDeadlineAt = void 0;
|
|
1177
|
+
if (this.ownsAppGitContext) this.appGitContext.dispose();
|
|
606
1178
|
}
|
|
607
1179
|
}
|
|
608
1180
|
async trackSignal(signal) {
|
|
609
1181
|
var _a, _b;
|
|
610
1182
|
if (!this.enabled) return;
|
|
1183
|
+
const destination = currentReplayTraceDestination();
|
|
1184
|
+
if (destination && destination.kind !== "workshop") return;
|
|
611
1185
|
const body = [
|
|
612
1186
|
{
|
|
613
1187
|
event_id: signal.eventId,
|
|
@@ -642,6 +1216,8 @@ var EventShipper = class {
|
|
|
642
1216
|
}
|
|
643
1217
|
async identify(users) {
|
|
644
1218
|
if (!this.enabled) return;
|
|
1219
|
+
const destination = currentReplayTraceDestination();
|
|
1220
|
+
if (destination && destination.kind !== "workshop") return;
|
|
645
1221
|
const list = Array.isArray(users) ? users : [users];
|
|
646
1222
|
const body = list.filter((user) => {
|
|
647
1223
|
if (!(user == null ? void 0 : user.userId) || !user.userId.trim()) {
|
|
@@ -694,8 +1270,9 @@ var EventShipper = class {
|
|
|
694
1270
|
this.buffers.delete(eventId);
|
|
695
1271
|
if (!accumulated) return;
|
|
696
1272
|
const sticky = (_a = this.sticky.get(eventId)) != null ? _a : {};
|
|
697
|
-
const
|
|
698
|
-
const
|
|
1273
|
+
const isPending = (_c = (_b = accumulated.isPending) != null ? _b : sticky.isPending) != null ? _c : true;
|
|
1274
|
+
const eventName = (_e = (_d = accumulated.eventName) != null ? _d : sticky.eventName) != null ? _e : this.defaultEventName;
|
|
1275
|
+
const userId = (_f = accumulated.userId) != null ? _f : sticky.userId;
|
|
699
1276
|
if (!userId) {
|
|
700
1277
|
if (this.debug) {
|
|
701
1278
|
console.warn(`${this.prefix} skipping track_partial for ${eventId}: missing userId`);
|
|
@@ -703,14 +1280,13 @@ var EventShipper = class {
|
|
|
703
1280
|
this.sticky.delete(eventId);
|
|
704
1281
|
return;
|
|
705
1282
|
}
|
|
706
|
-
const { wizardSession, ...restProperties } = (
|
|
1283
|
+
const { wizardSession, ...restProperties } = (_g = accumulated.properties) != null ? _g : {};
|
|
707
1284
|
let telemetryProperties = {};
|
|
708
1285
|
try {
|
|
709
1286
|
telemetryProperties = eventTelemetryProperties(accumulated);
|
|
710
1287
|
} catch (e) {
|
|
711
1288
|
}
|
|
712
|
-
const convoId = (
|
|
713
|
-
const isPending = (_h = (_g = accumulated.isPending) != null ? _g : sticky.isPending) != null ? _h : true;
|
|
1289
|
+
const convoId = (_h = accumulated.convoId) != null ? _h : sticky.convoId;
|
|
714
1290
|
const payload = {
|
|
715
1291
|
event_id: eventId,
|
|
716
1292
|
user_id: userId,
|
|
@@ -752,29 +1328,30 @@ var EventShipper = class {
|
|
|
752
1328
|
endpoint: url
|
|
753
1329
|
});
|
|
754
1330
|
}
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
});
|
|
762
|
-
}
|
|
1331
|
+
const mirror = this.localDebuggerUrl ? mirrorPartialEventToLocalDebugger(payload, {
|
|
1332
|
+
baseUrl: this.localDebuggerUrl,
|
|
1333
|
+
writeKey: this.writeKey,
|
|
1334
|
+
debug: this.debug,
|
|
1335
|
+
sdkName: this.sdkName
|
|
1336
|
+
}) : void 0;
|
|
763
1337
|
if (!this.writeKey) {
|
|
764
1338
|
if (!isPending) this.sticky.delete(eventId);
|
|
1339
|
+
if (mirror) await mirror;
|
|
765
1340
|
return;
|
|
766
1341
|
}
|
|
767
1342
|
const opts = this.requestOpts();
|
|
768
1343
|
if (!opts) {
|
|
769
1344
|
this.warnShutdownDrop(`track_partial ${eventId}`);
|
|
770
1345
|
if (!isPending) this.sticky.delete(eventId);
|
|
1346
|
+
if (mirror) await mirror;
|
|
771
1347
|
return;
|
|
772
1348
|
}
|
|
773
1349
|
const p = postJson(url, payload, this.requestHeaders(), opts);
|
|
774
|
-
|
|
1350
|
+
const combined = mirror ? Promise.all([mirror, p]).then(() => void 0) : p;
|
|
1351
|
+
this.inFlight.add(combined);
|
|
775
1352
|
try {
|
|
776
1353
|
try {
|
|
777
|
-
await
|
|
1354
|
+
await combined;
|
|
778
1355
|
if (this.debug) {
|
|
779
1356
|
console.log(`${this.prefix} sent track_partial ${eventId} (${eventName})`);
|
|
780
1357
|
}
|
|
@@ -786,7 +1363,7 @@ var EventShipper = class {
|
|
|
786
1363
|
);
|
|
787
1364
|
}
|
|
788
1365
|
} finally {
|
|
789
|
-
this.inFlight.delete(
|
|
1366
|
+
this.inFlight.delete(combined);
|
|
790
1367
|
}
|
|
791
1368
|
if (!isPending) {
|
|
792
1369
|
this.sticky.delete(eventId);
|
|
@@ -1039,6 +1616,13 @@ function redactJsonAttributeValue(key, value) {
|
|
|
1039
1616
|
if (scrubbedJson === json) return void 0;
|
|
1040
1617
|
return { stringValue: scrubbedJson };
|
|
1041
1618
|
}
|
|
1619
|
+
function appGitOwnerId2(prefix) {
|
|
1620
|
+
try {
|
|
1621
|
+
return `${prefix}:${randomUUID()}`;
|
|
1622
|
+
} catch (e) {
|
|
1623
|
+
return `${prefix}:${Date.now().toString(36)}:${Math.random().toString(36).slice(2)}`;
|
|
1624
|
+
}
|
|
1625
|
+
}
|
|
1042
1626
|
function identityAttrs(args) {
|
|
1043
1627
|
return [
|
|
1044
1628
|
attrString("ai.telemetry.metadata.raindrop.ai.userId", args.userId),
|
|
@@ -1061,23 +1645,30 @@ function applyOtelSpanAttributeLimit(limit) {
|
|
|
1061
1645
|
}
|
|
1062
1646
|
var TraceShipper = class {
|
|
1063
1647
|
constructor(opts) {
|
|
1648
|
+
this.appGitOwner = appGitOwnerId2("trace");
|
|
1649
|
+
this.appGitEventIds = /* @__PURE__ */ new WeakMap();
|
|
1650
|
+
this.appGitActiveSpans = /* @__PURE__ */ new Map();
|
|
1651
|
+
this.appGitCaptured = /* @__PURE__ */ new WeakSet();
|
|
1652
|
+
this.appGitAdded = /* @__PURE__ */ new WeakMap();
|
|
1064
1653
|
this.queue = [];
|
|
1065
1654
|
this.inFlight = /* @__PURE__ */ new Set();
|
|
1066
1655
|
this.hasShutdown = false;
|
|
1067
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
1068
|
-
this.
|
|
1069
|
-
this.
|
|
1656
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
1657
|
+
this.appGitContext = (_a = opts.appGitContext) != null ? _a : createAppGitContext(opts.appGit);
|
|
1658
|
+
this.ownsAppGitContext = opts.appGitContext === void 0;
|
|
1659
|
+
this.writeKey = (_b = opts.writeKey) == null ? void 0 : _b.trim();
|
|
1660
|
+
this.baseUrl = (_c = formatEndpoint(opts.endpoint)) != null ? _c : "https://api.raindrop.ai/v1/";
|
|
1070
1661
|
this.enabled = opts.enabled !== false;
|
|
1071
1662
|
this.debug = opts.debug;
|
|
1072
1663
|
this.debugSpans = opts.debugSpans === true;
|
|
1073
|
-
this.flushIntervalMs = (
|
|
1074
|
-
this.maxBatchSize = (
|
|
1075
|
-
this.maxQueueSize = (
|
|
1076
|
-
this.sdkName = (
|
|
1664
|
+
this.flushIntervalMs = (_d = opts.flushIntervalMs) != null ? _d : 1e3;
|
|
1665
|
+
this.maxBatchSize = (_e = opts.maxBatchSize) != null ? _e : 50;
|
|
1666
|
+
this.maxQueueSize = (_f = opts.maxQueueSize) != null ? _f : 5e3;
|
|
1667
|
+
this.sdkName = (_g = opts.sdkName) != null ? _g : "core";
|
|
1077
1668
|
this.prefix = `[raindrop-ai/${this.sdkName}]`;
|
|
1078
|
-
this.serviceName = (
|
|
1079
|
-
this.serviceVersion = (
|
|
1080
|
-
this.localDebuggerUrl = (
|
|
1669
|
+
this.serviceName = (_h = opts.serviceName) != null ? _h : "raindrop.core";
|
|
1670
|
+
this.serviceVersion = (_i = opts.serviceVersion) != null ? _i : "0.0.0";
|
|
1671
|
+
this.localDebuggerUrl = (_j = resolveLocalDebuggerBaseUrl(opts.localDebuggerUrl)) != null ? _j : void 0;
|
|
1081
1672
|
if (this.debug && this.localDebuggerUrl) {
|
|
1082
1673
|
console.log(`${this.prefix} Local debugger mirroring: ${this.localDebuggerUrl}`);
|
|
1083
1674
|
}
|
|
@@ -1141,7 +1732,10 @@ var TraceShipper = class {
|
|
|
1141
1732
|
try {
|
|
1142
1733
|
const result = this.transformSpanHook(current);
|
|
1143
1734
|
if (result === null) return null;
|
|
1144
|
-
if (result !== void 0)
|
|
1735
|
+
if (result !== void 0) {
|
|
1736
|
+
copyReplayTraceDestination(current, result);
|
|
1737
|
+
current = result;
|
|
1738
|
+
}
|
|
1145
1739
|
} catch (err) {
|
|
1146
1740
|
if (this.debug) {
|
|
1147
1741
|
const msg = err instanceof Error ? err.message : String(err);
|
|
@@ -1151,13 +1745,19 @@ var TraceShipper = class {
|
|
|
1151
1745
|
}
|
|
1152
1746
|
}
|
|
1153
1747
|
try {
|
|
1154
|
-
|
|
1748
|
+
const normalized = normalizeModelUsageSpan(current);
|
|
1749
|
+
copyReplayTraceDestination(current, normalized);
|
|
1750
|
+
current = normalized;
|
|
1155
1751
|
} catch (e) {
|
|
1156
1752
|
}
|
|
1157
1753
|
if (!this.disableDefaultRedaction) {
|
|
1158
|
-
|
|
1754
|
+
const redacted = defaultTransformSpan(current);
|
|
1755
|
+
copyReplayTraceDestination(current, redacted);
|
|
1756
|
+
current = redacted;
|
|
1159
1757
|
}
|
|
1160
|
-
|
|
1758
|
+
const capped = this.capSpanAttributes(current);
|
|
1759
|
+
copyReplayTraceDestination(current, capped);
|
|
1760
|
+
return capped;
|
|
1161
1761
|
}
|
|
1162
1762
|
isDebugEnabled() {
|
|
1163
1763
|
return this.debug;
|
|
@@ -1169,46 +1769,84 @@ var TraceShipper = class {
|
|
|
1169
1769
|
return { ...this.authHeaders(), ...projectIdHeaders(this.projectId) };
|
|
1170
1770
|
}
|
|
1171
1771
|
startSpan(args) {
|
|
1172
|
-
var _a, _b;
|
|
1772
|
+
var _a, _b, _c;
|
|
1173
1773
|
const ids = createSpanIds(args.parent);
|
|
1174
1774
|
const started = (_a = args.startTimeUnixNano) != null ? _a : nowUnixNanoString();
|
|
1175
1775
|
const attrs = [
|
|
1176
1776
|
attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId),
|
|
1177
1777
|
...identityAttrs(args),
|
|
1178
|
-
attrString("ai.operationId", args.operationId)
|
|
1778
|
+
attrString("ai.operationId", args.operationId),
|
|
1779
|
+
...Object.entries(evalScopeAttributes()).map(([key, value]) => attrString(key, value))
|
|
1179
1780
|
];
|
|
1180
1781
|
if ((_b = args.attributes) == null ? void 0 : _b.length) attrs.push(...args.attributes);
|
|
1181
|
-
const
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
);
|
|
1782
|
+
const tracksAppGit = this.appGitActiveSpans.has(args.eventId) || this.appGitActiveSpans.size < 1e4;
|
|
1783
|
+
const appGitOverrides = appGitPropertiesFromAttributes(attrs);
|
|
1784
|
+
const span = {
|
|
1785
|
+
ids,
|
|
1786
|
+
name: args.name,
|
|
1787
|
+
startTimeUnixNano: started,
|
|
1788
|
+
attributes: withAppGitAttributes(
|
|
1789
|
+
attrs,
|
|
1790
|
+
this.appGitContext.forOperation(args.eventId, appGitOverrides, this.appGitOwner)
|
|
1791
|
+
)
|
|
1792
|
+
};
|
|
1793
|
+
rememberReplayTraceDestination(span);
|
|
1794
|
+
this.appGitCaptured.add(span);
|
|
1795
|
+
this.appGitEventIds.set(span, args.eventId);
|
|
1796
|
+
if (tracksAppGit) {
|
|
1797
|
+
this.appGitActiveSpans.set(args.eventId, ((_c = this.appGitActiveSpans.get(args.eventId)) != null ? _c : 0) + 1);
|
|
1798
|
+
}
|
|
1799
|
+
this.appGitAdded.set(span, new Set(span.attributes.filter((attr) => !attrs.includes(attr))));
|
|
1800
|
+
const openSpan = buildOtlpSpan({
|
|
1801
|
+
ids: span.ids,
|
|
1802
|
+
name: span.name,
|
|
1803
|
+
startTimeUnixNano: span.startTimeUnixNano,
|
|
1804
|
+
endTimeUnixNano: span.startTimeUnixNano,
|
|
1805
|
+
// placeholder — will be updated on endSpan
|
|
1806
|
+
attributes: span.attributes,
|
|
1807
|
+
status: { code: SpanStatusCode.UNSET }
|
|
1808
|
+
});
|
|
1809
|
+
copyReplayTraceDestination(span, openSpan);
|
|
1810
|
+
this.mirrorToLocalDebugger(openSpan);
|
|
1193
1811
|
return span;
|
|
1194
1812
|
}
|
|
1195
|
-
mirrorToLocalDebugger(span) {
|
|
1196
|
-
|
|
1813
|
+
mirrorToLocalDebugger(span, completed = false) {
|
|
1814
|
+
const destination = replayTraceDestinationFor(span);
|
|
1815
|
+
if (destination && destination.kind !== "workshop") return;
|
|
1816
|
+
const localDebuggerUrl = (destination == null ? void 0 : destination.kind) === "workshop" ? destination.url : this.localDebuggerUrl;
|
|
1817
|
+
if (!localDebuggerUrl) return;
|
|
1197
1818
|
const redacted = this.redactSpan(span);
|
|
1198
1819
|
if (redacted === null) return;
|
|
1820
|
+
if (completed && (destination == null ? void 0 : destination.kind) === "workshop") {
|
|
1821
|
+
recordReplayExportedSpan(
|
|
1822
|
+
destination,
|
|
1823
|
+
base64ToHex(redacted.spanId),
|
|
1824
|
+
base64ToHex(redacted.traceId)
|
|
1825
|
+
);
|
|
1826
|
+
}
|
|
1199
1827
|
const body = buildExportTraceServiceRequest([redacted], this.serviceName, this.serviceVersion);
|
|
1200
|
-
mirrorTraceExportToLocalDebugger(body, {
|
|
1201
|
-
baseUrl:
|
|
1828
|
+
const p = mirrorTraceExportToLocalDebugger(body, {
|
|
1829
|
+
baseUrl: localDebuggerUrl,
|
|
1202
1830
|
debug: false,
|
|
1203
1831
|
sdkName: this.sdkName
|
|
1204
1832
|
});
|
|
1833
|
+
this.inFlight.add(p);
|
|
1834
|
+
void p.finally(() => {
|
|
1835
|
+
this.inFlight.delete(p);
|
|
1836
|
+
});
|
|
1205
1837
|
}
|
|
1206
1838
|
endSpan(span, extra) {
|
|
1207
|
-
var _a, _b;
|
|
1839
|
+
var _a, _b, _c;
|
|
1208
1840
|
if (span.endTimeUnixNano) return;
|
|
1209
1841
|
span.endTimeUnixNano = (_a = extra == null ? void 0 : extra.endTimeUnixNano) != null ? _a : nowUnixNanoString();
|
|
1210
1842
|
if ((_b = extra == null ? void 0 : extra.attributes) == null ? void 0 : _b.length) {
|
|
1843
|
+
const overrides = appGitPropertiesFromAttributes(extra.attributes);
|
|
1844
|
+
const eventId2 = this.appGitEventIds.get(span);
|
|
1845
|
+
const snapshot = eventId2 ? this.appGitContext.forOperation(eventId2, overrides, this.appGitOwner) : overrides;
|
|
1846
|
+
const added = this.appGitAdded.get(span);
|
|
1847
|
+
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));
|
|
1211
1848
|
span.attributes.push(...extra.attributes);
|
|
1849
|
+
span.attributes = withAppGitAttributes(span.attributes, snapshot);
|
|
1212
1850
|
}
|
|
1213
1851
|
let status = extra == null ? void 0 : extra.status;
|
|
1214
1852
|
if (!status && (extra == null ? void 0 : extra.error) !== void 0) {
|
|
@@ -1223,30 +1861,65 @@ var TraceShipper = class {
|
|
|
1223
1861
|
attributes: span.attributes,
|
|
1224
1862
|
status
|
|
1225
1863
|
});
|
|
1864
|
+
copyReplayTraceDestination(span, otlp);
|
|
1865
|
+
this.appGitCaptured.add(otlp);
|
|
1226
1866
|
this.enqueue(otlp);
|
|
1227
|
-
this.mirrorToLocalDebugger(otlp);
|
|
1867
|
+
this.mirrorToLocalDebugger(otlp, true);
|
|
1868
|
+
const eventId = this.appGitEventIds.get(span);
|
|
1869
|
+
if (eventId && this.appGitActiveSpans.has(eventId)) {
|
|
1870
|
+
const remaining = ((_c = this.appGitActiveSpans.get(eventId)) != null ? _c : 1) - 1;
|
|
1871
|
+
if (remaining > 0) this.appGitActiveSpans.set(eventId, remaining);
|
|
1872
|
+
else {
|
|
1873
|
+
this.appGitActiveSpans.delete(eventId);
|
|
1874
|
+
if (this.appGitContext.releaseOperation) this.appGitContext.releaseOperation(eventId, this.appGitOwner);
|
|
1875
|
+
else if (this.ownsAppGitContext) this.appGitContext.finishOperation(eventId);
|
|
1876
|
+
}
|
|
1877
|
+
}
|
|
1228
1878
|
}
|
|
1229
1879
|
createSpan(args) {
|
|
1230
1880
|
var _a;
|
|
1231
1881
|
const ids = createSpanIds(args.parent);
|
|
1232
1882
|
const attrs = [
|
|
1233
1883
|
attrString("ai.telemetry.metadata.raindrop.eventId", args.eventId),
|
|
1234
|
-
...identityAttrs(args)
|
|
1884
|
+
...identityAttrs(args),
|
|
1885
|
+
...Object.entries(evalScopeAttributes()).map(([key, value]) => attrString(key, value))
|
|
1235
1886
|
];
|
|
1236
1887
|
if ((_a = args.attributes) == null ? void 0 : _a.length) attrs.push(...args.attributes);
|
|
1888
|
+
const tracksAppGit = !this.appGitActiveSpans.has(args.eventId);
|
|
1237
1889
|
const otlp = buildOtlpSpan({
|
|
1238
1890
|
ids,
|
|
1239
1891
|
name: args.name,
|
|
1240
1892
|
startTimeUnixNano: args.startTimeUnixNano,
|
|
1241
1893
|
endTimeUnixNano: args.endTimeUnixNano,
|
|
1242
|
-
attributes:
|
|
1894
|
+
attributes: withAppGitAttributes(
|
|
1895
|
+
attrs,
|
|
1896
|
+
this.appGitContext.forOperation(
|
|
1897
|
+
args.eventId,
|
|
1898
|
+
appGitPropertiesFromAttributes(attrs),
|
|
1899
|
+
this.appGitOwner
|
|
1900
|
+
)
|
|
1901
|
+
),
|
|
1243
1902
|
status: args.status
|
|
1244
1903
|
});
|
|
1904
|
+
rememberReplayTraceDestination(otlp);
|
|
1905
|
+
this.appGitCaptured.add(otlp);
|
|
1906
|
+
if (tracksAppGit) {
|
|
1907
|
+
if (this.appGitContext.releaseOperation) this.appGitContext.releaseOperation(args.eventId, this.appGitOwner);
|
|
1908
|
+
else if (this.ownsAppGitContext) this.appGitContext.finishOperation(args.eventId);
|
|
1909
|
+
}
|
|
1245
1910
|
this.enqueue(otlp);
|
|
1246
|
-
this.mirrorToLocalDebugger(otlp);
|
|
1911
|
+
this.mirrorToLocalDebugger(otlp, true);
|
|
1247
1912
|
}
|
|
1248
1913
|
enqueue(span) {
|
|
1914
|
+
var _a;
|
|
1249
1915
|
if (!this.enabled) return;
|
|
1916
|
+
const attributes = (_a = span.attributes) != null ? _a : [];
|
|
1917
|
+
const enriched = this.appGitCaptured.has(span) ? attributes : withAppGitAttributes(attributes, this.appGitContext.snapshot(appGitPropertiesFromAttributes(attributes)));
|
|
1918
|
+
if (enriched !== attributes) {
|
|
1919
|
+
const original = span;
|
|
1920
|
+
span = { ...span, attributes: enriched.filter((attr) => attr !== void 0) };
|
|
1921
|
+
copyReplayTraceDestination(original, span);
|
|
1922
|
+
}
|
|
1250
1923
|
if (this.debugSpans) {
|
|
1251
1924
|
const short = (s) => s ? s.slice(-8) : "none";
|
|
1252
1925
|
console.log(
|
|
@@ -1257,6 +1930,13 @@ var TraceShipper = class {
|
|
|
1257
1930
|
}
|
|
1258
1931
|
const redacted = this.redactSpan(span);
|
|
1259
1932
|
if (redacted === null) return;
|
|
1933
|
+
const destination = replayTraceDestinationFor(redacted);
|
|
1934
|
+
recordReplayExportedSpan(
|
|
1935
|
+
destination,
|
|
1936
|
+
base64ToHex(redacted.spanId),
|
|
1937
|
+
base64ToHex(redacted.traceId)
|
|
1938
|
+
);
|
|
1939
|
+
if ((destination == null ? void 0 : destination.kind) === "workshop") return;
|
|
1260
1940
|
if (this.queue.length >= this.maxQueueSize) {
|
|
1261
1941
|
this.queue.shift();
|
|
1262
1942
|
}
|
|
@@ -1275,47 +1955,67 @@ var TraceShipper = class {
|
|
|
1275
1955
|
}
|
|
1276
1956
|
}
|
|
1277
1957
|
async flush() {
|
|
1278
|
-
|
|
1958
|
+
var _a;
|
|
1959
|
+
if (!this.enabled) {
|
|
1960
|
+
await Promise.all([...this.inFlight].map((p) => p.catch(() => {
|
|
1961
|
+
})));
|
|
1962
|
+
return;
|
|
1963
|
+
}
|
|
1279
1964
|
if (this.timer) {
|
|
1280
1965
|
clearTimeout(this.timer);
|
|
1281
1966
|
this.timer = void 0;
|
|
1282
1967
|
}
|
|
1283
1968
|
while (this.queue.length > 0) {
|
|
1284
1969
|
const batch = this.queue.splice(0, this.maxBatchSize);
|
|
1285
|
-
|
|
1286
|
-
const
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
`${this.prefix} shutdown flush deadline exceeded; dropping ${batch.length} spans`
|
|
1292
|
-
)
|
|
1293
|
-
);
|
|
1294
|
-
continue;
|
|
1970
|
+
const groups = /* @__PURE__ */ new Map();
|
|
1971
|
+
for (const span of batch) {
|
|
1972
|
+
const destination = replayTraceDestinationFor(span);
|
|
1973
|
+
const spans = groups.get(destination);
|
|
1974
|
+
if (spans) spans.push(span);
|
|
1975
|
+
else groups.set(destination, [span]);
|
|
1295
1976
|
}
|
|
1296
|
-
const
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
endpoint: url
|
|
1302
|
-
});
|
|
1303
|
-
}
|
|
1304
|
-
const p = postJson(url, body, this.requestHeaders(), opts);
|
|
1305
|
-
this.inFlight.add(p);
|
|
1306
|
-
try {
|
|
1307
|
-
try {
|
|
1308
|
-
await p;
|
|
1309
|
-
if (this.debug) console.log(`${this.prefix} sent ${batch.length} spans`);
|
|
1310
|
-
} catch (err) {
|
|
1311
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
1977
|
+
for (const [destination, spans] of groups) {
|
|
1978
|
+
if (!destination && !this.writeKey) continue;
|
|
1979
|
+
if ((destination == null ? void 0 : destination.kind) === "workshop") continue;
|
|
1980
|
+
const opts = this.requestOpts();
|
|
1981
|
+
if (!opts) {
|
|
1312
1982
|
rateLimitedLog(
|
|
1313
|
-
`${this.prefix}.
|
|
1314
|
-
() => console.warn(
|
|
1983
|
+
`${this.prefix}.shutdown_deadline`,
|
|
1984
|
+
() => console.warn(
|
|
1985
|
+
`${this.prefix} shutdown flush deadline exceeded; dropping ${spans.length} spans`
|
|
1986
|
+
)
|
|
1315
1987
|
);
|
|
1988
|
+
continue;
|
|
1989
|
+
}
|
|
1990
|
+
const body = buildExportTraceServiceRequest(spans, this.serviceName, this.serviceVersion);
|
|
1991
|
+
const url = destination ? replayTraceUrl(destination.url) : `${this.baseUrl}traces`;
|
|
1992
|
+
const headers = destination ? {
|
|
1993
|
+
Authorization: `Bearer ${destination.apiKey}`,
|
|
1994
|
+
"X-Raindrop-Replay-Id": destination.replayId,
|
|
1995
|
+
"X-Raindrop-Project-Id": (_a = destination.projectId) != null ? _a : "default"
|
|
1996
|
+
} : this.requestHeaders();
|
|
1997
|
+
if (this.debug) {
|
|
1998
|
+
console.log(`${this.prefix} sending traces batch`, {
|
|
1999
|
+
spans: spans.length,
|
|
2000
|
+
endpoint: url
|
|
2001
|
+
});
|
|
2002
|
+
}
|
|
2003
|
+
const p = postJson(url, body, headers, opts);
|
|
2004
|
+
this.inFlight.add(p);
|
|
2005
|
+
try {
|
|
2006
|
+
try {
|
|
2007
|
+
await p;
|
|
2008
|
+
if (this.debug) console.log(`${this.prefix} sent ${spans.length} spans`);
|
|
2009
|
+
} catch (err) {
|
|
2010
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
2011
|
+
rateLimitedLog(
|
|
2012
|
+
`${this.prefix}.send_spans_failed`,
|
|
2013
|
+
() => console.warn(`${this.prefix} failed to send ${spans.length} spans: ${msg}`)
|
|
2014
|
+
);
|
|
2015
|
+
}
|
|
2016
|
+
} finally {
|
|
2017
|
+
this.inFlight.delete(p);
|
|
1316
2018
|
}
|
|
1317
|
-
} finally {
|
|
1318
|
-
this.inFlight.delete(p);
|
|
1319
2019
|
}
|
|
1320
2020
|
}
|
|
1321
2021
|
}
|
|
@@ -1358,17 +2058,165 @@ var TraceShipper = class {
|
|
|
1358
2058
|
if (!settled) {
|
|
1359
2059
|
rateLimitedLog(
|
|
1360
2060
|
`${this.prefix}.shutdown_deadline`,
|
|
1361
|
-
() => console.warn(
|
|
2061
|
+
() => console.warn(
|
|
2062
|
+
`${this.prefix} shutdown flush deadline exceeded; abandoning in-flight spans`
|
|
2063
|
+
)
|
|
1362
2064
|
);
|
|
1363
2065
|
}
|
|
1364
2066
|
} finally {
|
|
1365
2067
|
this.shutdownDeadlineAt = void 0;
|
|
2068
|
+
if (this.ownsAppGitContext) this.appGitContext.dispose();
|
|
1366
2069
|
}
|
|
1367
2070
|
}
|
|
1368
2071
|
};
|
|
1369
2072
|
|
|
1370
2073
|
// ../core/dist/index.node.js
|
|
1371
2074
|
import { AsyncLocalStorage } from "async_hooks";
|
|
2075
|
+
import { execFile } from "child_process";
|
|
2076
|
+
import { resolve } from "path";
|
|
2077
|
+
var resolveLocal = (sourceDirectory, detectBranch, completed) => {
|
|
2078
|
+
const cwd = sourceDirectory ? resolve(sourceDirectory) : process.cwd();
|
|
2079
|
+
let cancelled = false;
|
|
2080
|
+
let active;
|
|
2081
|
+
let deadlineTimer;
|
|
2082
|
+
const deadline = Date.now() + 1e3;
|
|
2083
|
+
const run = (args, done) => {
|
|
2084
|
+
if (cancelled) return;
|
|
2085
|
+
const remaining = deadline - Date.now();
|
|
2086
|
+
if (remaining <= 0) {
|
|
2087
|
+
done(void 0);
|
|
2088
|
+
return;
|
|
2089
|
+
}
|
|
2090
|
+
try {
|
|
2091
|
+
active = execFile(
|
|
2092
|
+
"git",
|
|
2093
|
+
args,
|
|
2094
|
+
{
|
|
2095
|
+
cwd,
|
|
2096
|
+
encoding: "utf8",
|
|
2097
|
+
maxBuffer: 4096,
|
|
2098
|
+
windowsHide: true,
|
|
2099
|
+
env: {
|
|
2100
|
+
...process.env,
|
|
2101
|
+
// The selected application cwd, not the invoking shell's Git plumbing, owns identity.
|
|
2102
|
+
GIT_DIR: void 0,
|
|
2103
|
+
GIT_WORK_TREE: void 0,
|
|
2104
|
+
GIT_COMMON_DIR: void 0,
|
|
2105
|
+
GIT_NAMESPACE: void 0,
|
|
2106
|
+
GIT_INDEX_FILE: void 0,
|
|
2107
|
+
GIT_OBJECT_DIRECTORY: void 0,
|
|
2108
|
+
GIT_ALTERNATE_OBJECT_DIRECTORIES: void 0,
|
|
2109
|
+
GIT_CONFIG_PARAMETERS: void 0,
|
|
2110
|
+
GIT_CONFIG_COUNT: "0",
|
|
2111
|
+
GIT_TERMINAL_PROMPT: "0",
|
|
2112
|
+
GIT_OPTIONAL_LOCKS: "0"
|
|
2113
|
+
}
|
|
2114
|
+
},
|
|
2115
|
+
(error, stdout) => {
|
|
2116
|
+
clearTimeout(deadlineTimer);
|
|
2117
|
+
deadlineTimer = void 0;
|
|
2118
|
+
active = void 0;
|
|
2119
|
+
if (!cancelled) {
|
|
2120
|
+
try {
|
|
2121
|
+
done(error ? void 0 : stdout.trim());
|
|
2122
|
+
} catch (e) {
|
|
2123
|
+
}
|
|
2124
|
+
}
|
|
2125
|
+
}
|
|
2126
|
+
);
|
|
2127
|
+
active.unref();
|
|
2128
|
+
if (active.stdout && "unref" in active.stdout && typeof active.stdout.unref === "function")
|
|
2129
|
+
active.stdout.unref();
|
|
2130
|
+
if (active.stderr && "unref" in active.stderr && typeof active.stderr.unref === "function")
|
|
2131
|
+
active.stderr.unref();
|
|
2132
|
+
deadlineTimer = setTimeout(() => {
|
|
2133
|
+
try {
|
|
2134
|
+
active == null ? void 0 : active.kill("SIGKILL");
|
|
2135
|
+
} catch (e) {
|
|
2136
|
+
}
|
|
2137
|
+
}, remaining);
|
|
2138
|
+
deadlineTimer.unref();
|
|
2139
|
+
} catch (e) {
|
|
2140
|
+
try {
|
|
2141
|
+
done(void 0);
|
|
2142
|
+
} catch (e2) {
|
|
2143
|
+
}
|
|
2144
|
+
}
|
|
2145
|
+
};
|
|
2146
|
+
const scheduled = setTimeout(() => {
|
|
2147
|
+
try {
|
|
2148
|
+
run(["rev-parse", "HEAD"], (rawSha) => {
|
|
2149
|
+
const commitSha = validAppCommitSha(rawSha);
|
|
2150
|
+
if (!commitSha) {
|
|
2151
|
+
completed({});
|
|
2152
|
+
return;
|
|
2153
|
+
}
|
|
2154
|
+
run(["-c", "core.fsmonitor=false", "status", "--porcelain"], (status) => {
|
|
2155
|
+
const finish = (branch) => {
|
|
2156
|
+
run(["rev-parse", "HEAD"], (finalSha) => {
|
|
2157
|
+
const coherent = validAppCommitSha(finalSha) === commitSha;
|
|
2158
|
+
completed({
|
|
2159
|
+
commitSha,
|
|
2160
|
+
...coherent && status !== void 0 ? { commitDirty: status !== "" } : {},
|
|
2161
|
+
...coherent && branch && branch !== "HEAD" ? { branch } : {}
|
|
2162
|
+
});
|
|
2163
|
+
});
|
|
2164
|
+
};
|
|
2165
|
+
if (detectBranch) run(["symbolic-ref", "--quiet", "--short", "HEAD"], finish);
|
|
2166
|
+
else finish();
|
|
2167
|
+
});
|
|
2168
|
+
});
|
|
2169
|
+
} catch (e) {
|
|
2170
|
+
completed({});
|
|
2171
|
+
}
|
|
2172
|
+
}, 0);
|
|
2173
|
+
scheduled.unref();
|
|
2174
|
+
return () => {
|
|
2175
|
+
cancelled = true;
|
|
2176
|
+
clearTimeout(scheduled);
|
|
2177
|
+
clearTimeout(deadlineTimer);
|
|
2178
|
+
try {
|
|
2179
|
+
active == null ? void 0 : active.kill("SIGKILL");
|
|
2180
|
+
} catch (e) {
|
|
2181
|
+
}
|
|
2182
|
+
};
|
|
2183
|
+
};
|
|
2184
|
+
function createAppGitContext2(options, runtime = {}) {
|
|
2185
|
+
return new AppGitContext(options, { ...runtime, resolveLocal });
|
|
2186
|
+
}
|
|
2187
|
+
function hasDestination(options) {
|
|
2188
|
+
var _a;
|
|
2189
|
+
if (options.enabled === false) return false;
|
|
2190
|
+
return Boolean(((_a = options.writeKey) == null ? void 0 : _a.trim()) || resolveLocalDebuggerBaseUrl(options.localDebuggerUrl));
|
|
2191
|
+
}
|
|
2192
|
+
var EventShipper2 = class extends EventShipper {
|
|
2193
|
+
constructor(options) {
|
|
2194
|
+
var _a;
|
|
2195
|
+
const ownsAppGitContext = options.appGitContext === void 0;
|
|
2196
|
+
const appGitContext = (_a = options.appGitContext) != null ? _a : createAppGitContext2(options.appGit, { allowDiscovery: hasDestination(options) });
|
|
2197
|
+
try {
|
|
2198
|
+
super({ ...options, appGitContext });
|
|
2199
|
+
} catch (error) {
|
|
2200
|
+
if (ownsAppGitContext) appGitContext.dispose();
|
|
2201
|
+
throw error;
|
|
2202
|
+
}
|
|
2203
|
+
if (ownsAppGitContext) this.ownAppGitContextForShutdown();
|
|
2204
|
+
}
|
|
2205
|
+
};
|
|
2206
|
+
var TraceShipper2 = class extends TraceShipper {
|
|
2207
|
+
constructor(options) {
|
|
2208
|
+
var _a;
|
|
2209
|
+
const ownsAppGitContext = options.appGitContext === void 0;
|
|
2210
|
+
const appGitContext = (_a = options.appGitContext) != null ? _a : createAppGitContext2(options.appGit, { allowDiscovery: hasDestination(options) });
|
|
2211
|
+
try {
|
|
2212
|
+
super({ ...options, appGitContext });
|
|
2213
|
+
} catch (error) {
|
|
2214
|
+
if (ownsAppGitContext) appGitContext.dispose();
|
|
2215
|
+
throw error;
|
|
2216
|
+
}
|
|
2217
|
+
this.ownsAppGitContext = ownsAppGitContext;
|
|
2218
|
+
}
|
|
2219
|
+
};
|
|
1372
2220
|
globalThis.RAINDROP_ASYNC_LOCAL_STORAGE = AsyncLocalStorage;
|
|
1373
2221
|
var SUPPRESS_TRACING_KEY = /* @__PURE__ */ Symbol.for(
|
|
1374
2222
|
"OpenTelemetry SDK Context Key SUPPRESS_TRACING"
|
|
@@ -1433,7 +2281,20 @@ function loadConfig(projectDirectory) {
|
|
|
1433
2281
|
debug: process.env["RAINDROP_DEBUG"] === "true" ? true : (_g = merged.debug) != null ? _g : false,
|
|
1434
2282
|
captureSystemPrompt: process.env["RAINDROP_CAPTURE_SYSTEM_PROMPT"] !== void 0 ? process.env["RAINDROP_CAPTURE_SYSTEM_PROMPT"] === "true" : (_h = merged.capture_system_prompt) != null ? _h : false,
|
|
1435
2283
|
eventMetadata,
|
|
1436
|
-
localWorkshopUrl: resolveLocalWorkshopUrl(merged.local_workshop_url)
|
|
2284
|
+
localWorkshopUrl: resolveLocalWorkshopUrl(merged.local_workshop_url),
|
|
2285
|
+
appGit: mapAppGit(merged.app_git)
|
|
2286
|
+
};
|
|
2287
|
+
}
|
|
2288
|
+
function mapAppGit(value) {
|
|
2289
|
+
if (value === false) return false;
|
|
2290
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) return void 0;
|
|
2291
|
+
return {
|
|
2292
|
+
commitSha: "commit_sha" in value && (typeof value.commit_sha === "string" || value.commit_sha === null) ? value.commit_sha : void 0,
|
|
2293
|
+
commitDirty: "commit_dirty" in value && (typeof value.commit_dirty === "boolean" || value.commit_dirty === null) ? value.commit_dirty : void 0,
|
|
2294
|
+
branch: "branch" in value && (typeof value.branch === "string" || value.branch === null) ? value.branch : void 0,
|
|
2295
|
+
detectBranch: "detect_branch" in value && typeof value.detect_branch === "boolean" ? value.detect_branch : void 0,
|
|
2296
|
+
sourceDirectory: "source_directory" in value && typeof value.source_directory === "string" ? value.source_directory : void 0,
|
|
2297
|
+
autoDetect: "auto_detect" in value && typeof value.auto_detect === "boolean" ? value.auto_detect : void 0
|
|
1437
2298
|
};
|
|
1438
2299
|
}
|
|
1439
2300
|
function resolveLocalWorkshopUrl(fileValue) {
|
|
@@ -1450,7 +2311,7 @@ function resolveLocalWorkshopUrl(fileValue) {
|
|
|
1450
2311
|
// package.json
|
|
1451
2312
|
var package_default = {
|
|
1452
2313
|
name: "@raindrop-ai/opencode-plugin",
|
|
1453
|
-
version: "0.1.
|
|
2314
|
+
version: "0.1.4",
|
|
1454
2315
|
description: "Raindrop observability plugin for OpenCode \u2014 automatic session/event/span tracing",
|
|
1455
2316
|
type: "module",
|
|
1456
2317
|
main: "dist/index.js",
|
|
@@ -1521,7 +2382,7 @@ var PLUGIN_NAME = package_default.name;
|
|
|
1521
2382
|
var PLUGIN_VERSION = package_default.version;
|
|
1522
2383
|
|
|
1523
2384
|
// src/shipper.ts
|
|
1524
|
-
var
|
|
2385
|
+
var EventShipper3 = class extends EventShipper2 {
|
|
1525
2386
|
constructor(opts) {
|
|
1526
2387
|
var _a, _b, _c, _d;
|
|
1527
2388
|
super({
|
|
@@ -1533,7 +2394,7 @@ var EventShipper2 = class extends EventShipper {
|
|
|
1533
2394
|
});
|
|
1534
2395
|
}
|
|
1535
2396
|
};
|
|
1536
|
-
var
|
|
2397
|
+
var TraceShipper3 = class extends TraceShipper2 {
|
|
1537
2398
|
constructor(opts) {
|
|
1538
2399
|
var _a, _b, _c;
|
|
1539
2400
|
super({
|
|
@@ -1691,11 +2552,11 @@ function createSessionParentMapHelpers({
|
|
|
1691
2552
|
}) {
|
|
1692
2553
|
function applyChildSessionParentToState(childSessionId) {
|
|
1693
2554
|
const parentInfo = mapChildSessionToParent2.get(childSessionId);
|
|
1694
|
-
const
|
|
1695
|
-
if (!parentInfo || !
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
2555
|
+
const state2 = sessions2.get(childSessionId);
|
|
2556
|
+
if (!parentInfo || !state2) return;
|
|
2557
|
+
state2.parentId = parentInfo.parentId;
|
|
2558
|
+
state2.parentTaskSpanIds = parentInfo.parentTaskSpanIds;
|
|
2559
|
+
state2.parentEventContext = parentInfo.eventContext;
|
|
1699
2560
|
}
|
|
1700
2561
|
function queuePendingChildByCallKey(key, childSessionId) {
|
|
1701
2562
|
var _a;
|
|
@@ -1791,10 +2652,10 @@ function markTaskCallFinished(sessionID, callID) {
|
|
|
1791
2652
|
running.delete(callID);
|
|
1792
2653
|
if (running.size === 0) runningTaskCallsBySession.delete(sessionID);
|
|
1793
2654
|
}
|
|
1794
|
-
function endPendingToolSpanWithError(
|
|
1795
|
-
const startInfo =
|
|
2655
|
+
function endPendingToolSpanWithError(state2, callID, tool, toolCallArgs, errorMessage, traceShipper) {
|
|
2656
|
+
const startInfo = state2.toolSpanStarts.get(callID);
|
|
1796
2657
|
if (!startInfo) return false;
|
|
1797
|
-
|
|
2658
|
+
state2.toolSpanStarts.delete(callID);
|
|
1798
2659
|
const error = new Error(errorMessage);
|
|
1799
2660
|
const endAttrs = [
|
|
1800
2661
|
attrString("ai.toolCall.args", toolCallArgs),
|
|
@@ -1894,17 +2755,17 @@ function createHooks(config, worktree, directory, eventShipper, traceShipper) {
|
|
|
1894
2755
|
if (info == null || typeof info !== "object")
|
|
1895
2756
|
throw new Error("session.created: props.info is required");
|
|
1896
2757
|
const parentID = info["parentID"];
|
|
1897
|
-
let
|
|
1898
|
-
if (!
|
|
1899
|
-
|
|
1900
|
-
sessions.set(sessionID,
|
|
2758
|
+
let state2 = sessions.get(sessionID);
|
|
2759
|
+
if (!state2) {
|
|
2760
|
+
state2 = createSessionState(sessionID);
|
|
2761
|
+
sessions.set(sessionID, state2);
|
|
1901
2762
|
}
|
|
1902
|
-
|
|
1903
|
-
if (
|
|
2763
|
+
state2.parentId = parentID;
|
|
2764
|
+
if (state2.parentId) mapChildSessionToParent.set(sessionID, { parentId: state2.parentId });
|
|
1904
2765
|
} else if (event.type === "session.compacted") {
|
|
1905
|
-
const
|
|
1906
|
-
if (!
|
|
1907
|
-
|
|
2766
|
+
const state2 = sessions.get(String(sessionID));
|
|
2767
|
+
if (!state2) return;
|
|
2768
|
+
state2.isCompacting = true;
|
|
1908
2769
|
} else if (event.type === "message.part.updated") {
|
|
1909
2770
|
const part = props["part"];
|
|
1910
2771
|
if (part == null || typeof part !== "object")
|
|
@@ -1916,10 +2777,10 @@ function createHooks(config, worktree, directory, eventShipper, traceShipper) {
|
|
|
1916
2777
|
throw new Error("message.part.updated: part.sessionID is required");
|
|
1917
2778
|
if (messageId == null || messageId === "")
|
|
1918
2779
|
throw new Error("message.part.updated: part.messageID is required");
|
|
1919
|
-
const
|
|
1920
|
-
if (!
|
|
2780
|
+
const state2 = sessions.get(partSessionID);
|
|
2781
|
+
if (!state2) return;
|
|
1921
2782
|
if (partObj["type"] === "text" && typeof partObj["text"] === "string") {
|
|
1922
|
-
|
|
2783
|
+
state2.outputParts.set(messageId, capText2(partObj["text"]));
|
|
1923
2784
|
} else if (partObj["type"] === "tool" && messageId) {
|
|
1924
2785
|
const tool = partObj["tool"];
|
|
1925
2786
|
const callID = partObj["callID"];
|
|
@@ -1951,7 +2812,7 @@ function createHooks(config, worktree, directory, eventShipper, traceShipper) {
|
|
|
1951
2812
|
const input = toolState["input"];
|
|
1952
2813
|
const toolCallArgs = input === void 0 ? void 0 : typeof input === "string" ? capText2(input) : boundedStringify(input);
|
|
1953
2814
|
if (endPendingToolSpanWithError(
|
|
1954
|
-
|
|
2815
|
+
state2,
|
|
1955
2816
|
callID,
|
|
1956
2817
|
tool,
|
|
1957
2818
|
toolCallArgs,
|
|
@@ -1962,7 +2823,7 @@ function createHooks(config, worktree, directory, eventShipper, traceShipper) {
|
|
|
1962
2823
|
}
|
|
1963
2824
|
}
|
|
1964
2825
|
} else if (partObj["type"] === "reasoning" && typeof partObj["text"] === "string") {
|
|
1965
|
-
|
|
2826
|
+
state2.reasoningParts.set(messageId, capText2(partObj["text"]));
|
|
1966
2827
|
}
|
|
1967
2828
|
} else if (event.type === "message.updated") {
|
|
1968
2829
|
const msgInfo = props["info"];
|
|
@@ -1982,10 +2843,10 @@ function createHooks(config, worktree, directory, eventShipper, traceShipper) {
|
|
|
1982
2843
|
throw new Error("message.updated: info.time is required");
|
|
1983
2844
|
const timeObj = time;
|
|
1984
2845
|
if (timeObj["completed"] == null) return;
|
|
1985
|
-
const
|
|
1986
|
-
if (!
|
|
1987
|
-
if (
|
|
1988
|
-
|
|
2846
|
+
const state2 = sessions.get(msgSessionID);
|
|
2847
|
+
if (!state2 || !state2.currentEventId || !state2.currentRootSpan) return;
|
|
2848
|
+
if (state2.processedMessages.has(messageId)) return;
|
|
2849
|
+
state2.processedMessages.add(messageId);
|
|
1989
2850
|
const tokens = info2["tokens"];
|
|
1990
2851
|
if (tokens == null || typeof tokens !== "object")
|
|
1991
2852
|
throw new Error("message.updated: info.tokens is required");
|
|
@@ -2002,13 +2863,13 @@ function createHooks(config, worktree, directory, eventShipper, traceShipper) {
|
|
|
2002
2863
|
);
|
|
2003
2864
|
const modelName = `${providerID}/${modelID}`;
|
|
2004
2865
|
const finishReason = info2["finish"];
|
|
2005
|
-
const outputText =
|
|
2006
|
-
const reasoningText =
|
|
2866
|
+
const outputText = state2.outputParts.get(messageId);
|
|
2867
|
+
const reasoningText = state2.reasoningParts.get(messageId);
|
|
2007
2868
|
const isToolCallsCompletion = finishReason === "tool-calls";
|
|
2008
2869
|
if (outputText !== void 0 && outputText.trim().length > 0) {
|
|
2009
|
-
|
|
2870
|
+
state2.turnOutputParts.push(outputText);
|
|
2010
2871
|
}
|
|
2011
|
-
|
|
2872
|
+
state2.turnOutputTokens += outputTokens;
|
|
2012
2873
|
if (outputText === void 0 && !isToolCallsCompletion) return;
|
|
2013
2874
|
const msgError = info2["error"];
|
|
2014
2875
|
const errorForSpan = msgError ? (() => {
|
|
@@ -2028,17 +2889,17 @@ type: ${name != null ? name : "UnknownError"}`;
|
|
|
2028
2889
|
attrString("ai.response.text", responseText),
|
|
2029
2890
|
...buildLlmGenAiAttributes({ providerID, modelID, tokens: tokensObj })
|
|
2030
2891
|
];
|
|
2031
|
-
if (
|
|
2892
|
+
if (state2.currentSystemPrompt) {
|
|
2032
2893
|
llmAttrs.push(
|
|
2033
2894
|
attrString("gen_ai.prompt.0.role", "system"),
|
|
2034
|
-
attrString("gen_ai.prompt.0.content",
|
|
2895
|
+
attrString("gen_ai.prompt.0.content", state2.currentSystemPrompt)
|
|
2035
2896
|
);
|
|
2036
2897
|
}
|
|
2037
|
-
const llmParent =
|
|
2898
|
+
const llmParent = state2.parentId && state2.parentTaskSpanIds ? state2.parentTaskSpanIds : state2.currentRootSpan.ids;
|
|
2038
2899
|
const llmSpan = traceShipper.startSpan({
|
|
2039
2900
|
name: modelName,
|
|
2040
2901
|
parent: llmParent,
|
|
2041
|
-
eventId:
|
|
2902
|
+
eventId: state2.currentEventId,
|
|
2042
2903
|
attributes: llmAttrs
|
|
2043
2904
|
});
|
|
2044
2905
|
if (typeof timeObj["created"] === "number") {
|
|
@@ -2049,40 +2910,40 @@ type: ${name != null ? name : "UnknownError"}`;
|
|
|
2049
2910
|
return;
|
|
2050
2911
|
}
|
|
2051
2912
|
if (outputText === void 0) return;
|
|
2052
|
-
const turnOutputText = capText2(
|
|
2053
|
-
const rootSpan =
|
|
2054
|
-
const isCompaction =
|
|
2055
|
-
if (
|
|
2056
|
-
const userInput = unwrapQuotes(
|
|
2913
|
+
const turnOutputText = capText2(state2.turnOutputParts.join("\n\n"));
|
|
2914
|
+
const rootSpan = state2.currentRootSpan;
|
|
2915
|
+
const isCompaction = state2.isCompacting === true;
|
|
2916
|
+
if (state2.parentId) {
|
|
2917
|
+
const userInput = unwrapQuotes(state2.currentInput);
|
|
2057
2918
|
const llmAttrs = [
|
|
2058
2919
|
attrString("ai.operationId", "generateText"),
|
|
2059
2920
|
attrString("ai.prompt", userInput),
|
|
2060
2921
|
attrString(
|
|
2061
2922
|
"ai.prompt.messages",
|
|
2062
|
-
buildPromptMessages(
|
|
2923
|
+
buildPromptMessages(state2.currentSystemPrompt, state2.currentInput)
|
|
2063
2924
|
),
|
|
2064
2925
|
attrString("ai.response.text", turnOutputText),
|
|
2065
2926
|
...buildLlmGenAiAttributes({ providerID, modelID, tokens: tokensObj })
|
|
2066
2927
|
];
|
|
2067
|
-
if (
|
|
2928
|
+
if (state2.currentSystemPrompt) {
|
|
2068
2929
|
llmAttrs.push(
|
|
2069
2930
|
attrString("gen_ai.prompt.0.role", "system"),
|
|
2070
|
-
attrString("gen_ai.prompt.0.content",
|
|
2931
|
+
attrString("gen_ai.prompt.0.content", state2.currentSystemPrompt)
|
|
2071
2932
|
);
|
|
2072
2933
|
}
|
|
2073
|
-
if (!
|
|
2934
|
+
if (!state2.parentTaskSpanIds) {
|
|
2074
2935
|
traceShipper.endSpan(rootSpan, {
|
|
2075
2936
|
error: "Missing strict parent task for child session"
|
|
2076
2937
|
});
|
|
2077
|
-
|
|
2078
|
-
|
|
2938
|
+
state2.currentRootSpan = void 0;
|
|
2939
|
+
state2.currentEventId = void 0;
|
|
2079
2940
|
await traceShipper.flush();
|
|
2080
2941
|
return;
|
|
2081
2942
|
}
|
|
2082
2943
|
const finalLlmSpan = traceShipper.startSpan({
|
|
2083
2944
|
name: modelName,
|
|
2084
|
-
parent:
|
|
2085
|
-
eventId:
|
|
2945
|
+
parent: state2.parentTaskSpanIds,
|
|
2946
|
+
eventId: state2.currentEventId,
|
|
2086
2947
|
attributes: llmAttrs
|
|
2087
2948
|
});
|
|
2088
2949
|
if (typeof timeObj["created"] === "number") {
|
|
@@ -2092,19 +2953,19 @@ type: ${name != null ? name : "UnknownError"}`;
|
|
|
2092
2953
|
traceShipper.endSpan(rootSpan, {
|
|
2093
2954
|
attributes: [
|
|
2094
2955
|
attrString("is_subagent", "true"),
|
|
2095
|
-
attrString("parent_session_id",
|
|
2956
|
+
attrString("parent_session_id", state2.parentId)
|
|
2096
2957
|
],
|
|
2097
2958
|
error: errorForSpan
|
|
2098
2959
|
});
|
|
2099
2960
|
} else {
|
|
2100
2961
|
rootSpan.name = isCompaction ? "ai.compaction" : modelName;
|
|
2101
|
-
const userInput = unwrapQuotes(
|
|
2962
|
+
const userInput = unwrapQuotes(state2.currentInput);
|
|
2102
2963
|
const rootAttrs = [
|
|
2103
2964
|
attrString("ai.operationId", "generateText"),
|
|
2104
2965
|
attrString("ai.prompt", userInput),
|
|
2105
2966
|
attrString(
|
|
2106
2967
|
"ai.prompt.messages",
|
|
2107
|
-
buildPromptMessages(
|
|
2968
|
+
buildPromptMessages(state2.currentSystemPrompt, state2.currentInput)
|
|
2108
2969
|
),
|
|
2109
2970
|
attrString("ai.response.text", turnOutputText),
|
|
2110
2971
|
...buildLlmGenAiAttributes({ providerID, modelID, tokens: tokensObj })
|
|
@@ -2113,10 +2974,10 @@ type: ${name != null ? name : "UnknownError"}`;
|
|
|
2113
2974
|
rootAttrs.push(attrString("is_compaction", "true"));
|
|
2114
2975
|
}
|
|
2115
2976
|
rootAttrs.push(attrString("message_id", messageId));
|
|
2116
|
-
if (
|
|
2977
|
+
if (state2.currentSystemPrompt) {
|
|
2117
2978
|
rootAttrs.push(
|
|
2118
2979
|
attrString("gen_ai.prompt.0.role", "system"),
|
|
2119
|
-
attrString("gen_ai.prompt.0.content",
|
|
2980
|
+
attrString("gen_ai.prompt.0.content", state2.currentSystemPrompt)
|
|
2120
2981
|
);
|
|
2121
2982
|
}
|
|
2122
2983
|
traceShipper.endSpan(rootSpan, {
|
|
@@ -2124,24 +2985,24 @@ type: ${name != null ? name : "UnknownError"}`;
|
|
|
2124
2985
|
error: errorForSpan
|
|
2125
2986
|
});
|
|
2126
2987
|
if (isCompaction) {
|
|
2127
|
-
|
|
2988
|
+
state2.isCompacting = false;
|
|
2128
2989
|
}
|
|
2129
2990
|
}
|
|
2130
|
-
|
|
2991
|
+
state2.currentRootSpan = void 0;
|
|
2131
2992
|
const hasAssistantResponse = turnOutputText.trim().length > 0;
|
|
2132
2993
|
if (!hasAssistantResponse && !msgError) {
|
|
2133
2994
|
await traceShipper.flush();
|
|
2134
|
-
|
|
2995
|
+
state2.currentEventId = void 0;
|
|
2135
2996
|
return;
|
|
2136
2997
|
}
|
|
2137
|
-
if (!
|
|
2138
|
-
await eventShipper.finish(
|
|
2139
|
-
userId: (_d = (_c =
|
|
2998
|
+
if (!state2.parentId) {
|
|
2999
|
+
await eventShipper.finish(state2.currentEventId, {
|
|
3000
|
+
userId: (_d = (_c = state2.eventMetadata) == null ? void 0 : _c.userId) != null ? _d : state2.sessionId,
|
|
2140
3001
|
model: modelID,
|
|
2141
3002
|
output: msgError ? void 0 : turnOutputText,
|
|
2142
3003
|
usage: {
|
|
2143
3004
|
promptTokens: inputTokens,
|
|
2144
|
-
completionTokens:
|
|
3005
|
+
completionTokens: state2.turnOutputTokens
|
|
2145
3006
|
},
|
|
2146
3007
|
error: msgError ? {
|
|
2147
3008
|
name: msgError.name,
|
|
@@ -2156,35 +3017,35 @@ type: ${name != null ? name : "UnknownError"}`;
|
|
|
2156
3017
|
});
|
|
2157
3018
|
}
|
|
2158
3019
|
await traceShipper.flush();
|
|
2159
|
-
|
|
3020
|
+
state2.currentEventId = void 0;
|
|
2160
3021
|
} else if (event.type === "session.idle") {
|
|
2161
3022
|
if (!sessionID) return;
|
|
2162
|
-
const
|
|
2163
|
-
if (!
|
|
2164
|
-
if (
|
|
2165
|
-
traceShipper.endSpan(
|
|
2166
|
-
|
|
3023
|
+
const state2 = sessions.get(String(sessionID));
|
|
3024
|
+
if (!state2) return;
|
|
3025
|
+
if (state2.currentRootSpan) {
|
|
3026
|
+
traceShipper.endSpan(state2.currentRootSpan);
|
|
3027
|
+
state2.currentRootSpan = void 0;
|
|
2167
3028
|
}
|
|
2168
|
-
if (
|
|
2169
|
-
|
|
3029
|
+
if (state2.currentEventId) {
|
|
3030
|
+
state2.currentEventId = void 0;
|
|
2170
3031
|
}
|
|
2171
|
-
|
|
3032
|
+
state2.isCompacting = false;
|
|
2172
3033
|
await Promise.all([eventShipper.flush(), traceShipper.flush()]);
|
|
2173
|
-
if (
|
|
3034
|
+
if (state2.parentId) {
|
|
2174
3035
|
cleanupSessionParentMap(String(sessionID));
|
|
2175
3036
|
sessions.delete(String(sessionID));
|
|
2176
3037
|
} else {
|
|
2177
3038
|
}
|
|
2178
3039
|
} else if (event.type === "session.deleted") {
|
|
2179
3040
|
if (!sessionID) return;
|
|
2180
|
-
const
|
|
2181
|
-
if (!
|
|
2182
|
-
if (
|
|
2183
|
-
traceShipper.endSpan(
|
|
2184
|
-
|
|
3041
|
+
const state2 = sessions.get(String(sessionID));
|
|
3042
|
+
if (!state2) return;
|
|
3043
|
+
if (state2.currentRootSpan) {
|
|
3044
|
+
traceShipper.endSpan(state2.currentRootSpan);
|
|
3045
|
+
state2.currentRootSpan = void 0;
|
|
2185
3046
|
}
|
|
2186
|
-
if (
|
|
2187
|
-
|
|
3047
|
+
if (state2.currentEventId) {
|
|
3048
|
+
state2.currentEventId = void 0;
|
|
2188
3049
|
}
|
|
2189
3050
|
cleanupSessionParentMap(String(sessionID));
|
|
2190
3051
|
await Promise.all([eventShipper.flush(), traceShipper.flush()]);
|
|
@@ -2193,8 +3054,8 @@ type: ${name != null ? name : "UnknownError"}`;
|
|
|
2193
3054
|
const errorSessionID = (_h = props["sessionID"]) != null ? _h : sessionID;
|
|
2194
3055
|
if (errorSessionID === void 0 || errorSessionID === "")
|
|
2195
3056
|
throw new Error("session.error: missing sessionID");
|
|
2196
|
-
const
|
|
2197
|
-
if (!
|
|
3057
|
+
const state2 = sessions.get(String(errorSessionID));
|
|
3058
|
+
if (!state2) return;
|
|
2198
3059
|
const errorObj = props["error"];
|
|
2199
3060
|
if (errorObj == null) throw new Error("session.error: missing error object");
|
|
2200
3061
|
const errorName = errorObj.name;
|
|
@@ -2204,12 +3065,12 @@ type: ${name != null ? name : "UnknownError"}`;
|
|
|
2204
3065
|
const errorStr = `${errorMessage != null ? errorMessage : errorName}
|
|
2205
3066
|
|
|
2206
3067
|
type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
2207
|
-
if (
|
|
2208
|
-
traceShipper.endSpan(
|
|
2209
|
-
|
|
3068
|
+
if (state2.currentRootSpan) {
|
|
3069
|
+
traceShipper.endSpan(state2.currentRootSpan, { error: errorStr });
|
|
3070
|
+
state2.currentRootSpan = void 0;
|
|
2210
3071
|
}
|
|
2211
|
-
if (
|
|
2212
|
-
|
|
3072
|
+
if (state2.currentEventId) {
|
|
3073
|
+
state2.currentEventId = void 0;
|
|
2213
3074
|
}
|
|
2214
3075
|
cleanupSessionParentMap(String(errorSessionID));
|
|
2215
3076
|
await Promise.all([eventShipper.flush(), traceShipper.flush()]);
|
|
@@ -2229,15 +3090,15 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
2229
3090
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
2230
3091
|
try {
|
|
2231
3092
|
const { sessionID } = messageInput;
|
|
2232
|
-
let
|
|
2233
|
-
if (!
|
|
2234
|
-
|
|
2235
|
-
sessions.set(sessionID,
|
|
3093
|
+
let state2 = sessions.get(sessionID);
|
|
3094
|
+
if (!state2) {
|
|
3095
|
+
state2 = createSessionState(sessionID);
|
|
3096
|
+
sessions.set(sessionID, state2);
|
|
2236
3097
|
}
|
|
2237
3098
|
applyChildSessionParentToState(sessionID);
|
|
2238
|
-
if (
|
|
2239
|
-
traceShipper.endSpan(
|
|
2240
|
-
|
|
3099
|
+
if (state2.currentRootSpan) {
|
|
3100
|
+
traceShipper.endSpan(state2.currentRootSpan);
|
|
3101
|
+
state2.currentRootSpan = void 0;
|
|
2241
3102
|
}
|
|
2242
3103
|
if (output == null) throw new Error("chat.message: output is required");
|
|
2243
3104
|
const parts = output.parts;
|
|
@@ -2268,39 +3129,39 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
2268
3129
|
}
|
|
2269
3130
|
}
|
|
2270
3131
|
}
|
|
2271
|
-
|
|
3132
|
+
state2.eventMetadata = {
|
|
2272
3133
|
...baseMeta,
|
|
2273
3134
|
...promptMeta,
|
|
2274
3135
|
properties: baseMeta.properties || promptMeta.properties ? { ...(_a = baseMeta.properties) != null ? _a : {}, ...(_b = promptMeta.properties) != null ? _b : {} } : void 0
|
|
2275
3136
|
};
|
|
2276
3137
|
const userText = capText2(textParts.join("\n"));
|
|
2277
|
-
|
|
2278
|
-
|
|
2279
|
-
|
|
2280
|
-
if (
|
|
2281
|
-
if (!
|
|
3138
|
+
state2.currentInput = userText;
|
|
3139
|
+
state2.turnOutputParts = [];
|
|
3140
|
+
state2.turnOutputTokens = 0;
|
|
3141
|
+
if (state2.parentId) {
|
|
3142
|
+
if (!state2.parentTaskSpanIds || !state2.parentEventContext) {
|
|
2282
3143
|
return;
|
|
2283
3144
|
}
|
|
2284
|
-
|
|
2285
|
-
|
|
3145
|
+
state2.currentEventId = state2.parentEventContext.eventId;
|
|
3146
|
+
state2.currentRootSpan = traceShipper.startSpan({
|
|
2286
3147
|
name: "Subagent",
|
|
2287
|
-
parent:
|
|
2288
|
-
eventId:
|
|
3148
|
+
parent: state2.parentTaskSpanIds,
|
|
3149
|
+
eventId: state2.currentEventId,
|
|
2289
3150
|
attributes: [
|
|
2290
3151
|
attrString("workspace", worktree),
|
|
2291
3152
|
attrString("directory", directory),
|
|
2292
3153
|
attrString("hostname", hostname),
|
|
2293
3154
|
attrString("os", os),
|
|
2294
3155
|
attrString("is_subagent", "true"),
|
|
2295
|
-
attrString("parent_session_id",
|
|
3156
|
+
attrString("parent_session_id", state2.parentId)
|
|
2296
3157
|
]
|
|
2297
3158
|
});
|
|
2298
3159
|
return;
|
|
2299
3160
|
}
|
|
2300
|
-
|
|
2301
|
-
|
|
2302
|
-
name:
|
|
2303
|
-
eventId:
|
|
3161
|
+
state2.currentEventId = generateId();
|
|
3162
|
+
state2.currentRootSpan = traceShipper.startSpan({
|
|
3163
|
+
name: state2.isCompacting ? "ai.compaction" : "ai.event",
|
|
3164
|
+
eventId: state2.currentEventId,
|
|
2304
3165
|
attributes: [
|
|
2305
3166
|
attrString("workspace", worktree),
|
|
2306
3167
|
attrString("directory", directory),
|
|
@@ -2308,11 +3169,11 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
2308
3169
|
attrString("os", os)
|
|
2309
3170
|
]
|
|
2310
3171
|
});
|
|
2311
|
-
await eventShipper.patch(
|
|
3172
|
+
await eventShipper.patch(state2.currentEventId, {
|
|
2312
3173
|
isPending: true,
|
|
2313
|
-
userId: (_d = (_c =
|
|
2314
|
-
convoId:
|
|
2315
|
-
eventName: (_f = (_e =
|
|
3174
|
+
userId: (_d = (_c = state2.eventMetadata) == null ? void 0 : _c.userId) != null ? _d : state2.sessionId,
|
|
3175
|
+
convoId: state2.sessionId,
|
|
3176
|
+
eventName: (_f = (_e = state2.eventMetadata) == null ? void 0 : _e.eventName) != null ? _f : config.eventName,
|
|
2316
3177
|
input: userText,
|
|
2317
3178
|
...newAttachments.length > 0 ? { attachments: newAttachments } : {},
|
|
2318
3179
|
properties: {
|
|
@@ -2321,7 +3182,7 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
2321
3182
|
hostname,
|
|
2322
3183
|
os,
|
|
2323
3184
|
plugin_version: PLUGIN_VERSION,
|
|
2324
|
-
...(_g =
|
|
3185
|
+
...(_g = state2.eventMetadata) == null ? void 0 : _g.properties
|
|
2325
3186
|
}
|
|
2326
3187
|
});
|
|
2327
3188
|
} catch (err) {
|
|
@@ -2335,16 +3196,16 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
2335
3196
|
var _a, _b, _c;
|
|
2336
3197
|
try {
|
|
2337
3198
|
const { tool, sessionID, callID } = toolInput;
|
|
2338
|
-
const
|
|
2339
|
-
if (!
|
|
2340
|
-
const spanParent =
|
|
3199
|
+
const state2 = sessions.get(sessionID);
|
|
3200
|
+
if (!state2 || !state2.currentEventId) return;
|
|
3201
|
+
const spanParent = state2.parentId && state2.parentTaskSpanIds ? state2.parentTaskSpanIds : (_a = state2.currentRootSpan) == null ? void 0 : _a.ids;
|
|
2341
3202
|
if (!spanParent) return;
|
|
2342
3203
|
const startTimeUnixNano = nowUnixNanoString();
|
|
2343
3204
|
if (tool === "task") {
|
|
2344
3205
|
const liveTaskSpan = traceShipper.startSpan({
|
|
2345
3206
|
name: "ai.toolCall",
|
|
2346
3207
|
parent: spanParent,
|
|
2347
|
-
eventId:
|
|
3208
|
+
eventId: state2.currentEventId,
|
|
2348
3209
|
attributes: [
|
|
2349
3210
|
attrString("ai.operationId", "ai.toolCall"),
|
|
2350
3211
|
attrString("ai.toolCall.name", tool),
|
|
@@ -2355,9 +3216,9 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
2355
3216
|
const ctx = {
|
|
2356
3217
|
ids: liveTaskSpan.ids,
|
|
2357
3218
|
eventContext: {
|
|
2358
|
-
eventId:
|
|
2359
|
-
userId: (_c = (_b =
|
|
2360
|
-
convoId:
|
|
3219
|
+
eventId: state2.currentEventId,
|
|
3220
|
+
userId: (_c = (_b = state2.eventMetadata) == null ? void 0 : _b.userId) != null ? _c : state2.sessionId,
|
|
3221
|
+
convoId: state2.sessionId
|
|
2361
3222
|
}
|
|
2362
3223
|
};
|
|
2363
3224
|
taskContexts.set(callKey(sessionID, callID), ctx);
|
|
@@ -2368,18 +3229,18 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
2368
3229
|
}
|
|
2369
3230
|
running.add(callID);
|
|
2370
3231
|
resolvePendingChildrenForCall(sessionID, callID, "tool.execute.before");
|
|
2371
|
-
|
|
3232
|
+
state2.toolSpanStarts.set(callID, {
|
|
2372
3233
|
startTimeUnixNano,
|
|
2373
3234
|
parent: spanParent,
|
|
2374
|
-
eventId:
|
|
3235
|
+
eventId: state2.currentEventId,
|
|
2375
3236
|
name: tool,
|
|
2376
3237
|
liveSpan: liveTaskSpan
|
|
2377
3238
|
});
|
|
2378
3239
|
} else {
|
|
2379
|
-
|
|
3240
|
+
state2.toolSpanStarts.set(callID, {
|
|
2380
3241
|
startTimeUnixNano,
|
|
2381
3242
|
parent: spanParent,
|
|
2382
|
-
eventId:
|
|
3243
|
+
eventId: state2.currentEventId,
|
|
2383
3244
|
name: tool
|
|
2384
3245
|
});
|
|
2385
3246
|
}
|
|
@@ -2396,13 +3257,13 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
2396
3257
|
"tool.execute.after": async (toolInput, result) => {
|
|
2397
3258
|
try {
|
|
2398
3259
|
const { tool, sessionID, callID, args } = toolInput;
|
|
2399
|
-
const
|
|
2400
|
-
if (!
|
|
3260
|
+
const state2 = sessions.get(sessionID);
|
|
3261
|
+
if (!state2 || !state2.currentEventId) return;
|
|
2401
3262
|
if (args === void 0 || args === null)
|
|
2402
3263
|
throw new Error("tool.execute.after: args is required");
|
|
2403
3264
|
const toolCallArgs = typeof args === "string" ? capText2(args) : boundedStringify(args);
|
|
2404
|
-
const startInfo =
|
|
2405
|
-
|
|
3265
|
+
const startInfo = state2.toolSpanStarts.get(callID);
|
|
3266
|
+
state2.toolSpanStarts.delete(callID);
|
|
2406
3267
|
const resultMetadata = result.metadata;
|
|
2407
3268
|
const childSessionId = resultMetadata == null ? void 0 : resultMetadata["sessionId"];
|
|
2408
3269
|
if (tool === "task" && childSessionId) {
|
|
@@ -2455,9 +3316,9 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
2455
3316
|
try {
|
|
2456
3317
|
const sessionID = input.sessionID;
|
|
2457
3318
|
if (!sessionID) return;
|
|
2458
|
-
const
|
|
2459
|
-
if (
|
|
2460
|
-
|
|
3319
|
+
const state2 = sessions.get(sessionID);
|
|
3320
|
+
if (state2) {
|
|
3321
|
+
state2.isCompacting = true;
|
|
2461
3322
|
}
|
|
2462
3323
|
} catch (err) {
|
|
2463
3324
|
rateLimitedErrorLog(
|
|
@@ -2474,15 +3335,15 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
2474
3335
|
if (!config.captureSystemPrompt) return;
|
|
2475
3336
|
const sessionID = input.sessionID;
|
|
2476
3337
|
if (!sessionID) return;
|
|
2477
|
-
let
|
|
2478
|
-
if (!
|
|
2479
|
-
|
|
2480
|
-
sessions.set(sessionID,
|
|
3338
|
+
let state2 = sessions.get(sessionID);
|
|
3339
|
+
if (!state2) {
|
|
3340
|
+
state2 = createSessionState(sessionID);
|
|
3341
|
+
sessions.set(sessionID, state2);
|
|
2481
3342
|
}
|
|
2482
3343
|
const MAX_SYSTEM_PROMPT_LENGTH = 32768;
|
|
2483
3344
|
const TRUNCATION_MARKER3 = "\n...[truncated]";
|
|
2484
3345
|
const joined = output.system.join("\n\n");
|
|
2485
|
-
|
|
3346
|
+
state2.currentSystemPrompt = joined.length > MAX_SYSTEM_PROMPT_LENGTH ? joined.slice(0, MAX_SYSTEM_PROMPT_LENGTH - TRUNCATION_MARKER3.length) + TRUNCATION_MARKER3 : joined;
|
|
2486
3347
|
} catch (err) {
|
|
2487
3348
|
rateLimitedErrorLog(
|
|
2488
3349
|
"experimental.chat.system.transform",
|
|
@@ -2494,7 +3355,7 @@ type: ${errorName != null ? errorName : "UnknownError"}`;
|
|
|
2494
3355
|
}
|
|
2495
3356
|
|
|
2496
3357
|
// src/index.ts
|
|
2497
|
-
function createRaindropHandle(eventShipper, traceShipper) {
|
|
3358
|
+
function createRaindropHandle(eventShipper, traceShipper, appGitContext) {
|
|
2498
3359
|
return {
|
|
2499
3360
|
users: {
|
|
2500
3361
|
async identify(users) {
|
|
@@ -2505,12 +3366,19 @@ function createRaindropHandle(eventShipper, traceShipper) {
|
|
|
2505
3366
|
await Promise.all([eventShipper.flush(), traceShipper.flush()]);
|
|
2506
3367
|
},
|
|
2507
3368
|
async shutdown() {
|
|
2508
|
-
|
|
3369
|
+
try {
|
|
3370
|
+
await Promise.all([eventShipper.shutdown(), traceShipper.shutdown()]);
|
|
3371
|
+
} finally {
|
|
3372
|
+
try {
|
|
3373
|
+
appGitContext.dispose();
|
|
3374
|
+
} catch (e) {
|
|
3375
|
+
}
|
|
3376
|
+
}
|
|
2509
3377
|
}
|
|
2510
3378
|
};
|
|
2511
3379
|
}
|
|
2512
|
-
async function plugin(input) {
|
|
2513
|
-
var _a;
|
|
3380
|
+
async function plugin(input, opts = {}) {
|
|
3381
|
+
var _a, _b, _c;
|
|
2514
3382
|
const config = loadConfig(input.directory);
|
|
2515
3383
|
function appLog(level, message) {
|
|
2516
3384
|
console.log(`[raindrop-ai/opencode-plugin] [${level}] ${message}`);
|
|
@@ -2532,21 +3400,28 @@ async function plugin(input) {
|
|
|
2532
3400
|
].filter(Boolean);
|
|
2533
3401
|
appLog("info", `Raindrop tracing enabled \u2014 destinations: ${destinations.join(", ")}`);
|
|
2534
3402
|
}
|
|
2535
|
-
const
|
|
3403
|
+
const configuredAppGit = (_a = opts.appGit) != null ? _a : config.appGit;
|
|
3404
|
+
const appGitContext = createAppGitContext2(
|
|
3405
|
+
((_b = config.writeKey) == null ? void 0 : _b.trim()) || hasLocalDestination ? configuredAppGit : false,
|
|
3406
|
+
{ allowLocalGit: false }
|
|
3407
|
+
);
|
|
3408
|
+
const eventShipper = new EventShipper3({
|
|
2536
3409
|
writeKey: config.writeKey,
|
|
2537
3410
|
endpoint: config.endpoint,
|
|
2538
3411
|
debug: config.debug,
|
|
2539
3412
|
projectId: config.projectId,
|
|
2540
|
-
localDebuggerUrl: config.localWorkshopUrl
|
|
3413
|
+
localDebuggerUrl: config.localWorkshopUrl,
|
|
3414
|
+
appGitContext
|
|
2541
3415
|
});
|
|
2542
|
-
const traceShipper = new
|
|
3416
|
+
const traceShipper = new TraceShipper3({
|
|
2543
3417
|
writeKey: config.writeKey,
|
|
2544
3418
|
endpoint: config.endpoint,
|
|
2545
3419
|
debug: config.debug,
|
|
2546
3420
|
projectId: config.projectId,
|
|
2547
|
-
localDebuggerUrl: config.localWorkshopUrl
|
|
3421
|
+
localDebuggerUrl: config.localWorkshopUrl,
|
|
3422
|
+
appGitContext
|
|
2548
3423
|
});
|
|
2549
|
-
const worktree = (
|
|
3424
|
+
const worktree = (_c = input.worktree) != null ? _c : input.directory;
|
|
2550
3425
|
const hooks = createHooks(
|
|
2551
3426
|
config,
|
|
2552
3427
|
worktree,
|
|
@@ -2554,7 +3429,7 @@ async function plugin(input) {
|
|
|
2554
3429
|
eventShipper,
|
|
2555
3430
|
traceShipper
|
|
2556
3431
|
);
|
|
2557
|
-
return { ...hooks, raindrop: createRaindropHandle(eventShipper, traceShipper) };
|
|
3432
|
+
return { ...hooks, raindrop: createRaindropHandle(eventShipper, traceShipper, appGitContext) };
|
|
2558
3433
|
}
|
|
2559
3434
|
export {
|
|
2560
3435
|
plugin as default
|