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