@lmnr-ai/lmnr 0.8.21 → 0.8.22-alpha.1

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.
@@ -1,5 +1,5 @@
1
1
  import { r as __require } from "./chunk-BEJ448es.mjs";
2
- import { n as version, t as LaminarClient } from "./dist-B5CmOQ4s.mjs";
2
+ import { n as version, t as LaminarClient } from "./dist-TLHkfisO.mjs";
3
3
  import { A as SPAN_OUTPUT, C as PARENT_SPAN_PATH, D as SPAN_INPUT, E as SPAN_IDS_PATH, F as TRACE_TYPE, I as USER_ID, M as SPAN_SDK_VERSION, N as SPAN_TYPE, O as SPAN_INSTRUMENTATION_SOURCE, P as TRACE_HAS_BROWSER_SESSION, S as PARENT_SPAN_IDS_PATH, T as SESSION_ID, _ as validateTracingConfig, c as loadEnv, g as tryToOtelSpanContext, h as parseOtelHeaders, j as SPAN_PATH, k as SPAN_LANGUAGE_VERSION, l as metadataToAttributes, m as otelTraceIdToUUID, o as getOtelEnvVar, p as otelSpanIdToUUID, r as deserializeLaminarSpanContext, s as initializeLogger, t as NIL_UUID, u as newUUID, v as ASSOCIATION_PROPERTIES, w as ROLLOUT_SESSION_ID, x as LaminarAttributes, y as ASSOCIATION_PROPERTIES_OVERRIDES } from "./utils-CHJ0KZUR.mjs";
4
4
  import { DiagConsoleLogger, DiagLogLevel, ROOT_CONTEXT, SpanStatusCode, context, createContextKey, diag, isSpanContextValid, trace } from "@opentelemetry/api";
5
5
  import { AsyncLocalStorageContextManager } from "@opentelemetry/context-async-hooks";
@@ -2170,7 +2170,7 @@ const injectScript = (sessionRecordingOptions, stringifyCallbackArgs) => {
2170
2170
  };
2171
2171
  if (!window.lmnrStartedRecordingEvents) {
2172
2172
  setInterval(sendBatchIfReady, BATCH_TIMEOUT);
2173
- window.lmnrRrweb.record({
2173
+ const recordOptions = {
2174
2174
  emit(event) {
2175
2175
  window.lmnrRrwebEventsBatch.push(event);
2176
2176
  },
@@ -2186,12 +2186,17 @@ const injectScript = (sessionRecordingOptions, stringifyCallbackArgs) => {
2186
2186
  email: sessionRecordingOptions?.maskInputOptions?.email || false,
2187
2187
  tel: sessionRecordingOptions?.maskInputOptions?.tel || false
2188
2188
  }
2189
- });
2189
+ };
2190
+ window.lmnrRrweb.record(recordOptions);
2190
2191
  setInterval(() => {
2191
- window.lmnrRrweb.record.addCustomEvent("heartbeat", {
2192
- title: document.title,
2193
- url: document.URL
2194
- });
2192
+ try {
2193
+ window.lmnrRrweb.record.addCustomEvent("heartbeat", {
2194
+ title: document.title,
2195
+ url: document.URL
2196
+ });
2197
+ } catch {
2198
+ window.lmnrRrweb.record(recordOptions);
2199
+ }
2195
2200
  }, HEARTBEAT_INTERVAL);
2196
2201
  window.lmnrStartedRecordingEvents = true;
2197
2202
  }
@@ -3114,6 +3119,29 @@ function createTargetInfoChangedHandler(context, state, sessionRecordingOptions)
3114
3119
  }
3115
3120
  //#endregion
3116
3121
  //#region src/browser/stagehand/v3/instrumentation.ts
3122
+ /**
3123
+ * Guarded _wrap: only wraps `target[methodName]` if it exists as a function.
3124
+ * Prevents the "Cannot wrap non-existent method" warning from
3125
+ * InstrumentationBase._wrap when a handler/method was renamed or removed
3126
+ * in the upstream library (e.g. Stagehand v2 vs v3 differences).
3127
+ */
3128
+ const safeWrap = (instrumentation, target, methodName, wrapper) => {
3129
+ if (!target) return false;
3130
+ if (typeof target[methodName] !== "function") return false;
3131
+ instrumentation._wrap(target, methodName, wrapper);
3132
+ return true;
3133
+ };
3134
+ /**
3135
+ * Guarded _unwrap counterpart to safeWrap. Only unwraps when the target method
3136
+ * exists AND was previously wrapped via shimmer (has the `__original` marker).
3137
+ */
3138
+ const safeUnwrap = (instrumentation, target, methodName) => {
3139
+ if (!target) return;
3140
+ const current = target[methodName];
3141
+ if (typeof current !== "function") return;
3142
+ if (!current.__original) return;
3143
+ instrumentation._unwrap(target, methodName);
3144
+ };
3117
3145
  var StagehandInstrumentation = class extends InstrumentationBase {
3118
3146
  constructor(sessionRecordingOptions) {
3119
3147
  super("@lmnr/browserbase-stagehand-instrumentation", version, { enabled: true });
@@ -3165,21 +3193,28 @@ var StagehandInstrumentation = class extends InstrumentationBase {
3165
3193
  }
3166
3194
  unpatch(moduleExports, moduleVersion) {
3167
3195
  diag.debug(`unpatching stagehand ${moduleVersion}`);
3168
- this._unwrap(moduleExports, "Stagehand");
3196
+ safeUnwrap(this, moduleExports, "Stagehand");
3169
3197
  if (moduleExports.Stagehand && moduleExports.Stagehand.prototype) {
3170
- this._unwrap(moduleExports.Stagehand.prototype, "init");
3171
- this._unwrap(moduleExports.Stagehand.prototype, "close");
3172
- this._unwrap(moduleExports.Stagehand.prototype, "act");
3173
- this._unwrap(moduleExports.Stagehand.prototype, "extract");
3174
- this._unwrap(moduleExports.Stagehand.prototype, "observe");
3175
3198
  const prototype = moduleExports.Stagehand.prototype;
3199
+ safeUnwrap(this, prototype, "init");
3200
+ safeUnwrap(this, prototype, "close");
3201
+ safeUnwrap(this, prototype, "act");
3202
+ safeUnwrap(this, prototype, "extract");
3203
+ safeUnwrap(this, prototype, "observe");
3204
+ safeUnwrap(this, prototype, "agent");
3176
3205
  if (prototype.actHandler) {
3177
- this._unwrap(prototype.actHandler, "act");
3178
- this._unwrap(prototype.actHandler, "actFromObserveResult");
3206
+ safeUnwrap(this, prototype.actHandler, "act");
3207
+ safeUnwrap(this, prototype.actHandler, "actFromObserveResult");
3208
+ }
3209
+ if (prototype.extractHandler) safeUnwrap(this, prototype.extractHandler, "extract");
3210
+ if (prototype.observeHandler) safeUnwrap(this, prototype.observeHandler, "observe");
3211
+ if (prototype.llmClient) safeUnwrap(this, prototype.llmClient, "createChatCompletion");
3212
+ if (prototype.apiClient) {
3213
+ safeUnwrap(this, prototype.apiClient, "act");
3214
+ safeUnwrap(this, prototype.apiClient, "extract");
3215
+ safeUnwrap(this, prototype.apiClient, "observe");
3216
+ safeUnwrap(this, prototype.apiClient, "agentExecute");
3179
3217
  }
3180
- if (prototype.extractHandler) this._unwrap(prototype.extractHandler, "extract");
3181
- if (prototype.observeHandler) this._unwrap(prototype.observeHandler, "observe");
3182
- if (prototype.llmClient) this._unwrap(prototype.llmClient, "createChatCompletion");
3183
3218
  }
3184
3219
  return moduleExports;
3185
3220
  }
@@ -3211,9 +3246,9 @@ var StagehandInstrumentation = class extends InstrumentationBase {
3211
3246
  const otelTraceId = parentSpan.spanContext().traceId;
3212
3247
  const traceId = otelTraceIdToUUID(otelTraceId);
3213
3248
  const result = await original.bind(this).apply(this);
3214
- instrumentation._wrap(this, "act", instrumentation.patchStagehandGlobalMethod("act", sessionId, parentSpan));
3215
- instrumentation._wrap(this, "extract", instrumentation.patchStagehandGlobalMethod("extract", sessionId, parentSpan));
3216
- instrumentation._wrap(this, "observe", instrumentation.patchStagehandGlobalMethod("observe", sessionId, parentSpan));
3249
+ safeWrap(instrumentation, this, "act", instrumentation.patchStagehandGlobalMethod("act", sessionId, parentSpan));
3250
+ safeWrap(instrumentation, this, "extract", instrumentation.patchStagehandGlobalMethod("extract", sessionId, parentSpan));
3251
+ safeWrap(instrumentation, this, "observe", instrumentation.patchStagehandGlobalMethod("observe", sessionId, parentSpan));
3217
3252
  if (this.actHandler) instrumentation.patchActHandler(this.actHandler);
3218
3253
  if (this.extractHandler) instrumentation.patchExtractHandler(this.extractHandler);
3219
3254
  if (this.observeHandler) instrumentation.patchObserveHandler(this.observeHandler);
@@ -3222,9 +3257,10 @@ var StagehandInstrumentation = class extends InstrumentationBase {
3222
3257
  provider: this.llmClient.type,
3223
3258
  model: this.llmClient.modelName
3224
3259
  });
3225
- instrumentation._wrap(this.llmClient, "createChatCompletion", instrumentation.patchStagehandLLMClientCreateChatCompletion());
3260
+ safeWrap(instrumentation, this.llmClient, "createChatCompletion", instrumentation.patchStagehandLLMClientCreateChatCompletion());
3226
3261
  }
3227
- instrumentation._wrap(this, "agent", instrumentation.patchStagehandAgentInitializer(sessionId, parentSpan));
3262
+ if (this.apiClient) instrumentation.patchStagehandApiClient(this.apiClient, sessionId, parentSpan, this);
3263
+ safeWrap(instrumentation, this, "agent", instrumentation.patchStagehandAgentInitializer(sessionId, parentSpan));
3228
3264
  if (instrumentation._client) await instrumentation.setupSessionRecording(this, sessionId, traceId);
3229
3265
  if (this.context && this.context.pages) for (const page of this.context.pages()) instrumentation.patchStagehandPage(page, parentSpan);
3230
3266
  if (this.context && this.context.on) this.context.on("page", (page) => {
@@ -3359,8 +3395,8 @@ var StagehandInstrumentation = class extends InstrumentationBase {
3359
3395
  };
3360
3396
  }
3361
3397
  patchActHandler(actHandler) {
3362
- this._wrap(actHandler, "act", this.patchActHandlerAct());
3363
- this._wrap(actHandler, "actFromObserveResult", this.patchActHandlerActFromObserveResult());
3398
+ safeWrap(this, actHandler, "act", this.patchActHandlerAct());
3399
+ safeWrap(this, actHandler, "actFromObserveResult", this.patchActHandlerActFromObserveResult());
3364
3400
  }
3365
3401
  patchActHandlerAct() {
3366
3402
  return (original) => async function act(...args) {
@@ -3389,7 +3425,7 @@ var StagehandInstrumentation = class extends InstrumentationBase {
3389
3425
  };
3390
3426
  }
3391
3427
  patchExtractHandler(extractHandler) {
3392
- this._wrap(extractHandler, "extract", this.patchExtractHandlerExtract());
3428
+ safeWrap(this, extractHandler, "extract", this.patchExtractHandlerExtract());
3393
3429
  }
3394
3430
  patchExtractHandlerExtract() {
3395
3431
  return (original) => async function extract(...args) {
@@ -3413,7 +3449,7 @@ var StagehandInstrumentation = class extends InstrumentationBase {
3413
3449
  };
3414
3450
  }
3415
3451
  patchObserveHandler(observeHandler) {
3416
- this._wrap(observeHandler, "observe", this.patchObserveHandlerObserve());
3452
+ safeWrap(this, observeHandler, "observe", this.patchObserveHandlerObserve());
3417
3453
  }
3418
3454
  patchObserveHandlerObserve() {
3419
3455
  return (original) => async function observe$1(...args) {
@@ -3441,7 +3477,7 @@ var StagehandInstrumentation = class extends InstrumentationBase {
3441
3477
  };
3442
3478
  }
3443
3479
  patchStagehandAgent(agent, sessionId, parentSpan) {
3444
- this._wrap(agent, "execute", this.patchStagehandAgentExecute(sessionId, parentSpan));
3480
+ safeWrap(this, agent, "execute", this.patchStagehandAgentExecute(sessionId, parentSpan));
3445
3481
  this.wrapAgentMethod(agent, "captureScreenshot", parentSpan, {
3446
3482
  spanType: "TOOL",
3447
3483
  ignoreOutput: true
@@ -3508,8 +3544,7 @@ var StagehandInstrumentation = class extends InstrumentationBase {
3508
3544
  };
3509
3545
  }
3510
3546
  wrapAgentMethod(agent, methodName, parentSpan, options) {
3511
- if (typeof agent[methodName] !== "function") return;
3512
- this._wrap(agent, methodName, (original) => async function method(...args) {
3547
+ safeWrap(this, agent, methodName, (original) => async function method(...args) {
3513
3548
  const currentSpan = trace.getSpan(LaminarContextManager.getContext()) ?? trace.getActiveSpan();
3514
3549
  return await Laminar.withSpan(currentSpan ?? parentSpan, async () => await observe({
3515
3550
  name: `stagehand.agent.${methodName}`,
@@ -3531,13 +3566,77 @@ var StagehandInstrumentation = class extends InstrumentationBase {
3531
3566
  "keyPress",
3532
3567
  "keyDown",
3533
3568
  "keyUp"
3534
- ]) {
3535
- if (typeof page[methodName] !== "function") continue;
3536
- this._wrap(page, methodName, (original) => async function method(...args) {
3569
+ ]) safeWrap(this, page, methodName, (original) => async function method(...args) {
3570
+ const currentSpan = trace.getSpan(LaminarContextManager.getContext()) ?? trace.getActiveSpan();
3571
+ return await Laminar.withSpan(currentSpan ?? parentSpan, async () => await observe({ name: `stagehand.page.${methodName}` }, async (argVals) => await original.bind(this).apply(this, argVals), args));
3572
+ });
3573
+ }
3574
+ /**
3575
+ * In BROWSERBASE remote mode Stagehand's top-level `act`/`extract`/`observe`/
3576
+ * agent `execute` are routed through an internal `StagehandAPIClient` which
3577
+ * makes HTTP calls to the Stagehand Cloud API. The local `llmClient` and the
3578
+ * local `actHandler`/`extractHandler`/`observeHandler` are therefore never
3579
+ * invoked and our existing wrappers do not fire.
3580
+ *
3581
+ * Wrap the apiClient methods directly so we still emit child spans for the
3582
+ * LLM-backed calls and surface token usage from the response where available.
3583
+ */
3584
+ patchStagehandApiClient(apiClient, _sessionId, parentSpan, stagehandInstance) {
3585
+ const instrumentation = this;
3586
+ const baseProvider = stagehandInstance?.llmClient?.type;
3587
+ const baseModel = stagehandInstance?.llmClient?.modelName;
3588
+ const wrapApiMethod = (methodName) => {
3589
+ safeWrap(instrumentation, apiClient, methodName, (original) => async function method(...args) {
3537
3590
  const currentSpan = trace.getSpan(LaminarContextManager.getContext()) ?? trace.getActiveSpan();
3538
- return await Laminar.withSpan(currentSpan ?? parentSpan, async () => await observe({ name: `stagehand.page.${methodName}` }, async (argVals) => await original.bind(this).apply(this, argVals), args));
3591
+ const input = nameArgsOrCopy(args);
3592
+ const spanName = methodName === "agentExecute" ? "stagehand.apiClient.agentExecute" : `stagehand.apiClient.${methodName}`;
3593
+ return await Laminar.withSpan(currentSpan ?? parentSpan, async () => await observe({
3594
+ name: spanName,
3595
+ input,
3596
+ spanType: "LLM",
3597
+ ignoreInput: true,
3598
+ ignoreOutput: true
3599
+ }, async () => {
3600
+ const span = trace.getSpan(LaminarContextManager.getContext()) ?? trace.getActiveSpan();
3601
+ span?.setAttribute(TRACE_HAS_BROWSER_SESSION, true);
3602
+ if (baseProvider) span?.setAttribute("gen_ai.system", baseProvider);
3603
+ if (baseModel) span?.setAttribute("gen_ai.request.model", baseModel);
3604
+ try {
3605
+ const firstArg = args[0];
3606
+ const instruction = typeof firstArg === "string" ? firstArg : firstArg?.input ?? firstArg?.instruction;
3607
+ if (typeof instruction === "string" && instruction.length > 0) span?.setAttributes({
3608
+ "gen_ai.prompt.0.role": "user",
3609
+ "gen_ai.prompt.0.content": instruction
3610
+ });
3611
+ } catch {}
3612
+ const result = await original.bind(this).apply(this, args);
3613
+ try {
3614
+ const usage = result?.usage;
3615
+ if (usage) {
3616
+ const inputTokens = usage.input_tokens ?? usage.prompt_tokens ?? 0;
3617
+ const outputTokens = usage.output_tokens ?? usage.completion_tokens ?? 0;
3618
+ span?.setAttributes({
3619
+ "gen_ai.usage.input_tokens": inputTokens,
3620
+ "gen_ai.usage.output_tokens": outputTokens,
3621
+ "llm.usage.total_tokens": inputTokens + outputTokens
3622
+ });
3623
+ }
3624
+ if (methodName === "agentExecute") {
3625
+ const message = result?.message;
3626
+ if (message) span?.setAttributes({
3627
+ "gen_ai.completion.0.role": "assistant",
3628
+ "gen_ai.completion.0.content": typeof message === "string" ? message : JSON.stringify(message)
3629
+ });
3630
+ }
3631
+ } catch {}
3632
+ return result;
3633
+ }));
3539
3634
  });
3540
- }
3635
+ };
3636
+ wrapApiMethod("act");
3637
+ wrapApiMethod("extract");
3638
+ wrapApiMethod("observe");
3639
+ wrapApiMethod("agentExecute");
3541
3640
  }
3542
3641
  };
3543
3642
  //#endregion
@@ -5778,4 +5877,4 @@ function observeExperimentalDecorator(config) {
5778
5877
  //#endregion
5779
5878
  export { getSpanProcessor as a, LaminarSpanProcessor as c, Laminar as d, instrumentClaudeAgentQuery as f, stringifyPromptForTelemetry as g, consumeStreamResult as h, withTracingLevel as i, getLangVersion as l, TracingLevel as m, observeDecorator as n, getTracer as o, LaminarContextManager as p, observeExperimentalDecorator as r, getTracerProvider as s, observe as t, initializeLaminarInstrumentations as u };
5780
5879
 
5781
- //# sourceMappingURL=decorators-BDFgXfgI.mjs.map
5880
+ //# sourceMappingURL=decorators-Bq6Sf8vt.mjs.map