@dev-blinq/bvt-playwright-js 1.0.0-dev.2 → 1.0.0-dev.3

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.
Files changed (4) hide show
  1. package/index.d.mts +351 -167
  2. package/index.mjs +2298 -484
  3. package/index.mjs.map +1 -1
  4. package/package.json +1 -1
package/index.mjs CHANGED
@@ -276,6 +276,20 @@ var TestDataApi = class {
276
276
  this.options.onChange?.();
277
277
  }
278
278
  /**
279
+ * Shorthand for {@link setRuntime}. Saves a value to the current session's
280
+ * runtime scope, resolvable as `{{key}}` in subsequent steps.
281
+ */
282
+ async set(key, value, opts = {}) {
283
+ return this.setRuntime(key, value, opts);
284
+ }
285
+ /**
286
+ * Shorthand for {@link getRuntime}. Reads a value from the current session's
287
+ * runtime scope. Returns `null` if no entry exists for `key`.
288
+ */
289
+ async get(key) {
290
+ return this.getRuntime(key);
291
+ }
292
+ /**
279
293
  * Read a runtime value previously saved via setRuntime or an extract step.
280
294
  *
281
295
  * Returns `null` if no entry exists for `key` in the current runtime scope.
@@ -6014,6 +6028,14 @@ const CommandSchema = discriminatedUnion("type", [
6014
6028
  data: unknown().optional(),
6015
6029
  config: CommandConfigSchema.optional()
6016
6030
  }).strict(),
6031
+ object({
6032
+ _id: EntityIdSchema,
6033
+ type: literal$1("custom.code"),
6034
+ runtime: literal$1("secure-exec-v1").default("secure-exec-v1"),
6035
+ language: literal$1("javascript").default("javascript"),
6036
+ code: string().min(1).max(5e4),
6037
+ config: CommandConfigSchema.optional()
6038
+ }).strict(),
6017
6039
  object({
6018
6040
  _id: EntityIdSchema,
6019
6041
  type: literal$1("api.action"),
@@ -6032,7 +6054,7 @@ const CommandSchema = discriminatedUnion("type", [
6032
6054
  //#region ../../core/schemas/src/scenario/scenario.schema.ts
6033
6055
  const TagSchema = object({
6034
6056
  _id: EntityIdSchema,
6035
- name: string().min(1).max(100),
6057
+ name: string().min(1).max(50).regex(/^[a-z0-9_-]+$/, "Tag name can only contain lowercase letters, numbers, hyphens, and underscores"),
6036
6058
  projectId: EntityIdSchema
6037
6059
  }).strict();
6038
6060
  const RecorderModes = [
@@ -6437,14 +6459,14 @@ const BrowserObserverStateKSchema = union([_enum([
6437
6459
 
6438
6460
  //#endregion
6439
6461
  //#region ../../node_modules/xstate/dev/dist/xstate-dev.esm.js
6440
- function getGlobal() {
6462
+ function getGlobal$1() {
6441
6463
  if (typeof globalThis !== "undefined") return globalThis;
6442
6464
  if (typeof self !== "undefined") return self;
6443
6465
  if (typeof window !== "undefined") return window;
6444
6466
  if (typeof global !== "undefined") return global;
6445
6467
  }
6446
6468
  function getDevTools() {
6447
- const w = getGlobal();
6469
+ const w = getGlobal$1();
6448
6470
  if (w.__xstate__) return w.__xstate__;
6449
6471
  }
6450
6472
  const devToolsAdapter = (service) => {
@@ -9868,16 +9890,24 @@ const AiChatPageContextSchema = object({
9868
9890
  domSnapshot: string().min(1).optional(),
9869
9891
  screenshotBase64: string().min(1).optional()
9870
9892
  }).strict();
9871
- const AvailableModelSchema = object({
9872
- provider: string(),
9873
- model: string(),
9874
- name: string().optional()
9875
- });
9876
9893
  const ValidationComplexitySchema = _enum([
9877
9894
  "simple",
9878
9895
  "moderate",
9879
9896
  "complex"
9880
9897
  ]);
9898
+ /**
9899
+ * Discriminator for the observe-act loop's per-step semantic intent:
9900
+ * - "act": the step performs an action that mutates page state
9901
+ * (click, fill, navigate, etc.) and is verified by the
9902
+ * attached predicate.
9903
+ * - "assert": the step verifies a condition about the current page —
9904
+ * the predicate IS the verification and no action runs.
9905
+ *
9906
+ * Authoritative source for the enum. Re-exported via `@blinq/schemas`;
9907
+ * client + worker MUST import this rather than redefining the literal
9908
+ * union (see feedback_no_type_duplication.md).
9909
+ */
9910
+ const AiChatStepKindSchema = _enum(["act", "assert"]);
9881
9911
  const AiChatValidationResultSchema = object({
9882
9912
  valid: boolean(),
9883
9913
  complexity: ValidationComplexitySchema,
@@ -9984,8 +10014,6 @@ const AiChatRequestSchema = object({
9984
10014
  messages: array(record(string(), unknown())).optional(),
9985
10015
  pageContext: AiChatPageContextSchema.optional(),
9986
10016
  workerUrl: url().optional(),
9987
- provider: string().optional(),
9988
- model: string().optional(),
9989
10017
  maxExecutionRetries: number().int().nonnegative().default(5),
9990
10018
  maxSuccessfulStepsPerRun: number().int().positive().default(8).optional(),
9991
10019
  maxSemanticActionsPerAiStep: number().int().positive().default(DEFAULT_MAX_SEMANTIC_ACTIONS_PER_AI_STEP),
@@ -10075,14 +10103,16 @@ const AiChatExecutionCompleteEventSchema = object({
10075
10103
  code: string().min(1),
10076
10104
  accumulatedCode: string().min(1).optional(),
10077
10105
  accumulatedCodeSegments: array(AiCodeSegmentSchema).min(1).optional(),
10078
- execution: ExecutionResultSchema
10106
+ execution: ExecutionResultSchema,
10107
+ stepKind: AiChatStepKindSchema.optional()
10079
10108
  }).strict();
10080
10109
  const AiChatWorkerToolCallEventSchema = object({
10081
10110
  type: literal$1("worker-tool-call"),
10082
10111
  callId: string().min(1),
10083
10112
  toolName: AiChatToolNameSchema,
10084
10113
  args: unknown(),
10085
- runId: string().optional()
10114
+ runId: string().optional(),
10115
+ trace: record(string(), string()).optional()
10086
10116
  }).strict();
10087
10117
  const PlanSummaryCommittedStepSchema = object({
10088
10118
  stepId: string().min(1),
@@ -10090,7 +10120,8 @@ const PlanSummaryCommittedStepSchema = object({
10090
10120
  code: string().min(1),
10091
10121
  success: boolean(),
10092
10122
  failureCode: string().min(1).optional(),
10093
- codeSegments: array(AiCodeSegmentSchema).min(1).optional()
10123
+ codeSegments: array(AiCodeSegmentSchema).min(1).optional(),
10124
+ stepKind: AiChatStepKindSchema.optional()
10094
10125
  }).strict();
10095
10126
  const AiChatPlanSummaryStatusSchema = _enum([
10096
10127
  "complete",
@@ -10124,6 +10155,20 @@ const AiChatPlanSummaryEventSchema = object({
10124
10155
  type: literal$1("plan-summary"),
10125
10156
  summary: AiChatPlanSummarySchema
10126
10157
  }).strict();
10158
+ const AiChatHandoffUnverifiableSchema = object({
10159
+ intent: string().min(1),
10160
+ blocker: _enum([
10161
+ "missing-data",
10162
+ "runtime-arithmetic",
10163
+ "multi-element-ambiguity",
10164
+ "analyzer-rejected-3x",
10165
+ "other"
10166
+ ])
10167
+ }).strict();
10168
+ const AiChatHandoffEventSchema = object({
10169
+ type: literal$1("handoff"),
10170
+ unverifiable: AiChatHandoffUnverifiableSchema
10171
+ }).strict();
10127
10172
  const AiChatEventSchema = discriminatedUnion("type", [
10128
10173
  AiChatThinkingEventSchema,
10129
10174
  AiChatExplorationEventSchema,
@@ -10131,7 +10176,8 @@ const AiChatEventSchema = discriminatedUnion("type", [
10131
10176
  AiChatCompleteEventSchema,
10132
10177
  AiChatExecutionCompleteEventSchema,
10133
10178
  AiChatWorkerToolCallEventSchema,
10134
- AiChatPlanSummaryEventSchema
10179
+ AiChatPlanSummaryEventSchema,
10180
+ AiChatHandoffEventSchema
10135
10181
  ]);
10136
10182
  const AiChatDataThinkingPartSchema = object({
10137
10183
  type: literal$1("data-thinking"),
@@ -10148,7 +10194,8 @@ const AiChatDataExecutionStatusPartSchema = object({
10148
10194
  checkpoints: array(CheckpointSchema).optional().default([]),
10149
10195
  error: string().optional(),
10150
10196
  userMessage: string().optional(),
10151
- screenshotAfter: string().optional()
10197
+ screenshotAfter: string().optional(),
10198
+ stepKind: AiChatStepKindSchema.optional()
10152
10199
  });
10153
10200
  /**
10154
10201
  * Wire-level mode values emitted by ai-server in `complete` events. Enumerated
@@ -10198,6 +10245,10 @@ const AiChatDataGeneratedCodePartSchema = object({
10198
10245
  code: string(),
10199
10246
  validation: AiChatValidationResultSchema
10200
10247
  });
10248
+ const AiChatDataHandoffPartSchema = object({
10249
+ type: literal$1("data-handoff"),
10250
+ unverifiable: AiChatHandoffUnverifiableSchema
10251
+ });
10201
10252
  const AiChatDataPartSchema = discriminatedUnion("type", [
10202
10253
  AiChatDataThinkingPartSchema,
10203
10254
  AiChatDataExecutionStatusPartSchema,
@@ -10205,7 +10256,8 @@ const AiChatDataPartSchema = discriminatedUnion("type", [
10205
10256
  AiChatDataErrorPartSchema,
10206
10257
  AiChatDataPlanSummaryPartSchema,
10207
10258
  AiChatDataExplorationPartSchema,
10208
- AiChatDataGeneratedCodePartSchema
10259
+ AiChatDataGeneratedCodePartSchema,
10260
+ AiChatDataHandoffPartSchema
10209
10261
  ]);
10210
10262
  /** Schema for multi-turn continuation prompts. pageContext is REQUIRED (fixes bug 4 structurally). */
10211
10263
  const ContinuationPromptInputSchema = object({
@@ -10392,6 +10444,10 @@ const aiChatMachine = setup({
10392
10444
  contractViolation: {
10393
10445
  tags: ["invalid-contract", "has-code"],
10394
10446
  on: {
10447
+ SAVE: {
10448
+ target: "idle",
10449
+ actions: "clearPending"
10450
+ },
10395
10451
  RETRY: {
10396
10452
  target: "streaming",
10397
10453
  actions: "captureSubmission"
@@ -10570,7 +10626,7 @@ const UrlPredicateKindSchema = _enum([
10570
10626
  "changed-from-baseline"
10571
10627
  ]);
10572
10628
  const POSTCONDITION_GENERATION_MAX_NESTED_DEPTH = 1;
10573
- const PostconditionStatusSchema = number().optional().describe("Optional HTTP status code. Use an integer between 100 and 599.");
10629
+ const PostconditionStatusSchema = number().nullable().describe("HTTP status code (null when absent). Use an integer between 100 and 599.");
10574
10630
  function validateUrlPredicate(predicate, ctx) {
10575
10631
  if (!predicate) return;
10576
10632
  const hasValue = typeof predicate.value !== "undefined";
@@ -10631,22 +10687,27 @@ const ChangedFromBaselineUrlPredicateGenerationPayloadSchema = object({}).strict
10631
10687
  const PostconditionGenerationRouteSchema = object({ kind: PostconditionKindSchema }).strict();
10632
10688
  const PostconditionGenerationLeafRouteSchema = object({ kind: PostconditionLeafKindSchema }).strict();
10633
10689
  const CommonLeafFields = {
10634
- negate: boolean().optional(),
10635
- timeoutMs: number().int().positive().optional()
10690
+ negate: boolean().nullable(),
10691
+ timeoutMs: number().int().positive().nullable()
10636
10692
  };
10637
- const UrlPostconditionGenerationPayloadSchema = object({ predicate: UrlPredicateGenerationRouteSchema }).strict();
10693
+ const UrlPostconditionGenerationPayloadSchema = object({
10694
+ predicate: UrlPredicateGenerationRouteSchema,
10695
+ ...CommonLeafFields
10696
+ }).strict();
10638
10697
  const DomPostconditionGenerationPayloadSchema = object({
10639
10698
  selector: SelectorString,
10640
- state: DomPostconditionStateSchema
10699
+ state: DomPostconditionStateSchema,
10700
+ ...CommonLeafFields
10641
10701
  }).strict();
10642
10702
  const TextPostconditionGenerationPayloadSchema = object({
10643
10703
  text: string().min(1),
10644
- match: TextPostconditionMatchSchema
10704
+ match: TextPostconditionMatchSchema,
10705
+ ...CommonLeafFields
10645
10706
  }).strict();
10646
10707
  const DomCountPostconditionGenerationPayloadSchema = object({
10647
10708
  selector: SelectorString,
10648
10709
  n: number().int().min(0),
10649
- op: DomCountOpSchema.optional(),
10710
+ op: DomCountOpSchema.nullable(),
10650
10711
  ...CommonLeafFields
10651
10712
  }).strict();
10652
10713
  const ValuePostconditionGenerationPayloadSchema = object({
@@ -10658,7 +10719,7 @@ const ValuePostconditionGenerationPayloadSchema = object({
10658
10719
  const AttributePostconditionGenerationPayloadSchema = object({
10659
10720
  selector: SelectorString,
10660
10721
  name: string().min(1),
10661
- value: string().optional(),
10722
+ value: string().nullable(),
10662
10723
  ...CommonLeafFields
10663
10724
  }).strict();
10664
10725
  const TitlePostconditionGenerationPayloadSchema = object({
@@ -10668,7 +10729,8 @@ const TitlePostconditionGenerationPayloadSchema = object({
10668
10729
  }).strict();
10669
10730
  const NetworkPostconditionGenerationPayloadSchema = object({
10670
10731
  predicate: UrlPredicateGenerationRouteSchema,
10671
- status: PostconditionStatusSchema
10732
+ status: PostconditionStatusSchema,
10733
+ ...CommonLeafFields
10672
10734
  }).strict().superRefine((value, ctx) => {
10673
10735
  if (typeof value.status === "number" && !Number.isInteger(value.status)) ctx.addIssue({
10674
10736
  code: "custom",
@@ -11014,10 +11076,14 @@ function containsLegacyCode(node) {
11014
11076
  const PostconditionNodeGenerationSchema = PostconditionCanonicalSchema.refine((node) => !containsLegacyCode(node), { message: "legacy-code leaf is read-only and must not appear in generation output." });
11015
11077
  const ResolvedAllOfPostconditionGenerationPayloadSchema = object({ conditions: array(PostconditionLeafCanonicalSchema).min(1) }).strict();
11016
11078
  const ResolvedAnyOfPostconditionGenerationPayloadSchema = object({ conditions: array(PostconditionLeafCanonicalSchema).min(1) }).strict();
11017
- const ResolvedUrlPostconditionGenerationPayloadSchema = object({ predicate: UrlPredicateCanonicalSchema }).strict();
11079
+ const ResolvedUrlPostconditionGenerationPayloadSchema = object({
11080
+ predicate: UrlPredicateCanonicalSchema,
11081
+ ...CommonLeafFields
11082
+ }).strict();
11018
11083
  const ResolvedNetworkPostconditionGenerationPayloadSchema = object({
11019
11084
  predicate: UrlPredicateCanonicalSchema,
11020
- status: PostconditionStatusSchema
11085
+ status: PostconditionStatusSchema,
11086
+ ...CommonLeafFields
11021
11087
  }).strict().superRefine((value, ctx) => {
11022
11088
  if (typeof value.status === "number" && !Number.isInteger(value.status)) ctx.addIssue({
11023
11089
  code: "custom",
@@ -11070,6 +11136,28 @@ const WorkerClientToolExecuteResponseSchema = object({ result: unknown() }).stri
11070
11136
 
11071
11137
  //#endregion
11072
11138
  //#region ../../core/schemas/src/ai-chat/observe-act-generation.schema.ts
11139
+ /**
11140
+ * Walk a canonical PostconditionCanonical node and return true if any leaf is a
11141
+ * URL or network postcondition whose inner predicate kind is
11142
+ * "changed-from-baseline".
11143
+ *
11144
+ * Used by the kind="assert" guardrail on ResolvedStepBase: `changed-from-baseline`
11145
+ * asserts that a navigation occurred AS A CONSEQUENCE of an action, which is
11146
+ * semantically invalid on a kind="assert" step (which has no action).
11147
+ *
11148
+ * Scope: file-local helper. Not exported from the package barrel — blast radius
11149
+ * stays inside this file, and exhaustive coverage lives in
11150
+ * observe-act-generation.schema.test.ts.
11151
+ */
11152
+ function postconditionReferencesChangedFromBaseline(node) {
11153
+ switch (node.kind) {
11154
+ case "url":
11155
+ case "network": return node.predicate.kind === "changed-from-baseline";
11156
+ case "all-of":
11157
+ case "any-of": return node.conditions.some(postconditionReferencesChangedFromBaseline);
11158
+ default: return false;
11159
+ }
11160
+ }
11073
11161
  const ObserveActGenerationCheckpointSchema = object({
11074
11162
  label: string().min(1),
11075
11163
  timestampMs: number().nonnegative()
@@ -11144,85 +11232,97 @@ const ObserveActGenerationInputSchema = object({
11144
11232
  pinnedElement: ObserveActGenerationPinnedElementSchema.optional(),
11145
11233
  availableTestData: array(ListAvailableTestDataEntrySchema).readonly().optional()
11146
11234
  }).strict();
11147
- const ObserveActGenerationTypeSchema = _enum([
11148
- "step",
11149
- "assertion",
11150
- "complete"
11151
- ]);
11235
+ const ObserveActGenerationTypeSchema = _enum(["step", "complete"]);
11152
11236
  const ObserveActGenerationRouteSchema = object({ type: ObserveActGenerationTypeSchema }).strict();
11153
- const ObserveActGenerationStepShellPayloadSchema = object({
11237
+ const UnverifiableSchema = object({
11238
+ intent: string().min(1),
11239
+ blocker: _enum([
11240
+ "missing-data",
11241
+ "runtime-arithmetic",
11242
+ "multi-element-ambiguity",
11243
+ "analyzer-rejected-3x",
11244
+ "other"
11245
+ ])
11246
+ }).strict();
11247
+ const StepShellBase = object({
11154
11248
  stepGoal: string().min(1),
11155
- actionCode: string().min(1),
11156
- postcondition: PostconditionGenerationRouteSchema
11249
+ kind: _enum(["act", "assert"]),
11250
+ actionCode: string().min(1).nullable(),
11251
+ postCondition: PostconditionGenerationRouteSchema
11157
11252
  }).strict();
11158
- const ObserveActGenerationResolvedStepPayloadSchema = object({
11253
+ const ObserveActGenerationStepShellPayloadSchema = StepShellBase.superRefine((data, ctx) => {
11254
+ if (data.kind === "act" && (data.actionCode === null || data.actionCode.length === 0)) ctx.addIssue({
11255
+ code: ZodIssueCode.custom,
11256
+ message: "kind=act requires actionCode",
11257
+ path: ["actionCode"]
11258
+ });
11259
+ if (data.kind === "assert" && data.actionCode !== null) ctx.addIssue({
11260
+ code: ZodIssueCode.custom,
11261
+ message: "kind=assert must emit actionCode: null",
11262
+ path: ["actionCode"]
11263
+ });
11264
+ });
11265
+ const ResolvedStepBase = object({
11159
11266
  stepGoal: string().min(1),
11160
- actionCode: string().min(1),
11161
- postcondition: PostconditionCanonicalSchema
11267
+ kind: _enum(["act", "assert"]),
11268
+ actionCode: string().min(1).nullable(),
11269
+ postCondition: PostconditionCanonicalSchema
11270
+ }).strict();
11271
+ const ObserveActGenerationResolvedStepPayloadSchema = ResolvedStepBase.superRefine((data, ctx) => {
11272
+ if (data.kind === "act" && (data.actionCode === null || data.actionCode.length === 0)) ctx.addIssue({
11273
+ code: ZodIssueCode.custom,
11274
+ message: "kind=act requires actionCode",
11275
+ path: ["actionCode"]
11276
+ });
11277
+ if (data.kind === "assert" && data.actionCode !== null) ctx.addIssue({
11278
+ code: ZodIssueCode.custom,
11279
+ message: "kind=assert must emit actionCode: null",
11280
+ path: ["actionCode"]
11281
+ });
11282
+ if (data.kind === "assert" && postconditionReferencesChangedFromBaseline(data.postCondition)) ctx.addIssue({
11283
+ code: ZodIssueCode.custom,
11284
+ message: "url/network predicate \"changed-from-baseline\" is not valid on kind=\"assert\" steps; pick a concrete url leaf (equals/contains/path-contains/matches-regex) or a different leaf.",
11285
+ path: ["postCondition"]
11286
+ });
11287
+ });
11288
+ const ObserveActGenerationCompletePayloadSchema = object({
11289
+ reason: string().min(1),
11290
+ unverifiable: UnverifiableSchema.nullable()
11162
11291
  }).strict();
11292
+ /** @deprecated The assertion route is removed (PR #341). */
11163
11293
  const ObserveActGenerationAssertionPayloadSchema = object({
11164
11294
  assertionGoal: string().min(1),
11165
11295
  assertionCode: string().min(1)
11166
11296
  }).strict();
11167
- const ObserveActGenerationCompletePayloadSchema = object({ reason: string().min(1) }).strict();
11168
11297
  const ObserveActGenerationResolvedGroupPostconditionPayloadSchema = object({ conditions: array(PostconditionLeafCanonicalSchema).min(1) }).strict();
11169
11298
  const ObserveActGenerationCanonicalSchema = object({
11170
11299
  type: ObserveActGenerationTypeSchema,
11171
11300
  step: ObserveActGenerationResolvedStepPayloadSchema.optional(),
11172
- assertion: ObserveActGenerationAssertionPayloadSchema.optional(),
11173
11301
  complete: ObserveActGenerationCompletePayloadSchema.optional()
11174
11302
  }).strict().superRefine((value, ctx) => {
11175
11303
  if (value.type === "step") {
11176
11304
  if (!value.step) ctx.addIssue({
11177
- code: "custom",
11305
+ code: ZodIssueCode.custom,
11178
11306
  path: ["step"],
11179
11307
  message: "step is required when type is 'step'."
11180
11308
  });
11181
- if (value.assertion) ctx.addIssue({
11182
- code: "custom",
11183
- path: ["assertion"],
11184
- message: "assertion is not allowed when type is 'step'."
11185
- });
11186
11309
  if (value.complete) ctx.addIssue({
11187
- code: "custom",
11310
+ code: ZodIssueCode.custom,
11188
11311
  path: ["complete"],
11189
11312
  message: "complete is not allowed when type is 'step'."
11190
11313
  });
11191
- return;
11192
- }
11193
- if (value.type === "assertion") {
11194
- if (!value.assertion) ctx.addIssue({
11195
- code: "custom",
11196
- path: ["assertion"],
11197
- message: "assertion is required when type is 'assertion'."
11314
+ } else if (value.type === "complete") {
11315
+ if (!value.complete) ctx.addIssue({
11316
+ code: ZodIssueCode.custom,
11317
+ path: ["complete"],
11318
+ message: "complete is required when type is 'complete'."
11198
11319
  });
11199
11320
  if (value.step) ctx.addIssue({
11200
- code: "custom",
11321
+ code: ZodIssueCode.custom,
11201
11322
  path: ["step"],
11202
- message: "step is not allowed when type is 'assertion'."
11203
- });
11204
- if (value.complete) ctx.addIssue({
11205
- code: "custom",
11206
- path: ["complete"],
11207
- message: "complete is not allowed when type is 'assertion'."
11323
+ message: "step is not allowed when type is 'complete'."
11208
11324
  });
11209
- return;
11210
11325
  }
11211
- if (!value.complete) ctx.addIssue({
11212
- code: "custom",
11213
- path: ["complete"],
11214
- message: "complete is required when type is 'complete'."
11215
- });
11216
- if (value.step) ctx.addIssue({
11217
- code: "custom",
11218
- path: ["step"],
11219
- message: "step is not allowed when type is 'complete'."
11220
- });
11221
- if (value.assertion) ctx.addIssue({
11222
- code: "custom",
11223
- path: ["assertion"],
11224
- message: "assertion is not allowed when type is 'complete'."
11225
- });
11226
11326
  });
11227
11327
 
11228
11328
  //#endregion
@@ -11260,7 +11360,8 @@ const FEATURE_FLAG_KEYS = [
11260
11360
  "NewFirstUserFlow_DemoPage",
11261
11361
  "EnvReachabilityCheck",
11262
11362
  "SlackIntegration",
11263
- "ExecutionNotifications"
11363
+ "ExecutionNotifications",
11364
+ "ExecutionEditorModeSwitching"
11264
11365
  ];
11265
11366
  const FeatureFlagKeySchema = _enum(FEATURE_FLAG_KEYS);
11266
11367
  const FeatureFlagSchema = object({
@@ -17842,162 +17943,1935 @@ async function validatePlaywrightCode(code) {
17842
17943
  }
17843
17944
 
17844
17945
  //#endregion
17845
- //#region ../../core/bvt-agent/src/agent/playwright-runner.ts
17946
+ //#region ../../node_modules/@opentelemetry/api/build/esm/version.js
17947
+ const VERSION = "1.9.1";
17948
+
17949
+ //#endregion
17950
+ //#region ../../node_modules/@opentelemetry/api/build/esm/internal/semver.js
17951
+ const re = /^(\d+)\.(\d+)\.(\d+)(-(.+))?$/;
17846
17952
  /**
17847
- * Blocked methods are dangerous in a sandbox context (code execution, request
17848
- * interception, browser/context escape, etc.). Everything else discovered at
17849
- * runtime on the real Playwright objects is automatically allowed, so new
17850
- * Playwright API additions work without manual updates.
17953
+ * Create a function to test an API version to see if it is compatible with the provided ownVersion.
17954
+ *
17955
+ * The returned function has the following semantics:
17956
+ * - Exact match is always compatible
17957
+ * - Major versions must match exactly
17958
+ * - 1.x package cannot use global 2.x package
17959
+ * - 2.x package cannot use global 1.x package
17960
+ * - The minor version of the API module requesting access to the global API must be less than or equal to the minor version of this API
17961
+ * - 1.3 package may use 1.4 global because the later global contains all functions 1.3 expects
17962
+ * - 1.4 package may NOT use 1.3 global because it may try to call functions which don't exist on 1.3
17963
+ * - If the major version is 0, the minor version is treated as the major and the patch is treated as the minor
17964
+ * - Patch and build tag differences are not considered at this time
17965
+ *
17966
+ * @param ownVersion version which should be checked against
17851
17967
  */
17852
- const BLOCKED_PAGE_METHODS = new Set([
17853
- "evaluate",
17854
- "evaluateHandle",
17855
- "$eval",
17856
- "$$eval",
17857
- "addScriptTag",
17858
- "addStyleTag",
17859
- "exposeFunction",
17860
- "exposeBinding",
17861
- "addInitScript",
17862
- "route",
17863
- "unroute",
17864
- "routeFromHAR",
17865
- "unrouteAll",
17866
- "context",
17867
- "close",
17868
- "bringToFront",
17869
- "setContent",
17870
- "setExtraHTTPHeaders",
17871
- "setInputFiles",
17872
- "pdf",
17873
- "screenshot",
17874
- "video",
17875
- "on",
17876
- "off",
17877
- "once",
17878
- "emit",
17879
- "removeListener",
17880
- "removeAllListeners",
17881
- "addListener",
17882
- "setMaxListeners",
17883
- "waitForEvent",
17884
- "workers",
17885
- "frames",
17886
- "mainFrame",
17887
- "opener"
17888
- ]);
17889
- const BLOCKED_LOCATOR_METHODS = new Set([
17890
- "evaluate",
17891
- "evaluateHandle",
17892
- "evaluateAll",
17893
- "on",
17894
- "off",
17895
- "once",
17896
- "emit",
17897
- "removeListener",
17898
- "removeAllListeners",
17899
- "addListener",
17900
- "setMaxListeners",
17901
- "setInputFiles",
17902
- "screenshot"
17903
- ]);
17968
+ function _makeCompatibilityCheck(ownVersion) {
17969
+ const acceptedVersions = new Set([ownVersion]);
17970
+ const rejectedVersions = /* @__PURE__ */ new Set();
17971
+ const myVersionMatch = ownVersion.match(re);
17972
+ if (!myVersionMatch) return () => false;
17973
+ const ownVersionParsed = {
17974
+ major: +myVersionMatch[1],
17975
+ minor: +myVersionMatch[2],
17976
+ patch: +myVersionMatch[3],
17977
+ prerelease: myVersionMatch[4]
17978
+ };
17979
+ if (ownVersionParsed.prerelease != null) return function isExactmatch(globalVersion) {
17980
+ return globalVersion === ownVersion;
17981
+ };
17982
+ function _reject(v) {
17983
+ rejectedVersions.add(v);
17984
+ return false;
17985
+ }
17986
+ function _accept(v) {
17987
+ acceptedVersions.add(v);
17988
+ return true;
17989
+ }
17990
+ return function isCompatible(globalVersion) {
17991
+ if (acceptedVersions.has(globalVersion)) return true;
17992
+ if (rejectedVersions.has(globalVersion)) return false;
17993
+ const globalVersionMatch = globalVersion.match(re);
17994
+ if (!globalVersionMatch) return _reject(globalVersion);
17995
+ const globalVersionParsed = {
17996
+ major: +globalVersionMatch[1],
17997
+ minor: +globalVersionMatch[2],
17998
+ patch: +globalVersionMatch[3],
17999
+ prerelease: globalVersionMatch[4]
18000
+ };
18001
+ if (globalVersionParsed.prerelease != null) return _reject(globalVersion);
18002
+ if (ownVersionParsed.major !== globalVersionParsed.major) return _reject(globalVersion);
18003
+ if (ownVersionParsed.major === 0) {
18004
+ if (ownVersionParsed.minor === globalVersionParsed.minor && ownVersionParsed.patch <= globalVersionParsed.patch) return _accept(globalVersion);
18005
+ return _reject(globalVersion);
18006
+ }
18007
+ if (ownVersionParsed.minor <= globalVersionParsed.minor) return _accept(globalVersion);
18008
+ return _reject(globalVersion);
18009
+ };
18010
+ }
17904
18011
  /**
17905
- * Walk the prototype chain and collect every function-valued own-property.
17906
- * Uses property descriptors to avoid triggering getters/accessors (e.g.
17907
- * Playwright's `keyboard`, `mouse` accessors) during introspection.
18012
+ * Test an API version to see if it is compatible with this API.
18013
+ *
18014
+ * - Exact match is always compatible
18015
+ * - Major versions must match exactly
18016
+ * - 1.x package cannot use global 2.x package
18017
+ * - 2.x package cannot use global 1.x package
18018
+ * - The minor version of the API module requesting access to the global API must be less than or equal to the minor version of this API
18019
+ * - 1.3 package may use 1.4 global because the later global contains all functions 1.3 expects
18020
+ * - 1.4 package may NOT use 1.3 global because it may try to call functions which don't exist on 1.3
18021
+ * - If the major version is 0, the minor version is treated as the major and the patch is treated as the minor
18022
+ * - Patch and build tag differences are not considered at this time
18023
+ *
18024
+ * @param version version of the API requesting an instance of the global API
17908
18025
  */
17909
- function extractMethods(obj) {
17910
- const methods = /* @__PURE__ */ new Set();
17911
- let current = obj;
17912
- while (current && current !== Object.prototype) {
17913
- for (const key of Object.getOwnPropertyNames(current)) {
17914
- const descriptor = Object.getOwnPropertyDescriptor(current, key);
17915
- if (key !== "constructor" && descriptor && typeof descriptor.value === "function") methods.add(key);
17916
- }
17917
- current = Object.getPrototypeOf(current);
18026
+ const isCompatible = _makeCompatibilityCheck(VERSION);
18027
+
18028
+ //#endregion
18029
+ //#region ../../node_modules/@opentelemetry/api/build/esm/internal/global-utils.js
18030
+ const major = VERSION.split(".")[0];
18031
+ const GLOBAL_OPENTELEMETRY_API_KEY = Symbol.for(`opentelemetry.js.api.${major}`);
18032
+ const _global = typeof globalThis === "object" ? globalThis : typeof self === "object" ? self : typeof window === "object" ? window : typeof global === "object" ? global : {};
18033
+ function registerGlobal(type, instance, diag, allowOverride = false) {
18034
+ var _a;
18035
+ const api = _global[GLOBAL_OPENTELEMETRY_API_KEY] = (_a = _global[GLOBAL_OPENTELEMETRY_API_KEY]) !== null && _a !== void 0 ? _a : { version: VERSION };
18036
+ if (!allowOverride && api[type]) {
18037
+ const err = /* @__PURE__ */ new Error(`@opentelemetry/api: Attempted duplicate registration of API: ${type}`);
18038
+ diag.error(err.stack || err.message);
18039
+ return false;
17918
18040
  }
17919
- return [...methods];
18041
+ if (api.version !== VERSION) {
18042
+ const err = /* @__PURE__ */ new Error(`@opentelemetry/api: Registration of version v${api.version} for ${type} does not match previously registered API v${VERSION}`);
18043
+ diag.error(err.stack || err.message);
18044
+ return false;
18045
+ }
18046
+ api[type] = instance;
18047
+ diag.debug(`@opentelemetry/api: Registered a global for ${type} v${VERSION}.`);
18048
+ return true;
17920
18049
  }
17921
- const HOST_HELPER_METHODS = [
17922
- "getPreferredInteractiveTargetSelector",
17923
- "activatePreferredInteractiveTarget",
17924
- "activateWithRecovery"
17925
- ];
17926
- const FALLBACK_PAGE_METHODS = [
17927
- "getByAltText",
17928
- "getByDisplayValue",
17929
- "getByLabel",
17930
- "getByPlaceholder",
17931
- "getByRole",
17932
- "getByTestId",
17933
- "getByText",
17934
- "getByTitle",
17935
- "goto",
17936
- "reload",
17937
- "goBack",
17938
- "goForward",
17939
- "locator",
17940
- "title",
17941
- "url",
17942
- "waitForSelector",
17943
- "waitForTimeout",
17944
- "waitForURL",
17945
- "waitForLoadState"
17946
- ];
17947
- const FALLBACK_LOCATOR_METHODS = [
17948
- "allTextContents",
17949
- "and",
17950
- "blur",
17951
- "check",
17952
- "clear",
17953
- "click",
17954
- "count",
17955
- "fill",
17956
- "filter",
17957
- "first",
17958
- "focus",
17959
- "getAttribute",
17960
- "getByAltText",
17961
- "getByDisplayValue",
17962
- "getByLabel",
17963
- "getByPlaceholder",
17964
- "getByRole",
17965
- "getByTestId",
17966
- "getByText",
17967
- "getByTitle",
17968
- "hover",
17969
- "innerText",
17970
- "inputValue",
17971
- "isChecked",
17972
- "isDisabled",
17973
- "isEnabled",
17974
- "isHidden",
17975
- "isVisible",
17976
- "last",
17977
- "locator",
17978
- "nth",
17979
- "or",
17980
- "press",
17981
- "scrollIntoViewIfNeeded",
17982
- "selectOption",
17983
- "textContent",
17984
- "type",
17985
- "uncheck",
17986
- "waitFor"
17987
- ];
17988
- function buildAllowedMethods(obj, blocked, fallback) {
17989
- let all = extractMethods(obj);
17990
- if (all.length === 0) all = fallback;
17991
- const methods = all.filter((m) => !blocked.has(m));
17992
- return {
17993
- methods,
17994
- methodSet: new Set(methods)
17995
- };
18050
+ function getGlobal(type) {
18051
+ var _a, _b;
18052
+ const globalVersion = (_a = _global[GLOBAL_OPENTELEMETRY_API_KEY]) === null || _a === void 0 ? void 0 : _a.version;
18053
+ if (!globalVersion || !isCompatible(globalVersion)) return;
18054
+ return (_b = _global[GLOBAL_OPENTELEMETRY_API_KEY]) === null || _b === void 0 ? void 0 : _b[type];
17996
18055
  }
17997
- const HELPER_METHOD_SET = new Set(HOST_HELPER_METHODS);
17998
- const BRIDGE_ERROR_PREFIX = "[playwright-bridge]";
17999
- const RECOVERY_LOCATOR_OPERATION_TIMEOUT_MS = 2e3;
18000
- function recoveryLocatorOptions(extra) {
18056
+ function unregisterGlobal(type, diag) {
18057
+ diag.debug(`@opentelemetry/api: Unregistering a global for ${type} v${VERSION}.`);
18058
+ const api = _global[GLOBAL_OPENTELEMETRY_API_KEY];
18059
+ if (api) delete api[type];
18060
+ }
18061
+
18062
+ //#endregion
18063
+ //#region ../../node_modules/@opentelemetry/api/build/esm/diag/ComponentLogger.js
18064
+ /**
18065
+ * Component Logger which is meant to be used as part of any component which
18066
+ * will add automatically additional namespace in front of the log message.
18067
+ * It will then forward all message to global diag logger
18068
+ * @example
18069
+ * const cLogger = diag.createComponentLogger({ namespace: '@opentelemetry/instrumentation-http' });
18070
+ * cLogger.debug('test');
18071
+ * // @opentelemetry/instrumentation-http test
18072
+ */
18073
+ var DiagComponentLogger = class {
18074
+ constructor(props) {
18075
+ this._namespace = props.namespace || "DiagComponentLogger";
18076
+ }
18077
+ debug(...args) {
18078
+ return logProxy("debug", this._namespace, args);
18079
+ }
18080
+ error(...args) {
18081
+ return logProxy("error", this._namespace, args);
18082
+ }
18083
+ info(...args) {
18084
+ return logProxy("info", this._namespace, args);
18085
+ }
18086
+ warn(...args) {
18087
+ return logProxy("warn", this._namespace, args);
18088
+ }
18089
+ verbose(...args) {
18090
+ return logProxy("verbose", this._namespace, args);
18091
+ }
18092
+ };
18093
+ function logProxy(funcName, namespace, args) {
18094
+ const logger = getGlobal("diag");
18095
+ if (!logger) return;
18096
+ return logger[funcName](namespace, ...args);
18097
+ }
18098
+
18099
+ //#endregion
18100
+ //#region ../../node_modules/@opentelemetry/api/build/esm/diag/types.js
18101
+ /**
18102
+ * Defines the available internal logging levels for the diagnostic logger, the numeric values
18103
+ * of the levels are defined to match the original values from the initial LogLevel to avoid
18104
+ * compatibility/migration issues for any implementation that assume the numeric ordering.
18105
+ */
18106
+ var DiagLogLevel;
18107
+ (function(DiagLogLevel) {
18108
+ /** Diagnostic Logging level setting to disable all logging (except and forced logs) */
18109
+ DiagLogLevel[DiagLogLevel["NONE"] = 0] = "NONE";
18110
+ /** Identifies an error scenario */
18111
+ DiagLogLevel[DiagLogLevel["ERROR"] = 30] = "ERROR";
18112
+ /** Identifies a warning scenario */
18113
+ DiagLogLevel[DiagLogLevel["WARN"] = 50] = "WARN";
18114
+ /** General informational log message */
18115
+ DiagLogLevel[DiagLogLevel["INFO"] = 60] = "INFO";
18116
+ /** General debug log message */
18117
+ DiagLogLevel[DiagLogLevel["DEBUG"] = 70] = "DEBUG";
18118
+ /**
18119
+ * Detailed trace level logging should only be used for development, should only be set
18120
+ * in a development environment.
18121
+ */
18122
+ DiagLogLevel[DiagLogLevel["VERBOSE"] = 80] = "VERBOSE";
18123
+ /** Used to set the logging level to include all logging */
18124
+ DiagLogLevel[DiagLogLevel["ALL"] = 9999] = "ALL";
18125
+ })(DiagLogLevel || (DiagLogLevel = {}));
18126
+
18127
+ //#endregion
18128
+ //#region ../../node_modules/@opentelemetry/api/build/esm/diag/internal/logLevelLogger.js
18129
+ function createLogLevelDiagLogger(maxLevel, logger) {
18130
+ if (maxLevel < DiagLogLevel.NONE) maxLevel = DiagLogLevel.NONE;
18131
+ else if (maxLevel > DiagLogLevel.ALL) maxLevel = DiagLogLevel.ALL;
18132
+ logger = logger || {};
18133
+ function _filterFunc(funcName, theLevel) {
18134
+ const theFunc = logger[funcName];
18135
+ if (typeof theFunc === "function" && maxLevel >= theLevel) return theFunc.bind(logger);
18136
+ return function() {};
18137
+ }
18138
+ return {
18139
+ error: _filterFunc("error", DiagLogLevel.ERROR),
18140
+ warn: _filterFunc("warn", DiagLogLevel.WARN),
18141
+ info: _filterFunc("info", DiagLogLevel.INFO),
18142
+ debug: _filterFunc("debug", DiagLogLevel.DEBUG),
18143
+ verbose: _filterFunc("verbose", DiagLogLevel.VERBOSE)
18144
+ };
18145
+ }
18146
+
18147
+ //#endregion
18148
+ //#region ../../node_modules/@opentelemetry/api/build/esm/api/diag.js
18149
+ const API_NAME$2 = "diag";
18150
+ /**
18151
+ * Singleton object which represents the entry point to the OpenTelemetry internal
18152
+ * diagnostic API
18153
+ *
18154
+ * @since 1.0.0
18155
+ */
18156
+ var DiagAPI = class DiagAPI {
18157
+ /** Get the singleton instance of the DiagAPI API */
18158
+ static instance() {
18159
+ if (!this._instance) this._instance = new DiagAPI();
18160
+ return this._instance;
18161
+ }
18162
+ /**
18163
+ * Private internal constructor
18164
+ * @private
18165
+ */
18166
+ constructor() {
18167
+ function _logProxy(funcName) {
18168
+ return function(...args) {
18169
+ const logger = getGlobal("diag");
18170
+ if (!logger) return;
18171
+ return logger[funcName](...args);
18172
+ };
18173
+ }
18174
+ const self = this;
18175
+ const setLogger = (logger, optionsOrLogLevel = { logLevel: DiagLogLevel.INFO }) => {
18176
+ var _a, _b, _c;
18177
+ if (logger === self) {
18178
+ const err = /* @__PURE__ */ new Error("Cannot use diag as the logger for itself. Please use a DiagLogger implementation like ConsoleDiagLogger or a custom implementation");
18179
+ self.error((_a = err.stack) !== null && _a !== void 0 ? _a : err.message);
18180
+ return false;
18181
+ }
18182
+ if (typeof optionsOrLogLevel === "number") optionsOrLogLevel = { logLevel: optionsOrLogLevel };
18183
+ const oldLogger = getGlobal("diag");
18184
+ const newLogger = createLogLevelDiagLogger((_b = optionsOrLogLevel.logLevel) !== null && _b !== void 0 ? _b : DiagLogLevel.INFO, logger);
18185
+ if (oldLogger && !optionsOrLogLevel.suppressOverrideMessage) {
18186
+ const stack = (_c = (/* @__PURE__ */ new Error()).stack) !== null && _c !== void 0 ? _c : "<failed to generate stacktrace>";
18187
+ oldLogger.warn(`Current logger will be overwritten from ${stack}`);
18188
+ newLogger.warn(`Current logger will overwrite one already registered from ${stack}`);
18189
+ }
18190
+ return registerGlobal("diag", newLogger, self, true);
18191
+ };
18192
+ self.setLogger = setLogger;
18193
+ self.disable = () => {
18194
+ unregisterGlobal(API_NAME$2, self);
18195
+ };
18196
+ self.createComponentLogger = (options) => {
18197
+ return new DiagComponentLogger(options);
18198
+ };
18199
+ self.verbose = _logProxy("verbose");
18200
+ self.debug = _logProxy("debug");
18201
+ self.info = _logProxy("info");
18202
+ self.warn = _logProxy("warn");
18203
+ self.error = _logProxy("error");
18204
+ }
18205
+ };
18206
+
18207
+ //#endregion
18208
+ //#region ../../node_modules/@opentelemetry/api/build/esm/context/context.js
18209
+ /**
18210
+ * Get a key to uniquely identify a context value
18211
+ *
18212
+ * @since 1.0.0
18213
+ */
18214
+ function createContextKey(description) {
18215
+ return Symbol.for(description);
18216
+ }
18217
+ var BaseContext = class BaseContext {
18218
+ /**
18219
+ * Construct a new context which inherits values from an optional parent context.
18220
+ *
18221
+ * @param parentContext a context from which to inherit values
18222
+ */
18223
+ constructor(parentContext) {
18224
+ const self = this;
18225
+ self._currentContext = parentContext ? new Map(parentContext) : /* @__PURE__ */ new Map();
18226
+ self.getValue = (key) => self._currentContext.get(key);
18227
+ self.setValue = (key, value) => {
18228
+ const context = new BaseContext(self._currentContext);
18229
+ context._currentContext.set(key, value);
18230
+ return context;
18231
+ };
18232
+ self.deleteValue = (key) => {
18233
+ const context = new BaseContext(self._currentContext);
18234
+ context._currentContext.delete(key);
18235
+ return context;
18236
+ };
18237
+ }
18238
+ };
18239
+ /**
18240
+ * The root context is used as the default parent context when there is no active context
18241
+ *
18242
+ * @since 1.0.0
18243
+ */
18244
+ const ROOT_CONTEXT = new BaseContext();
18245
+
18246
+ //#endregion
18247
+ //#region ../../node_modules/@opentelemetry/api/build/esm/context/NoopContextManager.js
18248
+ var NoopContextManager = class {
18249
+ active() {
18250
+ return ROOT_CONTEXT;
18251
+ }
18252
+ with(_context, fn, thisArg, ...args) {
18253
+ return fn.call(thisArg, ...args);
18254
+ }
18255
+ bind(_context, target) {
18256
+ return target;
18257
+ }
18258
+ enable() {
18259
+ return this;
18260
+ }
18261
+ disable() {
18262
+ return this;
18263
+ }
18264
+ };
18265
+
18266
+ //#endregion
18267
+ //#region ../../node_modules/@opentelemetry/api/build/esm/api/context.js
18268
+ const API_NAME$1 = "context";
18269
+ const NOOP_CONTEXT_MANAGER = new NoopContextManager();
18270
+ /**
18271
+ * Singleton object which represents the entry point to the OpenTelemetry Context API
18272
+ *
18273
+ * @since 1.0.0
18274
+ */
18275
+ var ContextAPI = class ContextAPI {
18276
+ /** Empty private constructor prevents end users from constructing a new instance of the API */
18277
+ constructor() {}
18278
+ /** Get the singleton instance of the Context API */
18279
+ static getInstance() {
18280
+ if (!this._instance) this._instance = new ContextAPI();
18281
+ return this._instance;
18282
+ }
18283
+ /**
18284
+ * Set the current context manager.
18285
+ *
18286
+ * @returns true if the context manager was successfully registered, else false
18287
+ */
18288
+ setGlobalContextManager(contextManager) {
18289
+ return registerGlobal(API_NAME$1, contextManager, DiagAPI.instance());
18290
+ }
18291
+ /**
18292
+ * Get the currently active context
18293
+ */
18294
+ active() {
18295
+ return this._getContextManager().active();
18296
+ }
18297
+ /**
18298
+ * Execute a function with an active context
18299
+ *
18300
+ * @param context context to be active during function execution
18301
+ * @param fn function to execute in a context
18302
+ * @param thisArg optional receiver to be used for calling fn
18303
+ * @param args optional arguments forwarded to fn
18304
+ */
18305
+ with(context, fn, thisArg, ...args) {
18306
+ return this._getContextManager().with(context, fn, thisArg, ...args);
18307
+ }
18308
+ /**
18309
+ * Bind a context to a target function or event emitter
18310
+ *
18311
+ * @param context context to bind to the event emitter or function. Defaults to the currently active context
18312
+ * @param target function or event emitter to bind
18313
+ */
18314
+ bind(context, target) {
18315
+ return this._getContextManager().bind(context, target);
18316
+ }
18317
+ _getContextManager() {
18318
+ return getGlobal(API_NAME$1) || NOOP_CONTEXT_MANAGER;
18319
+ }
18320
+ /** Disable and remove the global context manager */
18321
+ disable() {
18322
+ this._getContextManager().disable();
18323
+ unregisterGlobal(API_NAME$1, DiagAPI.instance());
18324
+ }
18325
+ };
18326
+
18327
+ //#endregion
18328
+ //#region ../../node_modules/@opentelemetry/api/build/esm/trace/trace_flags.js
18329
+ /**
18330
+ * @since 1.0.0
18331
+ */
18332
+ var TraceFlags;
18333
+ (function(TraceFlags) {
18334
+ /** Represents no flag set. */
18335
+ TraceFlags[TraceFlags["NONE"] = 0] = "NONE";
18336
+ /** Bit to represent whether trace is sampled in trace flags. */
18337
+ TraceFlags[TraceFlags["SAMPLED"] = 1] = "SAMPLED";
18338
+ })(TraceFlags || (TraceFlags = {}));
18339
+
18340
+ //#endregion
18341
+ //#region ../../node_modules/@opentelemetry/api/build/esm/trace/invalid-span-constants.js
18342
+ /**
18343
+ * @since 1.0.0
18344
+ */
18345
+ const INVALID_SPANID = "0000000000000000";
18346
+ /**
18347
+ * @since 1.0.0
18348
+ */
18349
+ const INVALID_TRACEID = "00000000000000000000000000000000";
18350
+ /**
18351
+ * @since 1.0.0
18352
+ */
18353
+ const INVALID_SPAN_CONTEXT = {
18354
+ traceId: INVALID_TRACEID,
18355
+ spanId: INVALID_SPANID,
18356
+ traceFlags: TraceFlags.NONE
18357
+ };
18358
+
18359
+ //#endregion
18360
+ //#region ../../node_modules/@opentelemetry/api/build/esm/trace/NonRecordingSpan.js
18361
+ /**
18362
+ * The NonRecordingSpan is the default {@link Span} that is used when no Span
18363
+ * implementation is available. All operations are no-op including context
18364
+ * propagation.
18365
+ */
18366
+ var NonRecordingSpan = class {
18367
+ constructor(spanContext = INVALID_SPAN_CONTEXT) {
18368
+ this._spanContext = spanContext;
18369
+ }
18370
+ spanContext() {
18371
+ return this._spanContext;
18372
+ }
18373
+ setAttribute(_key, _value) {
18374
+ return this;
18375
+ }
18376
+ setAttributes(_attributes) {
18377
+ return this;
18378
+ }
18379
+ addEvent(_name, _attributes) {
18380
+ return this;
18381
+ }
18382
+ addLink(_link) {
18383
+ return this;
18384
+ }
18385
+ addLinks(_links) {
18386
+ return this;
18387
+ }
18388
+ setStatus(_status) {
18389
+ return this;
18390
+ }
18391
+ updateName(_name) {
18392
+ return this;
18393
+ }
18394
+ end(_endTime) {}
18395
+ isRecording() {
18396
+ return false;
18397
+ }
18398
+ recordException(_exception, _time) {}
18399
+ };
18400
+
18401
+ //#endregion
18402
+ //#region ../../node_modules/@opentelemetry/api/build/esm/trace/context-utils.js
18403
+ /**
18404
+ * span key
18405
+ */
18406
+ const SPAN_KEY = createContextKey("OpenTelemetry Context Key SPAN");
18407
+ /**
18408
+ * Return the span if one exists
18409
+ *
18410
+ * @param context context to get span from
18411
+ */
18412
+ function getSpan(context) {
18413
+ return context.getValue(SPAN_KEY) || void 0;
18414
+ }
18415
+ /**
18416
+ * Gets the span from the current context, if one exists.
18417
+ */
18418
+ function getActiveSpan() {
18419
+ return getSpan(ContextAPI.getInstance().active());
18420
+ }
18421
+ /**
18422
+ * Set the span on a context
18423
+ *
18424
+ * @param context context to use as parent
18425
+ * @param span span to set active
18426
+ */
18427
+ function setSpan(context, span) {
18428
+ return context.setValue(SPAN_KEY, span);
18429
+ }
18430
+ /**
18431
+ * Remove current span stored in the context
18432
+ *
18433
+ * @param context context to delete span from
18434
+ */
18435
+ function deleteSpan(context) {
18436
+ return context.deleteValue(SPAN_KEY);
18437
+ }
18438
+ /**
18439
+ * Wrap span context in a NoopSpan and set as span in a new
18440
+ * context
18441
+ *
18442
+ * @param context context to set active span on
18443
+ * @param spanContext span context to be wrapped
18444
+ */
18445
+ function setSpanContext(context, spanContext) {
18446
+ return setSpan(context, new NonRecordingSpan(spanContext));
18447
+ }
18448
+ /**
18449
+ * Get the span context of the span if it exists.
18450
+ *
18451
+ * @param context context to get values from
18452
+ */
18453
+ function getSpanContext(context) {
18454
+ var _a;
18455
+ return (_a = getSpan(context)) === null || _a === void 0 ? void 0 : _a.spanContext();
18456
+ }
18457
+
18458
+ //#endregion
18459
+ //#region ../../node_modules/@opentelemetry/api/build/esm/trace/spancontext-utils.js
18460
+ const isHex = new Uint8Array([
18461
+ 0,
18462
+ 0,
18463
+ 0,
18464
+ 0,
18465
+ 0,
18466
+ 0,
18467
+ 0,
18468
+ 0,
18469
+ 0,
18470
+ 0,
18471
+ 0,
18472
+ 0,
18473
+ 0,
18474
+ 0,
18475
+ 0,
18476
+ 0,
18477
+ 0,
18478
+ 0,
18479
+ 0,
18480
+ 0,
18481
+ 0,
18482
+ 0,
18483
+ 0,
18484
+ 0,
18485
+ 0,
18486
+ 0,
18487
+ 0,
18488
+ 0,
18489
+ 0,
18490
+ 0,
18491
+ 0,
18492
+ 0,
18493
+ 0,
18494
+ 0,
18495
+ 0,
18496
+ 0,
18497
+ 0,
18498
+ 0,
18499
+ 0,
18500
+ 0,
18501
+ 0,
18502
+ 0,
18503
+ 0,
18504
+ 0,
18505
+ 0,
18506
+ 0,
18507
+ 0,
18508
+ 0,
18509
+ 1,
18510
+ 1,
18511
+ 1,
18512
+ 1,
18513
+ 1,
18514
+ 1,
18515
+ 1,
18516
+ 1,
18517
+ 1,
18518
+ 1,
18519
+ 0,
18520
+ 0,
18521
+ 0,
18522
+ 0,
18523
+ 0,
18524
+ 0,
18525
+ 0,
18526
+ 1,
18527
+ 1,
18528
+ 1,
18529
+ 1,
18530
+ 1,
18531
+ 1,
18532
+ 0,
18533
+ 0,
18534
+ 0,
18535
+ 0,
18536
+ 0,
18537
+ 0,
18538
+ 0,
18539
+ 0,
18540
+ 0,
18541
+ 0,
18542
+ 0,
18543
+ 0,
18544
+ 0,
18545
+ 0,
18546
+ 0,
18547
+ 0,
18548
+ 0,
18549
+ 0,
18550
+ 0,
18551
+ 0,
18552
+ 0,
18553
+ 0,
18554
+ 0,
18555
+ 0,
18556
+ 0,
18557
+ 0,
18558
+ 1,
18559
+ 1,
18560
+ 1,
18561
+ 1,
18562
+ 1,
18563
+ 1
18564
+ ]);
18565
+ function isValidHex(id, length) {
18566
+ if (typeof id !== "string" || id.length !== length) return false;
18567
+ let r = 0;
18568
+ for (let i = 0; i < id.length; i += 4) r += (isHex[id.charCodeAt(i)] | 0) + (isHex[id.charCodeAt(i + 1)] | 0) + (isHex[id.charCodeAt(i + 2)] | 0) + (isHex[id.charCodeAt(i + 3)] | 0);
18569
+ return r === length;
18570
+ }
18571
+ /**
18572
+ * @since 1.0.0
18573
+ */
18574
+ function isValidTraceId(traceId) {
18575
+ return isValidHex(traceId, 32) && traceId !== INVALID_TRACEID;
18576
+ }
18577
+ /**
18578
+ * @since 1.0.0
18579
+ */
18580
+ function isValidSpanId(spanId) {
18581
+ return isValidHex(spanId, 16) && spanId !== INVALID_SPANID;
18582
+ }
18583
+ /**
18584
+ * Returns true if this {@link SpanContext} is valid.
18585
+ * @return true if this {@link SpanContext} is valid.
18586
+ *
18587
+ * @since 1.0.0
18588
+ */
18589
+ function isSpanContextValid(spanContext) {
18590
+ return isValidTraceId(spanContext.traceId) && isValidSpanId(spanContext.spanId);
18591
+ }
18592
+ /**
18593
+ * Wrap the given {@link SpanContext} in a new non-recording {@link Span}
18594
+ *
18595
+ * @param spanContext span context to be wrapped
18596
+ * @returns a new non-recording {@link Span} with the provided context
18597
+ */
18598
+ function wrapSpanContext(spanContext) {
18599
+ return new NonRecordingSpan(spanContext);
18600
+ }
18601
+
18602
+ //#endregion
18603
+ //#region ../../node_modules/@opentelemetry/api/build/esm/trace/NoopTracer.js
18604
+ const contextApi = ContextAPI.getInstance();
18605
+ /**
18606
+ * No-op implementations of {@link Tracer}.
18607
+ */
18608
+ var NoopTracer = class {
18609
+ startSpan(name, options, context = contextApi.active()) {
18610
+ if (Boolean(options === null || options === void 0 ? void 0 : options.root)) return new NonRecordingSpan();
18611
+ const parentFromContext = context && getSpanContext(context);
18612
+ if (isSpanContext(parentFromContext) && isSpanContextValid(parentFromContext)) return new NonRecordingSpan(parentFromContext);
18613
+ else return new NonRecordingSpan();
18614
+ }
18615
+ startActiveSpan(name, arg2, arg3, arg4) {
18616
+ let opts;
18617
+ let ctx;
18618
+ let fn;
18619
+ if (arguments.length < 2) return;
18620
+ else if (arguments.length === 2) fn = arg2;
18621
+ else if (arguments.length === 3) {
18622
+ opts = arg2;
18623
+ fn = arg3;
18624
+ } else {
18625
+ opts = arg2;
18626
+ ctx = arg3;
18627
+ fn = arg4;
18628
+ }
18629
+ const parentContext = ctx !== null && ctx !== void 0 ? ctx : contextApi.active();
18630
+ const span = this.startSpan(name, opts, parentContext);
18631
+ const contextWithSpanSet = setSpan(parentContext, span);
18632
+ return contextApi.with(contextWithSpanSet, fn, void 0, span);
18633
+ }
18634
+ };
18635
+ function isSpanContext(spanContext) {
18636
+ return spanContext !== null && typeof spanContext === "object" && "spanId" in spanContext && typeof spanContext["spanId"] === "string" && "traceId" in spanContext && typeof spanContext["traceId"] === "string" && "traceFlags" in spanContext && typeof spanContext["traceFlags"] === "number";
18637
+ }
18638
+
18639
+ //#endregion
18640
+ //#region ../../node_modules/@opentelemetry/api/build/esm/trace/ProxyTracer.js
18641
+ const NOOP_TRACER = new NoopTracer();
18642
+ /**
18643
+ * Proxy tracer provided by the proxy tracer provider
18644
+ *
18645
+ * @since 1.0.0
18646
+ */
18647
+ var ProxyTracer = class {
18648
+ constructor(provider, name, version, options) {
18649
+ this._provider = provider;
18650
+ this.name = name;
18651
+ this.version = version;
18652
+ this.options = options;
18653
+ }
18654
+ startSpan(name, options, context) {
18655
+ return this._getTracer().startSpan(name, options, context);
18656
+ }
18657
+ startActiveSpan(_name, _options, _context, _fn) {
18658
+ const tracer = this._getTracer();
18659
+ return Reflect.apply(tracer.startActiveSpan, tracer, arguments);
18660
+ }
18661
+ /**
18662
+ * Try to get a tracer from the proxy tracer provider.
18663
+ * If the proxy tracer provider has no delegate, return a noop tracer.
18664
+ */
18665
+ _getTracer() {
18666
+ if (this._delegate) return this._delegate;
18667
+ const tracer = this._provider.getDelegateTracer(this.name, this.version, this.options);
18668
+ if (!tracer) return NOOP_TRACER;
18669
+ this._delegate = tracer;
18670
+ return this._delegate;
18671
+ }
18672
+ };
18673
+
18674
+ //#endregion
18675
+ //#region ../../node_modules/@opentelemetry/api/build/esm/trace/NoopTracerProvider.js
18676
+ /**
18677
+ * An implementation of the {@link TracerProvider} which returns an impotent
18678
+ * Tracer for all calls to `getTracer`.
18679
+ *
18680
+ * All operations are no-op.
18681
+ */
18682
+ var NoopTracerProvider = class {
18683
+ getTracer(_name, _version, _options) {
18684
+ return new NoopTracer();
18685
+ }
18686
+ };
18687
+
18688
+ //#endregion
18689
+ //#region ../../node_modules/@opentelemetry/api/build/esm/trace/ProxyTracerProvider.js
18690
+ const NOOP_TRACER_PROVIDER = new NoopTracerProvider();
18691
+ /**
18692
+ * Tracer provider which provides {@link ProxyTracer}s.
18693
+ *
18694
+ * Before a delegate is set, tracers provided are NoOp.
18695
+ * When a delegate is set, traces are provided from the delegate.
18696
+ * When a delegate is set after tracers have already been provided,
18697
+ * all tracers already provided will use the provided delegate implementation.
18698
+ *
18699
+ * @deprecated This will be removed in the next major version.
18700
+ * @since 1.0.0
18701
+ */
18702
+ var ProxyTracerProvider = class {
18703
+ /**
18704
+ * Get a {@link ProxyTracer}
18705
+ */
18706
+ getTracer(name, version, options) {
18707
+ var _a;
18708
+ return (_a = this.getDelegateTracer(name, version, options)) !== null && _a !== void 0 ? _a : new ProxyTracer(this, name, version, options);
18709
+ }
18710
+ getDelegate() {
18711
+ var _a;
18712
+ return (_a = this._delegate) !== null && _a !== void 0 ? _a : NOOP_TRACER_PROVIDER;
18713
+ }
18714
+ /**
18715
+ * Set the delegate tracer provider
18716
+ */
18717
+ setDelegate(delegate) {
18718
+ this._delegate = delegate;
18719
+ }
18720
+ getDelegateTracer(name, version, options) {
18721
+ var _a;
18722
+ return (_a = this._delegate) === null || _a === void 0 ? void 0 : _a.getTracer(name, version, options);
18723
+ }
18724
+ };
18725
+
18726
+ //#endregion
18727
+ //#region ../../node_modules/@opentelemetry/api/build/esm/trace/span_kind.js
18728
+ /**
18729
+ * @since 1.0.0
18730
+ */
18731
+ var SpanKind;
18732
+ (function(SpanKind) {
18733
+ /** Default value. Indicates that the span is used internally. */
18734
+ SpanKind[SpanKind["INTERNAL"] = 0] = "INTERNAL";
18735
+ /**
18736
+ * Indicates that the span covers server-side handling of an RPC or other
18737
+ * remote request.
18738
+ */
18739
+ SpanKind[SpanKind["SERVER"] = 1] = "SERVER";
18740
+ /**
18741
+ * Indicates that the span covers the client-side wrapper around an RPC or
18742
+ * other remote request.
18743
+ */
18744
+ SpanKind[SpanKind["CLIENT"] = 2] = "CLIENT";
18745
+ /**
18746
+ * Indicates that the span describes producer sending a message to a
18747
+ * broker. Unlike client and server, there is no direct critical path latency
18748
+ * relationship between producer and consumer spans.
18749
+ */
18750
+ SpanKind[SpanKind["PRODUCER"] = 3] = "PRODUCER";
18751
+ /**
18752
+ * Indicates that the span describes consumer receiving a message from a
18753
+ * broker. Unlike client and server, there is no direct critical path latency
18754
+ * relationship between producer and consumer spans.
18755
+ */
18756
+ SpanKind[SpanKind["CONSUMER"] = 4] = "CONSUMER";
18757
+ })(SpanKind || (SpanKind = {}));
18758
+
18759
+ //#endregion
18760
+ //#region ../../node_modules/@opentelemetry/api/build/esm/trace/status.js
18761
+ /**
18762
+ * An enumeration of status codes.
18763
+ *
18764
+ * @since 1.0.0
18765
+ */
18766
+ var SpanStatusCode;
18767
+ (function(SpanStatusCode) {
18768
+ /**
18769
+ * The default status.
18770
+ */
18771
+ SpanStatusCode[SpanStatusCode["UNSET"] = 0] = "UNSET";
18772
+ /**
18773
+ * The operation has been validated by an Application developer or
18774
+ * Operator to have completed successfully.
18775
+ */
18776
+ SpanStatusCode[SpanStatusCode["OK"] = 1] = "OK";
18777
+ /**
18778
+ * The operation contains an error.
18779
+ */
18780
+ SpanStatusCode[SpanStatusCode["ERROR"] = 2] = "ERROR";
18781
+ })(SpanStatusCode || (SpanStatusCode = {}));
18782
+
18783
+ //#endregion
18784
+ //#region ../../node_modules/@opentelemetry/api/build/esm/api/trace.js
18785
+ const API_NAME = "trace";
18786
+ /**
18787
+ * Singleton object which represents the entry point to the OpenTelemetry Tracing API
18788
+ *
18789
+ * @since 1.0.0
18790
+ */
18791
+ var TraceAPI = class TraceAPI {
18792
+ /** Empty private constructor prevents end users from constructing a new instance of the API */
18793
+ constructor() {
18794
+ this._proxyTracerProvider = new ProxyTracerProvider();
18795
+ this.wrapSpanContext = wrapSpanContext;
18796
+ this.isSpanContextValid = isSpanContextValid;
18797
+ this.deleteSpan = deleteSpan;
18798
+ this.getSpan = getSpan;
18799
+ this.getActiveSpan = getActiveSpan;
18800
+ this.getSpanContext = getSpanContext;
18801
+ this.setSpan = setSpan;
18802
+ this.setSpanContext = setSpanContext;
18803
+ }
18804
+ /** Get the singleton instance of the Trace API */
18805
+ static getInstance() {
18806
+ if (!this._instance) this._instance = new TraceAPI();
18807
+ return this._instance;
18808
+ }
18809
+ /**
18810
+ * Set the current global tracer.
18811
+ *
18812
+ * @returns true if the tracer provider was successfully registered, else false
18813
+ */
18814
+ setGlobalTracerProvider(provider) {
18815
+ const success = registerGlobal(API_NAME, this._proxyTracerProvider, DiagAPI.instance());
18816
+ if (success) this._proxyTracerProvider.setDelegate(provider);
18817
+ return success;
18818
+ }
18819
+ /**
18820
+ * Returns the global tracer provider.
18821
+ */
18822
+ getTracerProvider() {
18823
+ return getGlobal(API_NAME) || this._proxyTracerProvider;
18824
+ }
18825
+ /**
18826
+ * Returns a tracer from the global tracer provider.
18827
+ */
18828
+ getTracer(name, version) {
18829
+ return this.getTracerProvider().getTracer(name, version);
18830
+ }
18831
+ /** Remove the global tracer provider */
18832
+ disable() {
18833
+ unregisterGlobal(API_NAME, DiagAPI.instance());
18834
+ this._proxyTracerProvider = new ProxyTracerProvider();
18835
+ }
18836
+ };
18837
+
18838
+ //#endregion
18839
+ //#region ../../node_modules/@opentelemetry/api/build/esm/trace-api.js
18840
+ /**
18841
+ * Entrypoint for trace API
18842
+ *
18843
+ * @since 1.0.0
18844
+ */
18845
+ const trace = TraceAPI.getInstance();
18846
+
18847
+ //#endregion
18848
+ //#region ../../node_modules/@arizeai/openinference-semantic-conventions/dist/esm/trace/SemanticConventions.js
18849
+ /**
18850
+ * Semantic conventions for OpenInference tracing
18851
+ */
18852
+ const SemanticAttributePrefixes = {
18853
+ input: "input",
18854
+ output: "output",
18855
+ llm: "llm",
18856
+ retrieval: "retrieval",
18857
+ reranker: "reranker",
18858
+ messages: "messages",
18859
+ message: "message",
18860
+ document: "document",
18861
+ embedding: "embedding",
18862
+ tool: "tool",
18863
+ tool_call: "tool_call",
18864
+ metadata: "metadata",
18865
+ tag: "tag",
18866
+ session: "session",
18867
+ user: "user",
18868
+ openinference: "openinference",
18869
+ message_content: "message_content",
18870
+ image: "image",
18871
+ audio: "audio",
18872
+ prompt: "prompt",
18873
+ agent: "agent",
18874
+ graph: "graph"
18875
+ };
18876
+ const LLMAttributePostfixes = {
18877
+ provider: "provider",
18878
+ system: "system",
18879
+ model_name: "model_name",
18880
+ token_count: "token_count",
18881
+ input_messages: "input_messages",
18882
+ output_messages: "output_messages",
18883
+ invocation_parameters: "invocation_parameters",
18884
+ prompts: "prompts",
18885
+ prompt_template: "prompt_template",
18886
+ function_call: "function_call",
18887
+ tools: "tools",
18888
+ cost: "cost",
18889
+ finish_reason: "finish_reason"
18890
+ };
18891
+ const RetrievalAttributePostfixes = { documents: "documents" };
18892
+ const RerankerAttributePostfixes = {
18893
+ input_documents: "input_documents",
18894
+ output_documents: "output_documents",
18895
+ query: "query",
18896
+ model_name: "model_name",
18897
+ top_k: "top_k"
18898
+ };
18899
+ const EmbeddingAttributePostfixes = {
18900
+ embeddings: "embeddings",
18901
+ text: "text",
18902
+ model_name: "model_name",
18903
+ vector: "vector"
18904
+ };
18905
+ const ToolAttributePostfixes = {
18906
+ name: "name",
18907
+ description: "description",
18908
+ parameters: "parameters",
18909
+ json_schema: "json_schema",
18910
+ id: "id"
18911
+ };
18912
+ const MessageAttributePostfixes = {
18913
+ role: "role",
18914
+ content: "content",
18915
+ contents: "contents",
18916
+ name: "name",
18917
+ function_call_name: "function_call_name",
18918
+ function_call_arguments_json: "function_call_arguments_json",
18919
+ tool_calls: "tool_calls",
18920
+ tool_call_id: "tool_call_id"
18921
+ };
18922
+ const MessageContentsAttributePostfixes = {
18923
+ type: "type",
18924
+ text: "text",
18925
+ image: "image",
18926
+ id: "id",
18927
+ signature: "signature",
18928
+ data: "data",
18929
+ encrypted_content: "encrypted_content"
18930
+ };
18931
+ const ImageAttributesPostfixes = { url: "url" };
18932
+ const ToolCallAttributePostfixes = {
18933
+ function_name: "function.name",
18934
+ function_arguments_json: "function.arguments",
18935
+ id: "id",
18936
+ reasoning_signature: "reasoning_signature"
18937
+ };
18938
+ const DocumentAttributePostfixes = {
18939
+ id: "id",
18940
+ content: "content",
18941
+ score: "score",
18942
+ metadata: "metadata"
18943
+ };
18944
+ const TagAttributePostfixes = { tags: "tags" };
18945
+ const SessionAttributePostfixes = { id: "id" };
18946
+ const UserAttributePostfixes = { id: "id" };
18947
+ const AudioAttributesPostfixes = {
18948
+ url: "url",
18949
+ mime_type: "mime_type",
18950
+ transcript: "transcript"
18951
+ };
18952
+ const PromptAttributePostfixes = {
18953
+ vendor: "vendor",
18954
+ id: "id",
18955
+ url: "url"
18956
+ };
18957
+ const AgentPostfixes = { name: "name" };
18958
+ const GraphPostfixes = {
18959
+ node_id: "node.id",
18960
+ node_name: "node.name",
18961
+ node_parent_id: "node.parent_id"
18962
+ };
18963
+ /**
18964
+ * The input to any span
18965
+ */
18966
+ const INPUT_VALUE = `${SemanticAttributePrefixes.input}.value`;
18967
+ const INPUT_MIME_TYPE = `${SemanticAttributePrefixes.input}.mime_type`;
18968
+ /**
18969
+ * The output of any span
18970
+ */
18971
+ const OUTPUT_VALUE = `${SemanticAttributePrefixes.output}.value`;
18972
+ const OUTPUT_MIME_TYPE = `${SemanticAttributePrefixes.output}.mime_type`;
18973
+ /**
18974
+ * The messages sent to the LLM for completions
18975
+ * Typically seen in OpenAI chat completions
18976
+ * @see https://beta.openai.com/docs/api-reference/completions/create
18977
+ */
18978
+ const LLM_INPUT_MESSAGES = `${SemanticAttributePrefixes.llm}.${LLMAttributePostfixes.input_messages}`;
18979
+ /**
18980
+ * The prompts sent to the LLM for completions
18981
+ * Typically seen in OpenAI legacy completions
18982
+ * @see https://beta.openai.com/docs/api-reference/completions/create
18983
+ */
18984
+ const LLM_PROMPTS = `${SemanticAttributePrefixes.llm}.${LLMAttributePostfixes.prompts}`;
18985
+ /**
18986
+ * The JSON representation of the parameters passed to the LLM
18987
+ */
18988
+ const LLM_INVOCATION_PARAMETERS = `${SemanticAttributePrefixes.llm}.${LLMAttributePostfixes.invocation_parameters}`;
18989
+ /**
18990
+ * The messages received from the LLM for completions
18991
+ * Typically seen in OpenAI chat completions
18992
+ * @see https://platform.openai.com/docs/api-reference/chat/object#choices-message
18993
+ */
18994
+ const LLM_OUTPUT_MESSAGES = `${SemanticAttributePrefixes.llm}.${LLMAttributePostfixes.output_messages}`;
18995
+ /**
18996
+ * The name of the LLM model
18997
+ */
18998
+ const LLM_MODEL_NAME = `${SemanticAttributePrefixes.llm}.${LLMAttributePostfixes.model_name}`;
18999
+ /**
19000
+ * The provider of the inferences. E.g. the cloud provider
19001
+ */
19002
+ const LLM_PROVIDER = `${SemanticAttributePrefixes.llm}.${LLMAttributePostfixes.provider}`;
19003
+ /**
19004
+ * The AI product as identified by the client or server
19005
+ */
19006
+ const LLM_SYSTEM = `${SemanticAttributePrefixes.llm}.${LLMAttributePostfixes.system}`;
19007
+ /** Token count for the completion by the llm (in tokens) */
19008
+ const LLM_TOKEN_COUNT_COMPLETION = `${SemanticAttributePrefixes.llm}.${LLMAttributePostfixes.token_count}.completion`;
19009
+ /** Token count for the reasoning steps in the completion (in tokens) */
19010
+ const LLM_TOKEN_COUNT_COMPLETION_DETAILS_REASONING = `${SemanticAttributePrefixes.llm}.${LLMAttributePostfixes.token_count}.completion_details.reasoning`;
19011
+ /** Token count for audio input generated by the model (in tokens) */
19012
+ const LLM_TOKEN_COUNT_COMPLETION_DETAILS_AUDIO = `${SemanticAttributePrefixes.llm}.${LLMAttributePostfixes.token_count}.completion_details.audio`;
19013
+ /** Token count for the prompt to the llm (in tokens) */
19014
+ const LLM_TOKEN_COUNT_PROMPT = `${SemanticAttributePrefixes.llm}.${LLMAttributePostfixes.token_count}.prompt`;
19015
+ /** Token count for the tokens written to cache (in tokens) */
19016
+ const LLM_TOKEN_COUNT_PROMPT_DETAILS_CACHE_WRITE = `${SemanticAttributePrefixes.llm}.${LLMAttributePostfixes.token_count}.prompt_details.cache_write`;
19017
+ /** Token count for the tokens retrieved from cache (in tokens) */
19018
+ const LLM_TOKEN_COUNT_PROMPT_DETAILS_CACHE_READ = `${SemanticAttributePrefixes.llm}.${LLMAttributePostfixes.token_count}.prompt_details.cache_read`;
19019
+ /** Token count for the input tokens in the prompt that were cached (in tokens) */
19020
+ const LLM_TOKEN_COUNT_PROMPT_DETAILS_CACHE_INPUT = `${SemanticAttributePrefixes.llm}.${LLMAttributePostfixes.token_count}.prompt_details.cache_input`;
19021
+ /** Token count for audio input presented in the prompt (in tokens) */
19022
+ const LLM_TOKEN_COUNT_PROMPT_DETAILS_AUDIO = `${SemanticAttributePrefixes.llm}.${LLMAttributePostfixes.token_count}.prompt_details.audio`;
19023
+ /** Token count for the entire transaction with the llm (in tokens) */
19024
+ const LLM_TOKEN_COUNT_TOTAL = `${SemanticAttributePrefixes.llm}.${LLMAttributePostfixes.token_count}.total`;
19025
+ /**
19026
+ * The reason the model stopped generating tokens, e.g. `"stop"` or `"length"`.
19027
+ */
19028
+ const LLM_FINISH_REASON = `${SemanticAttributePrefixes.llm}.${LLMAttributePostfixes.finish_reason}`;
19029
+ /**
19030
+ * Key prefix for additional prompt token count details. Each detail should be a separate attribute
19031
+ * with this prefix, e.g. llm.token_count.prompt_details.reasoning, llm.token_count.prompt_details.audio.
19032
+ * All values should be in tokens (integer count of tokens).
19033
+ */
19034
+ const LLM_TOKEN_COUNT_PROMPT_DETAILS = `${SemanticAttributePrefixes.llm}.${LLMAttributePostfixes.token_count}.prompt_details`;
19035
+ /**
19036
+ * Key prefix for additional completion token count details. Each detail should be a separate attribute
19037
+ * with this prefix, e.g. llm.token_count.completion_details.reasoning, llm.token_count.completion_details.audio.
19038
+ * All values should be in tokens (integer count of tokens).
19039
+ */
19040
+ const LLM_TOKEN_COUNT_COMPLETION_DETAILS = `${SemanticAttributePrefixes.llm}.${LLMAttributePostfixes.token_count}.completion_details`;
19041
+ /**
19042
+ * Key prefix for cost information. When these keys are transformed into a JSON-like structure, it would look like:
19043
+ * {
19044
+ * "prompt": 0.0021, # Cost in USD
19045
+ * "completion": 0.0045, # Cost in USD
19046
+ * "total": 0.0066, # Cost in USD
19047
+ * "completion_details": {
19048
+ * "output": 0.0009, # Cost in USD
19049
+ * "reasoning": 0.0024, # Cost in USD (e.g., 80 tokens * $0.03/1K tokens)
19050
+ * "audio": 0.0012 # Cost in USD (e.g., 40 tokens * $0.03/1K tokens)
19051
+ * },
19052
+ * "prompt_details": {
19053
+ * "input": 0.0003, # Cost in USD
19054
+ * "cache_write": 0.0006, # Cost in USD (e.g., 20 tokens * $0.03/1K tokens)
19055
+ * "cache_read": 0.0003, # Cost in USD (e.g., 10 tokens * $0.03/1K tokens)
19056
+ * "cache_input": 0.0006, # Cost in USD (e.g., 20 tokens * $0.03/1K tokens)
19057
+ * "audio": 0.0003 # Cost in USD (e.g., 10 tokens * $0.03/1K tokens)
19058
+ * }
19059
+ * }
19060
+ * Note: This is a key prefix - individual attributes are stored as separate span attributes with this prefix,
19061
+ * e.g. llm.cost.prompt, llm.cost.completion_details.reasoning, etc. The JSON structure shown above represents
19062
+ * how these separate attributes can be conceptually organized.
19063
+ * All monetary values are in USD with floating point precision.
19064
+ */
19065
+ const LLM_COST = `${SemanticAttributePrefixes.llm}.${LLMAttributePostfixes.cost}`;
19066
+ /** Cost of the prompt tokens in USD */
19067
+ const LLM_COST_PROMPT = `${SemanticAttributePrefixes.llm}.${LLMAttributePostfixes.cost}.prompt`;
19068
+ /** Cost of the completion tokens in USD */
19069
+ const LLM_COST_COMPLETION = `${SemanticAttributePrefixes.llm}.${LLMAttributePostfixes.cost}.completion`;
19070
+ /** Total cost of the LLM call in USD (prompt + completion) */
19071
+ const LLM_COST_TOTAL = `${SemanticAttributePrefixes.llm}.${LLMAttributePostfixes.cost}.total`;
19072
+ /** Total cost of input tokens in USD. This represents the cost of tokens that were used as input
19073
+ * to the model, which may be different from the prompt cost if there are additional processing steps. */
19074
+ const LLM_COST_INPUT = `${SemanticAttributePrefixes.llm}.${LLMAttributePostfixes.cost}.prompt_details.input`;
19075
+ /** Total cost of output tokens in USD. This represents the cost of tokens that were generated as output
19076
+ * by the model, which may be different from the completion cost if there are additional processing steps. */
19077
+ const LLM_COST_OUTPUT = `${SemanticAttributePrefixes.llm}.${LLMAttributePostfixes.cost}.completion_details.output`;
19078
+ /** Cost of reasoning steps in the completion in USD */
19079
+ const LLM_COST_COMPLETION_DETAILS_REASONING = `${SemanticAttributePrefixes.llm}.${LLMAttributePostfixes.cost}.completion_details.reasoning`;
19080
+ /** Cost of audio tokens in the completion in USD */
19081
+ const LLM_COST_COMPLETION_DETAILS_AUDIO = `${SemanticAttributePrefixes.llm}.${LLMAttributePostfixes.cost}.completion_details.audio`;
19082
+ /** Cost of prompt tokens written to cache in USD */
19083
+ const LLM_COST_PROMPT_DETAILS_CACHE_WRITE = `${SemanticAttributePrefixes.llm}.${LLMAttributePostfixes.cost}.prompt_details.cache_write`;
19084
+ /** Cost of prompt tokens read from cache in USD */
19085
+ const LLM_COST_PROMPT_DETAILS_CACHE_READ = `${SemanticAttributePrefixes.llm}.${LLMAttributePostfixes.cost}.prompt_details.cache_read`;
19086
+ /** Cost of input tokens in the prompt that were cached in USD */
19087
+ const LLM_COST_PROMPT_DETAILS_CACHE_INPUT = `${SemanticAttributePrefixes.llm}.${LLMAttributePostfixes.cost}.prompt_details.cache_input`;
19088
+ /** Cost of audio tokens in the prompt in USD */
19089
+ const LLM_COST_PROMPT_DETAILS_AUDIO = `${SemanticAttributePrefixes.llm}.${LLMAttributePostfixes.cost}.prompt_details.audio`;
19090
+ /**
19091
+ * The role that the LLM assumes the message is from
19092
+ * during the LLM invocation
19093
+ */
19094
+ const MESSAGE_ROLE = `${SemanticAttributePrefixes.message}.${MessageAttributePostfixes.role}`;
19095
+ /**
19096
+ * The name of the message. This is only used for role 'function' where the name
19097
+ * of the function is captured in the name field and the parameters are captured in the
19098
+ * content.
19099
+ */
19100
+ const MESSAGE_NAME = `${SemanticAttributePrefixes.message}.${MessageAttributePostfixes.name}`;
19101
+ /**
19102
+ * The tool calls generated by the model, such as function calls.
19103
+ */
19104
+ const MESSAGE_TOOL_CALLS = `${SemanticAttributePrefixes.message}.${MessageAttributePostfixes.tool_calls}`;
19105
+ /**
19106
+ * The id of the tool call on a "tool" role message
19107
+ */
19108
+ const MESSAGE_TOOL_CALL_ID = `${SemanticAttributePrefixes.message}.${MessageAttributePostfixes.tool_call_id}`;
19109
+ /**
19110
+ * tool_call.function.name
19111
+ */
19112
+ const TOOL_CALL_FUNCTION_NAME = `${SemanticAttributePrefixes.tool_call}.${ToolCallAttributePostfixes.function_name}`;
19113
+ /**
19114
+ * tool_call.function.argument (JSON string)
19115
+ */
19116
+ const TOOL_CALL_FUNCTION_ARGUMENTS_JSON = `${SemanticAttributePrefixes.tool_call}.${ToolCallAttributePostfixes.function_arguments_json}`;
19117
+ /**
19118
+ * The id of the tool call
19119
+ */
19120
+ const TOOL_CALL_ID = `${SemanticAttributePrefixes.tool_call}.${ToolCallAttributePostfixes.id}`;
19121
+ /**
19122
+ * Opaque vendor-issued reasoning echo token attached to a tool call. Maps to
19123
+ * Gemini thoughtSignature when it is attached to a functionCall part
19124
+ */
19125
+ const TOOL_CALL_REASONING_SIGNATURE = `${SemanticAttributePrefixes.tool_call}.${ToolCallAttributePostfixes.reasoning_signature}`;
19126
+ /**
19127
+ * The LLM function call function name
19128
+ */
19129
+ const MESSAGE_FUNCTION_CALL_NAME = `${SemanticAttributePrefixes.message}.${MessageAttributePostfixes.function_call_name}`;
19130
+ /**
19131
+ * The LLM function call function arguments in a json string
19132
+ */
19133
+ const MESSAGE_FUNCTION_CALL_ARGUMENTS_JSON = `${SemanticAttributePrefixes.message}.${MessageAttributePostfixes.function_call_arguments_json}`;
19134
+ /**
19135
+ * The content of the message sent to the LLM
19136
+ */
19137
+ const MESSAGE_CONTENT = `${SemanticAttributePrefixes.message}.${MessageAttributePostfixes.content}`;
19138
+ /**
19139
+ * The array of contents for the message sent to the LLM. Each element of the array is
19140
+ * an `message_content` object.
19141
+ */
19142
+ const MESSAGE_CONTENTS = `${SemanticAttributePrefixes.message}.${MessageAttributePostfixes.contents}`;
19143
+ /**
19144
+ * The type of content sent to the LLM, such as "text", "image", "audio",
19145
+ * "reasoning", or "tool_use"
19146
+ */
19147
+ const MESSAGE_CONTENT_TYPE = `${SemanticAttributePrefixes.message_content}.${MessageContentsAttributePostfixes.type}`;
19148
+ /**
19149
+ * The text content of the message sent to the LLM
19150
+ */
19151
+ const MESSAGE_CONTENT_TEXT = `${SemanticAttributePrefixes.message_content}.${MessageContentsAttributePostfixes.text}`;
19152
+ /**
19153
+ * The image content of the message sent to the LLM
19154
+ */
19155
+ const MESSAGE_CONTENT_IMAGE = `${SemanticAttributePrefixes.message_content}.${MessageContentsAttributePostfixes.image}`;
19156
+ /**
19157
+ * Provider-assigned identifier for this message content item. For OpenAI
19158
+ * Responses reasoning items, this maps to ResponseReasoningItem.id and should
19159
+ * be preserved for stateless replay
19160
+ */
19161
+ const MESSAGE_CONTENT_ID = `${SemanticAttributePrefixes.message_content}.${MessageContentsAttributePostfixes.id}`;
19162
+ /**
19163
+ * Opaque vendor-issued signature captured verbatim. Maps to provider signature
19164
+ * fields and to Gemini thoughtSignature fields when the signature is attached
19165
+ * to a non-tool content part
19166
+ */
19167
+ const MESSAGE_CONTENT_SIGNATURE = `${SemanticAttributePrefixes.message_content}.${MessageContentsAttributePostfixes.signature}`;
19168
+ /**
19169
+ * Opaque vendor-issued data captured verbatim. Maps to Anthropic
19170
+ * redacted_thinking.data
19171
+ */
19172
+ const MESSAGE_CONTENT_DATA = `${SemanticAttributePrefixes.message_content}.${MessageContentsAttributePostfixes.data}`;
19173
+ /**
19174
+ * OpenAI encrypted_content captured verbatim
19175
+ */
19176
+ const MESSAGE_CONTENT_ENCRYPTED_CONTENT = `${SemanticAttributePrefixes.message_content}.${MessageContentsAttributePostfixes.encrypted_content}`;
19177
+ /**
19178
+ * The http or base64 link to the image
19179
+ */
19180
+ const IMAGE_URL = `${SemanticAttributePrefixes.image}.${ImageAttributesPostfixes.url}`;
19181
+ const DOCUMENT_ID = `${SemanticAttributePrefixes.document}.${DocumentAttributePostfixes.id}`;
19182
+ const DOCUMENT_CONTENT = `${SemanticAttributePrefixes.document}.${DocumentAttributePostfixes.content}`;
19183
+ const DOCUMENT_SCORE = `${SemanticAttributePrefixes.document}.${DocumentAttributePostfixes.score}`;
19184
+ const DOCUMENT_METADATA = `${SemanticAttributePrefixes.document}.${DocumentAttributePostfixes.metadata}`;
19185
+ /**
19186
+ * The text that was embedded to create the vector
19187
+ */
19188
+ const EMBEDDING_TEXT = `${SemanticAttributePrefixes.embedding}.${EmbeddingAttributePostfixes.text}`;
19189
+ /**
19190
+ * The name of the model that was used to create the vector
19191
+ */
19192
+ const EMBEDDING_MODEL_NAME = `${SemanticAttributePrefixes.embedding}.${EmbeddingAttributePostfixes.model_name}`;
19193
+ /**
19194
+ * The embedding vector. Typically a high dimensional vector of floats or ints
19195
+ */
19196
+ const EMBEDDING_VECTOR = `${SemanticAttributePrefixes.embedding}.${EmbeddingAttributePostfixes.vector}`;
19197
+ /**
19198
+ * The embedding list root
19199
+ */
19200
+ const EMBEDDING_EMBEDDINGS = `${SemanticAttributePrefixes.embedding}.${EmbeddingAttributePostfixes.embeddings}`;
19201
+ /**
19202
+ * The retrieval documents list root
19203
+ */
19204
+ const RETRIEVAL_DOCUMENTS = `${SemanticAttributePrefixes.retrieval}.${RetrievalAttributePostfixes.documents}`;
19205
+ const PROMPT_TEMPLATE_PREFIX = `${SemanticAttributePrefixes.llm}.${LLMAttributePostfixes.prompt_template}`;
19206
+ /**
19207
+ * The JSON representation of the variables used in the prompt template
19208
+ */
19209
+ const PROMPT_TEMPLATE_VARIABLES = `${PROMPT_TEMPLATE_PREFIX}.variables`;
19210
+ /**
19211
+ * A prompt template
19212
+ */
19213
+ const PROMPT_TEMPLATE_TEMPLATE = `${PROMPT_TEMPLATE_PREFIX}.template`;
19214
+ /**
19215
+ * The JSON representation of a function call of an LLM
19216
+ */
19217
+ const LLM_FUNCTION_CALL = `${SemanticAttributePrefixes.llm}.${LLMAttributePostfixes.function_call}`;
19218
+ /**
19219
+ * List of tools that are advertised to the LLM to be able to call
19220
+ */
19221
+ const LLM_TOOLS = `${SemanticAttributePrefixes.llm}.${LLMAttributePostfixes.tools}`;
19222
+ /**
19223
+ * The name of a tool
19224
+ */
19225
+ const TOOL_NAME$1 = `${SemanticAttributePrefixes.tool}.${ToolAttributePostfixes.name}`;
19226
+ /**
19227
+ * The description of a tool
19228
+ */
19229
+ const TOOL_DESCRIPTION = `${SemanticAttributePrefixes.tool}.${ToolAttributePostfixes.description}`;
19230
+ /**
19231
+ * The parameters of the tool represented as a JSON string
19232
+ */
19233
+ const TOOL_PARAMETERS = `${SemanticAttributePrefixes.tool}.${ToolAttributePostfixes.parameters}`;
19234
+ /**
19235
+ * The json schema of a tool input, It is RECOMMENDED that this be in the
19236
+ * OpenAI tool calling format: https://platform.openai.com/docs/assistants/tools
19237
+ */
19238
+ const TOOL_JSON_SCHEMA = `${SemanticAttributePrefixes.tool}.${ToolAttributePostfixes.json_schema}`;
19239
+ /**
19240
+ * The identifier for the result of the tool call (corresponding to tool_call.id).
19241
+ */
19242
+ const TOOL_ID = `${SemanticAttributePrefixes.tool}.${ToolAttributePostfixes.id}`;
19243
+ /**
19244
+ * The session id of a trace. Used to correlate spans in a single session.
19245
+ */
19246
+ const SESSION_ID = `${SemanticAttributePrefixes.session}.${SessionAttributePostfixes.id}`;
19247
+ /**
19248
+ * The user id of a trace. Used to correlate spans for a single user.
19249
+ */
19250
+ const USER_ID = `${SemanticAttributePrefixes.user}.${UserAttributePostfixes.id}`;
19251
+ /**
19252
+ * The documents used as input to the reranker
19253
+ */
19254
+ const RERANKER_INPUT_DOCUMENTS = `${SemanticAttributePrefixes.reranker}.${RerankerAttributePostfixes.input_documents}`;
19255
+ /**
19256
+ * The documents output by the reranker
19257
+ */
19258
+ const RERANKER_OUTPUT_DOCUMENTS = `${SemanticAttributePrefixes.reranker}.${RerankerAttributePostfixes.output_documents}`;
19259
+ /**
19260
+ * The query string for the reranker
19261
+ */
19262
+ const RERANKER_QUERY = `${SemanticAttributePrefixes.reranker}.${RerankerAttributePostfixes.query}`;
19263
+ /**
19264
+ * The model name for the reranker
19265
+ */
19266
+ const RERANKER_MODEL_NAME = `${SemanticAttributePrefixes.reranker}.${RerankerAttributePostfixes.model_name}`;
19267
+ /**
19268
+ * The top k parameter for the reranker
19269
+ */
19270
+ const RERANKER_TOP_K = `${SemanticAttributePrefixes.reranker}.${RerankerAttributePostfixes.top_k}`;
19271
+ /**
19272
+ * Metadata for a span, used to store user-defined key-value pairs
19273
+ */
19274
+ const METADATA = "metadata";
19275
+ /**
19276
+ * A prompt template version
19277
+ */
19278
+ const PROMPT_TEMPLATE_VERSION = `${PROMPT_TEMPLATE_PREFIX}.version`;
19279
+ /**
19280
+ * The tags associated with a span
19281
+ */
19282
+ const TAG_TAGS = `${SemanticAttributePrefixes.tag}.${TagAttributePostfixes.tags}`;
19283
+ /**
19284
+ * The url of an audio file
19285
+ */
19286
+ const AUDIO_URL = `${SemanticAttributePrefixes.audio}.${AudioAttributesPostfixes.url}`;
19287
+ /**
19288
+ * The audio mime type
19289
+ */
19290
+ const AUDIO_MIME_TYPE = `${SemanticAttributePrefixes.audio}.${AudioAttributesPostfixes.mime_type}`;
19291
+ /**
19292
+ * The audio transcript as text
19293
+ */
19294
+ const AUDIO_TRANSCRIPT = `${SemanticAttributePrefixes.audio}.${AudioAttributesPostfixes.transcript}`;
19295
+ /**
19296
+ * The vendor or origin of the prompt, e.g. a prompt library, a specialized service, etc.
19297
+ */
19298
+ const PROMPT_VENDOR = `${SemanticAttributePrefixes.prompt}.${PromptAttributePostfixes.vendor}`;
19299
+ /**
19300
+ * A vendor-specific id used to locate the prompt
19301
+ */
19302
+ const PROMPT_ID = `${SemanticAttributePrefixes.prompt}.${PromptAttributePostfixes.id}`;
19303
+ /**
19304
+ * A vendor-specific URL used to locate the prompt
19305
+ */
19306
+ const PROMPT_URL = `${SemanticAttributePrefixes.prompt}.${PromptAttributePostfixes.url}`;
19307
+ /**
19308
+ * The name of the agent. Agents that perform the same functions should have the same name.
19309
+ */
19310
+ const AGENT_NAME$1 = `${SemanticAttributePrefixes.agent}.${AgentPostfixes.name}`;
19311
+ /**
19312
+ * The id of the node in the execution graph. This along with graph.node.parent_id are used to visualize the execution graph.
19313
+ */
19314
+ const GRAPH_NODE_ID = `${SemanticAttributePrefixes.graph}.${GraphPostfixes.node_id}`;
19315
+ /**
19316
+ * The name of the node in the execution graph. Use this to present a human readable name for the node. Optional
19317
+ */
19318
+ const GRAPH_NODE_NAME = `${SemanticAttributePrefixes.graph}.${GraphPostfixes.node_name}`;
19319
+ /**
19320
+ * This references the id of the parent node. Leaving this unset or set as empty string implies that the current span is the root node.
19321
+ */
19322
+ const GRAPH_NODE_PARENT_ID = `${SemanticAttributePrefixes.graph}.${GraphPostfixes.node_parent_id}`;
19323
+ const SemanticConventions = {
19324
+ IMAGE_URL,
19325
+ INPUT_VALUE,
19326
+ INPUT_MIME_TYPE,
19327
+ OUTPUT_VALUE,
19328
+ OUTPUT_MIME_TYPE,
19329
+ LLM_INPUT_MESSAGES,
19330
+ LLM_OUTPUT_MESSAGES,
19331
+ LLM_MODEL_NAME,
19332
+ LLM_PROMPTS,
19333
+ LLM_INVOCATION_PARAMETERS,
19334
+ LLM_TOKEN_COUNT_COMPLETION,
19335
+ LLM_TOKEN_COUNT_COMPLETION_DETAILS,
19336
+ LLM_TOKEN_COUNT_COMPLETION_DETAILS_REASONING,
19337
+ LLM_TOKEN_COUNT_COMPLETION_DETAILS_AUDIO,
19338
+ LLM_TOKEN_COUNT_PROMPT,
19339
+ LLM_TOKEN_COUNT_PROMPT_DETAILS,
19340
+ LLM_TOKEN_COUNT_PROMPT_DETAILS_CACHE_WRITE,
19341
+ LLM_TOKEN_COUNT_PROMPT_DETAILS_CACHE_READ,
19342
+ LLM_TOKEN_COUNT_PROMPT_DETAILS_CACHE_INPUT,
19343
+ LLM_TOKEN_COUNT_PROMPT_DETAILS_AUDIO,
19344
+ LLM_TOKEN_COUNT_TOTAL,
19345
+ LLM_SYSTEM,
19346
+ LLM_PROVIDER,
19347
+ LLM_TOOLS,
19348
+ LLM_FINISH_REASON,
19349
+ LLM_COST,
19350
+ LLM_COST_PROMPT,
19351
+ LLM_COST_COMPLETION,
19352
+ LLM_COST_TOTAL,
19353
+ LLM_COST_INPUT,
19354
+ LLM_COST_OUTPUT,
19355
+ LLM_COST_COMPLETION_DETAILS_REASONING,
19356
+ LLM_COST_COMPLETION_DETAILS_AUDIO,
19357
+ LLM_COST_PROMPT_DETAILS_CACHE_WRITE,
19358
+ LLM_COST_PROMPT_DETAILS_CACHE_READ,
19359
+ LLM_COST_PROMPT_DETAILS_CACHE_INPUT,
19360
+ LLM_COST_PROMPT_DETAILS_AUDIO,
19361
+ MESSAGE_ROLE,
19362
+ MESSAGE_NAME,
19363
+ MESSAGE_TOOL_CALLS,
19364
+ MESSAGE_TOOL_CALL_ID,
19365
+ TOOL_CALL_ID,
19366
+ TOOL_CALL_REASONING_SIGNATURE,
19367
+ TOOL_CALL_FUNCTION_NAME,
19368
+ TOOL_CALL_FUNCTION_ARGUMENTS_JSON,
19369
+ MESSAGE_FUNCTION_CALL_NAME,
19370
+ MESSAGE_FUNCTION_CALL_ARGUMENTS_JSON,
19371
+ MESSAGE_CONTENT,
19372
+ MESSAGE_CONTENTS,
19373
+ MESSAGE_CONTENT_IMAGE,
19374
+ MESSAGE_CONTENT_ID,
19375
+ MESSAGE_CONTENT_SIGNATURE,
19376
+ MESSAGE_CONTENT_DATA,
19377
+ MESSAGE_CONTENT_ENCRYPTED_CONTENT,
19378
+ MESSAGE_CONTENT_TEXT,
19379
+ MESSAGE_CONTENT_TYPE,
19380
+ DOCUMENT_ID,
19381
+ DOCUMENT_CONTENT,
19382
+ DOCUMENT_SCORE,
19383
+ DOCUMENT_METADATA,
19384
+ EMBEDDING_EMBEDDINGS,
19385
+ EMBEDDING_TEXT,
19386
+ EMBEDDING_MODEL_NAME,
19387
+ EMBEDDING_VECTOR,
19388
+ TOOL_DESCRIPTION,
19389
+ TOOL_NAME: TOOL_NAME$1,
19390
+ TOOL_PARAMETERS,
19391
+ TOOL_JSON_SCHEMA,
19392
+ TOOL_ID,
19393
+ PROMPT_TEMPLATE_VARIABLES,
19394
+ PROMPT_TEMPLATE_TEMPLATE,
19395
+ PROMPT_TEMPLATE_VERSION,
19396
+ RERANKER_INPUT_DOCUMENTS,
19397
+ RERANKER_OUTPUT_DOCUMENTS,
19398
+ RERANKER_QUERY,
19399
+ RERANKER_MODEL_NAME,
19400
+ RERANKER_TOP_K,
19401
+ LLM_FUNCTION_CALL,
19402
+ RETRIEVAL_DOCUMENTS,
19403
+ SESSION_ID,
19404
+ USER_ID,
19405
+ METADATA,
19406
+ TAG_TAGS,
19407
+ OPENINFERENCE_SPAN_KIND: `${SemanticAttributePrefixes.openinference}.span.kind`,
19408
+ PROMPT_VENDOR,
19409
+ PROMPT_ID,
19410
+ PROMPT_URL,
19411
+ AGENT_NAME: AGENT_NAME$1,
19412
+ GRAPH_NODE_ID,
19413
+ GRAPH_NODE_NAME,
19414
+ GRAPH_NODE_PARENT_ID
19415
+ };
19416
+ var OpenInferenceSpanKind;
19417
+ (function(OpenInferenceSpanKind) {
19418
+ OpenInferenceSpanKind["LLM"] = "LLM";
19419
+ OpenInferenceSpanKind["CHAIN"] = "CHAIN";
19420
+ OpenInferenceSpanKind["TOOL"] = "TOOL";
19421
+ OpenInferenceSpanKind["RETRIEVER"] = "RETRIEVER";
19422
+ OpenInferenceSpanKind["RERANKER"] = "RERANKER";
19423
+ OpenInferenceSpanKind["EMBEDDING"] = "EMBEDDING";
19424
+ OpenInferenceSpanKind["AGENT"] = "AGENT";
19425
+ OpenInferenceSpanKind["GUARDRAIL"] = "GUARDRAIL";
19426
+ OpenInferenceSpanKind["EVALUATOR"] = "EVALUATOR";
19427
+ })(OpenInferenceSpanKind || (OpenInferenceSpanKind = {}));
19428
+ /**
19429
+ * An enum of common mime types. Not exhaustive.
19430
+ */
19431
+ var MimeType;
19432
+ (function(MimeType) {
19433
+ MimeType["TEXT"] = "text/plain";
19434
+ MimeType["JSON"] = "application/json";
19435
+ MimeType["AUDIO_WAV"] = "audio/wav";
19436
+ })(MimeType || (MimeType = {}));
19437
+ var LLMSystem;
19438
+ (function(LLMSystem) {
19439
+ LLMSystem["OPENAI"] = "openai";
19440
+ LLMSystem["ANTHROPIC"] = "anthropic";
19441
+ LLMSystem["MISTRALAI"] = "mistralai";
19442
+ LLMSystem["COHERE"] = "cohere";
19443
+ LLMSystem["VERTEXAI"] = "vertexai";
19444
+ LLMSystem["AI21"] = "ai21";
19445
+ LLMSystem["META"] = "meta";
19446
+ LLMSystem["AMAZON"] = "amazon";
19447
+ })(LLMSystem || (LLMSystem = {}));
19448
+ var LLMProvider;
19449
+ (function(LLMProvider) {
19450
+ LLMProvider["OPENAI"] = "openai";
19451
+ LLMProvider["ANTHROPIC"] = "anthropic";
19452
+ LLMProvider["MISTRALAI"] = "mistralai";
19453
+ LLMProvider["COHERE"] = "cohere";
19454
+ LLMProvider["GOOGLE"] = "google";
19455
+ LLMProvider["AWS"] = "aws";
19456
+ LLMProvider["AZURE"] = "azure";
19457
+ LLMProvider["XAI"] = "xai";
19458
+ LLMProvider["DEEPSEEK"] = "deepseek";
19459
+ LLMProvider["GROQ"] = "groq";
19460
+ LLMProvider["FIREWORKS"] = "fireworks";
19461
+ LLMProvider["MOONSHOT"] = "moonshot";
19462
+ LLMProvider["CEREBRAS"] = "cerebras";
19463
+ LLMProvider["PERPLEXITY"] = "perplexity";
19464
+ LLMProvider["TOGETHER"] = "together";
19465
+ })(LLMProvider || (LLMProvider = {}));
19466
+
19467
+ //#endregion
19468
+ //#region ../../shared/observability/src/openinference.ts
19469
+ /**
19470
+ * OpenInference semantic-convention re-exports for blinqV2.
19471
+ *
19472
+ * Phoenix (Arize) classifies spans by reading the
19473
+ * `openinference.span.kind` attribute. Without it every span shows up as
19474
+ * `UNKNOWN` in the Phoenix UI. Each blinq emitter pulls these typed
19475
+ * constants from a single place so a typo on the attribute key (or a
19476
+ * stray casing on the enum value) is a TypeScript error at the call
19477
+ * site, not a runtime miss in Phoenix.
19478
+ *
19479
+ * Reference: https://docs.arize.com/phoenix/tracing/concepts-tracing/what-are-traces
19480
+ *
19481
+ * Usage:
19482
+ *
19483
+ * import {
19484
+ * OpenInferenceSpanKind,
19485
+ * OPENINFERENCE_SPAN_KIND,
19486
+ * } from "@blinq/observability/openinference";
19487
+ *
19488
+ * span.setAttribute(OPENINFERENCE_SPAN_KIND, OpenInferenceSpanKind.TOOL);
19489
+ */
19490
+ /**
19491
+ * Convenience aliases for the two attribute keys blinq emitters touch
19492
+ * directly. Pulling the literal off `SemanticConventions` keeps the
19493
+ * attribute key one source of truth and lets call sites read the value
19494
+ * directly (e.g. `attributes: { [OPENINFERENCE_SPAN_KIND]: kind }`).
19495
+ */
19496
+ const OPENINFERENCE_SPAN_KIND = SemanticConventions.OPENINFERENCE_SPAN_KIND;
19497
+ /**
19498
+ * Companion attribute used on TOOL-kind spans to surface the bounded
19499
+ * tool name (e.g. `playwright.click`, `worker.tool.execute:fillForm`).
19500
+ * Keep it bounded — high-cardinality strings here defeat the bucketing.
19501
+ */
19502
+ const TOOL_NAME = SemanticConventions.TOOL_NAME;
19503
+ /**
19504
+ * Companion attribute used on AGENT-kind spans (the outer SSE run span)
19505
+ * so Phoenix can group runs by agent name. There's no first-class
19506
+ * constant in OpenInference for the agent label — `AGENT_NAME` covers
19507
+ * the same surface and is the convention Phoenix already understands.
19508
+ */
19509
+ const AGENT_NAME = SemanticConventions.AGENT_NAME;
19510
+ /**
19511
+ * Companion attribute used on EVALUATOR-kind spans (postcondition
19512
+ * matcher invocations) so Phoenix can group evaluator runs by matcher
19513
+ * name. OpenInference uses `tool.name` as the canonical name slot for
19514
+ * EVALUATOR spans too; we mirror the same key for consistency with the
19515
+ * playwright tool spans that share the tracer.
19516
+ */
19517
+ const EVALUATOR_NAME = SemanticConventions.TOOL_NAME;
19518
+
19519
+ //#endregion
19520
+ //#region ../../core/bvt-agent/src/agent/playwright-runner.ts
19521
+ /**
19522
+ * Tracer for Playwright primitive operations driven through the sandbox
19523
+ * bridge. Spans are kept INTERNAL kind (in-process work, not a network
19524
+ * hop) and only the small set of operations users care about for the
19525
+ * `100s gap` (where time is actually spent inside a step) are wrapped —
19526
+ * `locator()` lookups and other O(1) DOM queries are intentionally
19527
+ * skipped to keep cardinality and span volume bounded.
19528
+ */
19529
+ const playwrightActionTracer = trace.getTracer("worker.playwright.action");
19530
+ /**
19531
+ * Whitelist of page-level Playwright methods that produce a Playwright span
19532
+ * via the bridge. Keep this in sync with `TRACED_LOCATOR_METHODS` — the
19533
+ * goal is to span every operation that drives the browser (clicks,
19534
+ * navigation, waits) and skip cheap pure-DOM helpers (locator queries,
19535
+ * `url()`, `title()`) which would otherwise multiply the span count for
19536
+ * every step without adding signal.
19537
+ */
19538
+ const TRACED_PAGE_METHODS = new Set([
19539
+ "goto",
19540
+ "reload",
19541
+ "goBack",
19542
+ "goForward",
19543
+ "waitForURL",
19544
+ "waitForLoadState",
19545
+ "waitForSelector",
19546
+ "waitForTimeout"
19547
+ ]);
19548
+ const TRACED_LOCATOR_METHODS = new Set([
19549
+ "click",
19550
+ "fill",
19551
+ "type",
19552
+ "press",
19553
+ "check",
19554
+ "uncheck",
19555
+ "hover",
19556
+ "focus",
19557
+ "selectOption",
19558
+ "waitFor",
19559
+ "scrollIntoViewIfNeeded",
19560
+ "clear"
19561
+ ]);
19562
+ /**
19563
+ * Extract the relevant selector / url from the first bridge arg passed to
19564
+ * a Playwright method. Avoids putting full args payloads on the span
19565
+ * (cardinality bomb when args contain DOM/JSON blobs). For locator
19566
+ * methods the selector is implicit in the receiving locator handle, so
19567
+ * we return `undefined` and let the span name carry the signal.
19568
+ */
19569
+ function selectorAttrFromBridgeArgs(methodName, args) {
19570
+ const first = args[0];
19571
+ if (typeof first !== "string") return;
19572
+ if (methodName === "goto" || methodName === "waitForURL" || methodName === "waitForSelector") return first;
19573
+ }
19574
+ /**
19575
+ * Pull a timeout out of the trailing options bag (always position 1 on
19576
+ * Playwright primitives) so the span captures what budget the call had.
19577
+ * Skip if not present — most calls inherit the page-level default and
19578
+ * surfacing `undefined` adds noise without signal.
19579
+ */
19580
+ function timeoutAttrFromBridgeArgs(args) {
19581
+ for (const candidate of args) if (candidate && typeof candidate === "object" && !Array.isArray(candidate) && typeof candidate.timeout === "number") return candidate.timeout;
19582
+ }
19583
+ /**
19584
+ * Wrap a Playwright primitive invocation in an INTERNAL span. Returns the
19585
+ * raw result of `fn()` so the bridge call site is unchanged. The span is
19586
+ * a no-op when the SDK is disabled — `trace.getTracer` falls back to a
19587
+ * tracer that mints non-recording spans, so the cost is one allocation
19588
+ * per call.
19589
+ *
19590
+ * The `kind` argument controls the OpenInference classification surfaced
19591
+ * to Phoenix: `TOOL` for page/locator driving actions, `EVALUATOR` for
19592
+ * postcondition matcher invocations. The bounded action/matcher name
19593
+ * lives under `tool.name` / `evaluator.name` (both alias the same
19594
+ * canonical OpenInference attribute key) so Phoenix can group dispatches
19595
+ * without re-parsing the span name. All attribute values are bounded
19596
+ * enums — no high-cardinality user input ever lands on the span.
19597
+ */
19598
+ function tracePlaywrightAction(spanName, attrs, fn) {
19599
+ const oiKind = attrs.kind === "EVALUATOR" ? OpenInferenceSpanKind.EVALUATOR : OpenInferenceSpanKind.TOOL;
19600
+ const nameAttr = attrs.kind === "EVALUATOR" ? EVALUATOR_NAME : TOOL_NAME;
19601
+ return playwrightActionTracer.startActiveSpan(spanName, {
19602
+ kind: SpanKind.INTERNAL,
19603
+ attributes: {
19604
+ ...attrs.selector ? { "playwright.selector": attrs.selector } : {},
19605
+ ...typeof attrs.timeout === "number" ? { "playwright.timeout": attrs.timeout } : {},
19606
+ [OPENINFERENCE_SPAN_KIND]: oiKind,
19607
+ [nameAttr]: spanName
19608
+ }
19609
+ }, (span) => {
19610
+ let outcome;
19611
+ try {
19612
+ outcome = fn();
19613
+ } catch (err) {
19614
+ span.setStatus({
19615
+ code: SpanStatusCode.ERROR,
19616
+ message: err instanceof Error ? err.message : String(err)
19617
+ });
19618
+ if (err instanceof Error) span.recordException(err);
19619
+ span.end();
19620
+ throw err;
19621
+ }
19622
+ if (outcome instanceof Promise) return outcome.then((value) => {
19623
+ span.end();
19624
+ return value;
19625
+ }, (err) => {
19626
+ span.setStatus({
19627
+ code: SpanStatusCode.ERROR,
19628
+ message: err instanceof Error ? err.message : String(err)
19629
+ });
19630
+ if (err instanceof Error) span.recordException(err);
19631
+ span.end();
19632
+ throw err;
19633
+ });
19634
+ span.end();
19635
+ return outcome;
19636
+ });
19637
+ }
19638
+ /**
19639
+ * Default timeout for `expect(...).toX(...)` matchers when the caller did not
19640
+ * supply a per-call `{ timeout }` option. Matches the prior shim's default so
19641
+ * postcondition snippets compiled before the migration keep the same budget.
19642
+ */
19643
+ const EXPECT_DEFAULT_TIMEOUT_MS = 15e3;
19644
+ /**
19645
+ * Matchers exposed to user-authored Playwright snippets via the sandbox
19646
+ * `expect()` helper. Whitelist gates which matchers cross the realm boundary,
19647
+ * keeping the surface area auditable and matching what `postcondition-compiler`
19648
+ * emits plus the handful used directly by AI-generated code.
19649
+ */
19650
+ const SUPPORTED_EXPECT_MATCHERS = new Set([
19651
+ "toBeVisible",
19652
+ "toBeHidden",
19653
+ "toBeAttached",
19654
+ "toBeEnabled",
19655
+ "toBeDisabled",
19656
+ "toBeChecked",
19657
+ "toBeFocused",
19658
+ "toBeEditable",
19659
+ "toBeEmpty",
19660
+ "toBeInViewport",
19661
+ "toHaveCount",
19662
+ "toHaveText",
19663
+ "toContainText",
19664
+ "toHaveValue",
19665
+ "toHaveValues",
19666
+ "toHaveAttribute",
19667
+ "toHaveClass",
19668
+ "toHaveURL",
19669
+ "toHaveTitle"
19670
+ ]);
19671
+ /**
19672
+ * Matchers whose first arg is the expected value (string/regex/predicate/
19673
+ * number/boolean). For these the options object lives at args[1].
19674
+ * `toBeVisible/Hidden/Attached/Enabled/Disabled/Checked` take no value arg —
19675
+ * their options object sits at args[0].
19676
+ */
19677
+ const VALUE_FIRST_EXPECT_MATCHERS = new Set([
19678
+ "toHaveURL",
19679
+ "toHaveTitle",
19680
+ "toHaveText",
19681
+ "toContainText",
19682
+ "toHaveValue",
19683
+ "toHaveValues",
19684
+ "toHaveCount",
19685
+ "toHaveClass"
19686
+ ]);
19687
+ /**
19688
+ * `toHaveAttribute(name, expected?, opts?)` is special: opts is at index 2.
19689
+ * The compiler always passes `expected` explicitly (or `undefined` for the
19690
+ * presence check), so we can rely on the 3-arg layout when normalizing.
19691
+ */
19692
+ const HAS_OPTS_AT_POSITION_2 = new Set(["toHaveAttribute"]);
19693
+ /**
19694
+ * Fills in `{ timeout: EXPECT_DEFAULT_TIMEOUT_MS }` when the caller did not
19695
+ * pass any options object. Per-call options always win — we only inject the
19696
+ * default when no options were provided at the expected position. Keeps the
19697
+ * 15s budget the prior shim used so postcondition snippets stay backward-
19698
+ * compatible without depending on `playwrightExpect.configure(...)` at module
19699
+ * load time (some tests mock `playwright/test` without `.configure`).
19700
+ */
19701
+ function applyExpectDefaults(matcherName, args) {
19702
+ const optsPos = HAS_OPTS_AT_POSITION_2.has(matcherName) ? 2 : VALUE_FIRST_EXPECT_MATCHERS.has(matcherName) ? 1 : 0;
19703
+ const existing = args[optsPos];
19704
+ if (existing && typeof existing === "object") {
19705
+ const opts = existing;
19706
+ if (opts.timeout !== void 0) return args;
19707
+ const next = args.slice();
19708
+ next[optsPos] = {
19709
+ ...opts,
19710
+ timeout: EXPECT_DEFAULT_TIMEOUT_MS
19711
+ };
19712
+ return next;
19713
+ }
19714
+ if (existing !== void 0) return args;
19715
+ const next = args.slice();
19716
+ while (next.length < optsPos) next.push(void 0);
19717
+ next[optsPos] = { timeout: EXPECT_DEFAULT_TIMEOUT_MS };
19718
+ return next;
19719
+ }
19720
+ /**
19721
+ * Blocked methods are dangerous in a sandbox context (code execution, request
19722
+ * interception, browser/context escape, etc.). Everything else discovered at
19723
+ * runtime on the real Playwright objects is automatically allowed, so new
19724
+ * Playwright API additions work without manual updates.
19725
+ */
19726
+ const BLOCKED_PAGE_METHODS = new Set([
19727
+ "evaluate",
19728
+ "evaluateHandle",
19729
+ "$eval",
19730
+ "$$eval",
19731
+ "addScriptTag",
19732
+ "addStyleTag",
19733
+ "exposeFunction",
19734
+ "exposeBinding",
19735
+ "addInitScript",
19736
+ "route",
19737
+ "unroute",
19738
+ "routeFromHAR",
19739
+ "unrouteAll",
19740
+ "context",
19741
+ "close",
19742
+ "bringToFront",
19743
+ "setContent",
19744
+ "setExtraHTTPHeaders",
19745
+ "setInputFiles",
19746
+ "pdf",
19747
+ "screenshot",
19748
+ "video",
19749
+ "on",
19750
+ "off",
19751
+ "once",
19752
+ "emit",
19753
+ "removeListener",
19754
+ "removeAllListeners",
19755
+ "addListener",
19756
+ "setMaxListeners",
19757
+ "waitForEvent",
19758
+ "workers",
19759
+ "frames",
19760
+ "mainFrame",
19761
+ "opener"
19762
+ ]);
19763
+ const BLOCKED_LOCATOR_METHODS = new Set([
19764
+ "evaluate",
19765
+ "evaluateHandle",
19766
+ "evaluateAll",
19767
+ "on",
19768
+ "off",
19769
+ "once",
19770
+ "emit",
19771
+ "removeListener",
19772
+ "removeAllListeners",
19773
+ "addListener",
19774
+ "setMaxListeners",
19775
+ "setInputFiles",
19776
+ "screenshot"
19777
+ ]);
19778
+ /**
19779
+ * Walk the prototype chain and collect every function-valued own-property.
19780
+ * Uses property descriptors to avoid triggering getters/accessors (e.g.
19781
+ * Playwright's `keyboard`, `mouse` accessors) during introspection.
19782
+ */
19783
+ function extractMethods(obj) {
19784
+ const methods = /* @__PURE__ */ new Set();
19785
+ let current = obj;
19786
+ while (current && current !== Object.prototype) {
19787
+ for (const key of Object.getOwnPropertyNames(current)) {
19788
+ const descriptor = Object.getOwnPropertyDescriptor(current, key);
19789
+ if (key !== "constructor" && descriptor && typeof descriptor.value === "function") methods.add(key);
19790
+ }
19791
+ current = Object.getPrototypeOf(current);
19792
+ }
19793
+ return [...methods];
19794
+ }
19795
+ const HOST_HELPER_METHODS = [
19796
+ "getPreferredInteractiveTargetSelector",
19797
+ "activatePreferredInteractiveTarget",
19798
+ "activateWithRecovery"
19799
+ ];
19800
+ const FALLBACK_PAGE_METHODS = [
19801
+ "getByAltText",
19802
+ "getByDisplayValue",
19803
+ "getByLabel",
19804
+ "getByPlaceholder",
19805
+ "getByRole",
19806
+ "getByTestId",
19807
+ "getByText",
19808
+ "getByTitle",
19809
+ "goto",
19810
+ "reload",
19811
+ "goBack",
19812
+ "goForward",
19813
+ "locator",
19814
+ "title",
19815
+ "url",
19816
+ "waitForSelector",
19817
+ "waitForTimeout",
19818
+ "waitForURL",
19819
+ "waitForLoadState"
19820
+ ];
19821
+ const FALLBACK_LOCATOR_METHODS = [
19822
+ "allTextContents",
19823
+ "and",
19824
+ "blur",
19825
+ "check",
19826
+ "clear",
19827
+ "click",
19828
+ "count",
19829
+ "fill",
19830
+ "filter",
19831
+ "first",
19832
+ "focus",
19833
+ "getAttribute",
19834
+ "getByAltText",
19835
+ "getByDisplayValue",
19836
+ "getByLabel",
19837
+ "getByPlaceholder",
19838
+ "getByRole",
19839
+ "getByTestId",
19840
+ "getByText",
19841
+ "getByTitle",
19842
+ "hover",
19843
+ "innerText",
19844
+ "inputValue",
19845
+ "isChecked",
19846
+ "isDisabled",
19847
+ "isEnabled",
19848
+ "isHidden",
19849
+ "isVisible",
19850
+ "last",
19851
+ "locator",
19852
+ "nth",
19853
+ "or",
19854
+ "press",
19855
+ "scrollIntoViewIfNeeded",
19856
+ "selectOption",
19857
+ "textContent",
19858
+ "type",
19859
+ "uncheck",
19860
+ "waitFor"
19861
+ ];
19862
+ function buildAllowedMethods(obj, blocked, fallback) {
19863
+ let all = extractMethods(obj);
19864
+ if (all.length === 0) all = fallback;
19865
+ const methods = all.filter((m) => !blocked.has(m));
19866
+ return {
19867
+ methods,
19868
+ methodSet: new Set(methods)
19869
+ };
19870
+ }
19871
+ const HELPER_METHOD_SET = new Set(HOST_HELPER_METHODS);
19872
+ const BRIDGE_ERROR_PREFIX = "[playwright-bridge]";
19873
+ const RECOVERY_LOCATOR_OPERATION_TIMEOUT_MS = 2e3;
19874
+ function recoveryLocatorOptions(extra) {
18001
19875
  return {
18002
19876
  timeout: RECOVERY_LOCATOR_OPERATION_TIMEOUT_MS,
18003
19877
  ...extra
@@ -18099,6 +19973,19 @@ function buildBootstrap(code, pageMethods, locatorMethods) {
18099
19973
  });
18100
19974
 
18101
19975
  const testData = Object.freeze({
19976
+ set: async (key, value, opts) => {
19977
+ const result = __bridgeTestData("set", [key, value, opts]);
19978
+ if (result && typeof result.then === "function") {
19979
+ const resolved = await result;
19980
+ return resolved && resolved.type === "value" ? resolved.value : undefined;
19981
+ }
19982
+ return undefined;
19983
+ },
19984
+ get: async (key) => {
19985
+ const result = __bridgeTestData("get", [key]);
19986
+ const resolved = result && typeof result.then === "function" ? await result : result;
19987
+ return resolved && resolved.type === "value" ? resolved.value : null;
19988
+ },
18102
19989
  setRuntime: async (key, value, opts) => {
18103
19990
  const result = __bridgeTestData("setRuntime", [key, value, opts]);
18104
19991
  if (result && typeof result.then === "function") {
@@ -18158,234 +20045,35 @@ function buildBootstrap(code, pageMethods, locatorMethods) {
18158
20045
  }
18159
20046
  };
18160
20047
 
18161
- // ── Minimal expect() shim for postcondition snippets ────────────────────
18162
- // Not a full Playwright @playwright/test expect; covers common matchers.
18163
- // Supports .not inversion and { timeout } option on every matcher.
18164
- const EXPECT_DEFAULT_TIMEOUT_MS = 15000;
18165
- const EXPECT_POLL_INTERVAL_MS = 100;
18166
- const expectRegexOrStringEq = (actual, expected) => {
18167
- const str = actual == null ? "" : String(actual);
18168
- if (expected instanceof RegExp) return expected.test(str);
18169
- return str === String(expected);
18170
- };
18171
- const expectRegexOrStringContains = (actual, expected) => {
18172
- const str = actual == null ? "" : String(actual);
18173
- if (expected instanceof RegExp) return expected.test(str);
18174
- return str.includes(String(expected));
18175
- };
18176
- const expectPoll = async (predicate, timeout, errorBuilder) => {
18177
- const deadline = Date.now() + timeout;
18178
- let lastDetail = "<never observed>";
18179
- while (Date.now() < deadline) {
18180
- try {
18181
- const result = await predicate();
18182
- if (result && result.ok) return;
18183
- if (result && result.detail !== undefined) lastDetail = result.detail;
18184
- } catch (err) {
18185
- lastDetail = err && err.message ? err.message : String(err);
18186
- }
18187
- const remaining = deadline - Date.now();
18188
- if (remaining <= 0) break;
18189
- await __bridgeDelay(Math.min(EXPECT_POLL_INTERVAL_MS, remaining));
18190
- }
18191
- throw new Error(errorBuilder(lastDetail));
20048
+ // ── expect() bridge to Playwright's official @playwright/test expect ──
20049
+ // The user-authored code runs inside this vm context; the real Playwright
20050
+ // page/locator objects live in the host realm. Each matcher call is shipped
20051
+ // across the bridge as a single (matcherName, subjectRef, args, negate)
20052
+ // tuple so the host can invoke the official expect on the real subject —
20053
+ // preserving function-predicate, cross-realm RegExp, polling/intervals,
20054
+ // and the full matcher message format that ships with Playwright.
20055
+ const buildExpectChain = (subjectRef, negate) => {
20056
+ const handler = {
20057
+ get(_target, prop) {
20058
+ if (prop === "not") {
20059
+ return buildExpectChain(subjectRef, !negate);
20060
+ }
20061
+ if (typeof prop !== "string") {
20062
+ return undefined;
20063
+ }
20064
+ return (...args) => __bridgeExpect(prop, subjectRef, args, negate);
20065
+ },
20066
+ };
20067
+ return new Proxy(Object.create(null), handler);
18192
20068
  };
18193
20069
  const expect = (subject) => {
18194
- const isLocator = subject != null && typeof subject.__locatorId === "number";
18195
- const isPage = subject === page;
18196
- const ensureLocator = (matcher) => {
18197
- if (!isLocator) throw new Error(matcher + " requires a locator subject");
18198
- };
18199
- const ensurePage = (matcher) => {
18200
- if (!isPage) throw new Error(matcher + " requires a page subject");
18201
- };
18202
- const make = (negate) => {
18203
- const flip = (ok) => (negate ? !ok : ok);
18204
- const flipWord = negate ? "NOT " : "";
18205
- const api = {
18206
- async toBeVisible(opts = {}) {
18207
- ensureLocator("toBeVisible");
18208
- const timeout = opts.timeout ?? EXPECT_DEFAULT_TIMEOUT_MS;
18209
- await subject.waitFor({ state: negate ? "hidden" : "visible", timeout: timeout });
18210
- },
18211
- async toBeHidden(opts = {}) {
18212
- ensureLocator("toBeHidden");
18213
- const timeout = opts.timeout ?? EXPECT_DEFAULT_TIMEOUT_MS;
18214
- await subject.waitFor({ state: negate ? "visible" : "hidden", timeout: timeout });
18215
- },
18216
- async toBeAttached(opts = {}) {
18217
- ensureLocator("toBeAttached");
18218
- const timeout = opts.timeout ?? EXPECT_DEFAULT_TIMEOUT_MS;
18219
- await subject.waitFor({ state: negate ? "detached" : "attached", timeout: timeout });
18220
- },
18221
- async toBeEnabled(opts = {}) {
18222
- ensureLocator("toBeEnabled");
18223
- const timeout = opts.timeout ?? EXPECT_DEFAULT_TIMEOUT_MS;
18224
- await expectPoll(
18225
- async () => {
18226
- const enabled = await subject.isEnabled();
18227
- return flip(enabled) ? { ok: true } : { ok: false, detail: "isEnabled=" + enabled };
18228
- },
18229
- timeout,
18230
- (detail) => "Expected locator " + flipWord + "to be enabled. Last: " + detail,
18231
- );
18232
- },
18233
- async toBeDisabled(opts = {}) {
18234
- ensureLocator("toBeDisabled");
18235
- const timeout = opts.timeout ?? EXPECT_DEFAULT_TIMEOUT_MS;
18236
- await expectPoll(
18237
- async () => {
18238
- const disabled = await subject.isDisabled();
18239
- return flip(disabled) ? { ok: true } : { ok: false, detail: "isDisabled=" + disabled };
18240
- },
18241
- timeout,
18242
- (detail) => "Expected locator " + flipWord + "to be disabled. Last: " + detail,
18243
- );
18244
- },
18245
- async toBeChecked(opts = {}) {
18246
- ensureLocator("toBeChecked");
18247
- const timeout = opts.timeout ?? EXPECT_DEFAULT_TIMEOUT_MS;
18248
- await expectPoll(
18249
- async () => {
18250
- const checked = await subject.isChecked();
18251
- return flip(checked) ? { ok: true } : { ok: false, detail: "isChecked=" + checked };
18252
- },
18253
- timeout,
18254
- (detail) => "Expected locator " + flipWord + "to be checked. Last: " + detail,
18255
- );
18256
- },
18257
- async toHaveCount(expected, opts = {}) {
18258
- ensureLocator("toHaveCount");
18259
- const timeout = opts.timeout ?? EXPECT_DEFAULT_TIMEOUT_MS;
18260
- await expectPoll(
18261
- async () => {
18262
- const count = await subject.count();
18263
- return flip(count === expected)
18264
- ? { ok: true }
18265
- : { ok: false, detail: "count=" + count };
18266
- },
18267
- timeout,
18268
- (detail) => "Expected count " + flipWord + "to equal " + expected + ". Last: " + detail,
18269
- );
18270
- },
18271
- async toHaveText(expected, opts = {}) {
18272
- ensureLocator("toHaveText");
18273
- const timeout = opts.timeout ?? EXPECT_DEFAULT_TIMEOUT_MS;
18274
- await expectPoll(
18275
- async () => {
18276
- const text = await subject.textContent();
18277
- return flip(expectRegexOrStringEq(text, expected))
18278
- ? { ok: true }
18279
- : { ok: false, detail: "textContent=" + JSON.stringify(text) };
18280
- },
18281
- timeout,
18282
- (detail) =>
18283
- "Expected text " + flipWord + "to match " + String(expected) + ". Last: " + detail,
18284
- );
18285
- },
18286
- async toContainText(expected, opts = {}) {
18287
- ensureLocator("toContainText");
18288
- const timeout = opts.timeout ?? EXPECT_DEFAULT_TIMEOUT_MS;
18289
- await expectPoll(
18290
- async () => {
18291
- const text = await subject.textContent();
18292
- return flip(expectRegexOrStringContains(text, expected))
18293
- ? { ok: true }
18294
- : { ok: false, detail: "textContent=" + JSON.stringify(text) };
18295
- },
18296
- timeout,
18297
- (detail) =>
18298
- "Expected text " +
18299
- flipWord +
18300
- "to contain " +
18301
- String(expected) +
18302
- ". Last: " +
18303
- detail,
18304
- );
18305
- },
18306
- async toHaveValue(expected, opts = {}) {
18307
- ensureLocator("toHaveValue");
18308
- const timeout = opts.timeout ?? EXPECT_DEFAULT_TIMEOUT_MS;
18309
- await expectPoll(
18310
- async () => {
18311
- const value = await subject.inputValue();
18312
- return flip(expectRegexOrStringEq(value, expected))
18313
- ? { ok: true }
18314
- : { ok: false, detail: "inputValue=" + JSON.stringify(value) };
18315
- },
18316
- timeout,
18317
- (detail) =>
18318
- "Expected value " + flipWord + "to equal " + String(expected) + ". Last: " + detail,
18319
- );
18320
- },
18321
- async toHaveAttribute(name, expected, opts = {}) {
18322
- ensureLocator("toHaveAttribute");
18323
- const timeout = (opts && opts.timeout) ?? EXPECT_DEFAULT_TIMEOUT_MS;
18324
- await expectPoll(
18325
- async () => {
18326
- const actual = await subject.getAttribute(name);
18327
- if (expected === undefined) {
18328
- return flip(actual !== null)
18329
- ? { ok: true }
18330
- : { ok: false, detail: "attr[" + name + "]=" + JSON.stringify(actual) };
18331
- }
18332
- return flip(expectRegexOrStringEq(actual, expected))
18333
- ? { ok: true }
18334
- : { ok: false, detail: "attr[" + name + "]=" + JSON.stringify(actual) };
18335
- },
18336
- timeout,
18337
- (detail) =>
18338
- "Expected attribute " +
18339
- name +
18340
- " " +
18341
- flipWord +
18342
- "to match. Last: " +
18343
- detail,
18344
- );
18345
- },
18346
- async toHaveURL(expected, opts = {}) {
18347
- ensurePage("toHaveURL");
18348
- const timeout = opts.timeout ?? EXPECT_DEFAULT_TIMEOUT_MS;
18349
- // Poll page.url() instead of page.waitForURL. waitForURL waits for a
18350
- // NEW navigation event and does not short-circuit when navigation
18351
- // has already settled before the call (common for fast clicks).
18352
- await expectPoll(
18353
- async () => {
18354
- const url = await page.url();
18355
- const ok = expectRegexOrStringEq(url, expected);
18356
- return flip(ok)
18357
- ? { ok: true }
18358
- : { ok: false, detail: "url=" + String(url) };
18359
- },
18360
- timeout,
18361
- (detail) =>
18362
- "Expected URL " + flipWord + "to match " + String(expected) + ". Last: " + detail,
18363
- );
18364
- },
18365
- async toHaveTitle(expected, opts = {}) {
18366
- ensurePage("toHaveTitle");
18367
- const timeout = opts.timeout ?? EXPECT_DEFAULT_TIMEOUT_MS;
18368
- await expectPoll(
18369
- async () => {
18370
- const title = await page.title();
18371
- return flip(expectRegexOrStringEq(title, expected))
18372
- ? { ok: true }
18373
- : { ok: false, detail: "title=" + JSON.stringify(title) };
18374
- },
18375
- timeout,
18376
- (detail) =>
18377
- "Expected title " + flipWord + "to match " + String(expected) + ". Last: " + detail,
18378
- );
18379
- },
18380
- };
18381
- Object.defineProperty(api, "not", {
18382
- get() {
18383
- return make(!negate);
18384
- },
18385
- });
18386
- return api;
18387
- };
18388
- return make(false);
20070
+ if (subject === page) {
20071
+ return buildExpectChain({ kind: "page" }, false);
20072
+ }
20073
+ if (subject != null && typeof subject.__locatorId === "number") {
20074
+ return buildExpectChain({ kind: "locator", locatorId: subject.__locatorId }, false);
20075
+ }
20076
+ throw new Error("expect() requires the sandbox page or a sandbox locator as its subject");
18389
20077
  };
18390
20078
 
18391
20079
  return (async (page, context, console, checkpoint, helpers, expect, onCommandStart, onCommandPass) => {
@@ -18434,10 +20122,15 @@ function raceWithAbort(promise, signal) {
18434
20122
  }
18435
20123
  function isLocatorLike(value) {
18436
20124
  if (!value || typeof value !== "object" && typeof value !== "function") return false;
20125
+ if (Array.isArray(value)) return false;
18437
20126
  const candidate = value;
18438
20127
  return FALLBACK_LOCATOR_METHODS.some((methodName) => typeof candidate[methodName] === "function");
18439
20128
  }
18440
20129
  function bridgeResultFromValue(value, locatorIds, locators) {
20130
+ if (Array.isArray(value)) return {
20131
+ type: "array",
20132
+ items: value.map((item) => bridgeResultFromValue(item, locatorIds, locators))
20133
+ };
18441
20134
  if (isLocatorLike(value)) {
18442
20135
  const locatorObject = value;
18443
20136
  const existingLocatorId = locatorIds.get(locatorObject);
@@ -18668,7 +20361,7 @@ async function activateWithRecovery(page, locator) {
18668
20361
  function invokeHelperMethod(helperName, args, page, locatorIds, locators) {
18669
20362
  if (!HELPER_METHOD_SET.has(helperName)) throw new Error(`${BRIDGE_ERROR_PREFIX} Blocked helper call: ${helperName}`);
18670
20363
  const [firstArg] = args;
18671
- const resolvedLocator = firstArg?.type === "locator" ? locators.get(firstArg.locatorId) : firstArg?.value;
20364
+ const resolvedLocator = firstArg?.type === "locator" ? locators.get(firstArg.locatorId) : firstArg?.type === "value" ? firstArg.value : void 0;
18672
20365
  const helperResult = helperName === "getPreferredInteractiveTargetSelector" ? getPreferredInteractiveTargetSelector(resolvedLocator) : helperName === "activatePreferredInteractiveTarget" ? activatePreferredInteractiveTarget(page, resolvedLocator) : helperName === "activateWithRecovery" ? activateWithRecovery(page, resolvedLocator) : resolvedLocator;
18673
20366
  if (helperResult instanceof Promise) return helperResult.then((value) => bridgeResultFromValue(value, locatorIds, locators));
18674
20367
  return bridgeResultFromValue(helperResult, locatorIds, locators);
@@ -18722,18 +20415,64 @@ async function runPlaywrightCode({ page, code, context, timeoutMs, signal, onLog
18722
20415
  sandbox.__bridgeCheckpoint = (label, data) => {
18723
20416
  onCheckpoint(label, data === void 0 ? void 0 : cloneSerializableValue(data));
18724
20417
  };
18725
- sandbox.__bridgePage = (methodName, args) => invokeBridgeMethod(page, methodName, args, allowedPage.methodSet, locatorIds, locators, signal);
20418
+ sandbox.__bridgePage = (methodName, args) => {
20419
+ const invoke = () => invokeBridgeMethod(page, methodName, args, allowedPage.methodSet, locatorIds, locators, signal);
20420
+ if (!TRACED_PAGE_METHODS.has(methodName)) return invoke();
20421
+ return tracePlaywrightAction(`playwright.${methodName}`, {
20422
+ selector: selectorAttrFromBridgeArgs(methodName, args),
20423
+ timeout: timeoutAttrFromBridgeArgs(args)
20424
+ }, invoke);
20425
+ };
18726
20426
  sandbox.__bridgeLocator = (locatorId, methodName, args) => {
18727
20427
  const locator = locators.get(locatorId);
18728
20428
  if (!locator) throw new Error(`${BRIDGE_ERROR_PREFIX} Unknown locator handle: ${locatorId}`);
18729
- return invokeBridgeMethod(locator, methodName, args, allowedLocator.methodSet, locatorIds, locators, signal);
20429
+ const invoke = () => invokeBridgeMethod(locator, methodName, args, allowedLocator.methodSet, locatorIds, locators, signal);
20430
+ if (!TRACED_LOCATOR_METHODS.has(methodName)) return invoke();
20431
+ return tracePlaywrightAction(`playwright.${methodName}`, { timeout: timeoutAttrFromBridgeArgs(args) }, invoke);
18730
20432
  };
18731
20433
  sandbox.__bridgeHelper = (helperName, args) => invokeHelperMethod(helperName, args, page, locatorIds, locators);
20434
+ sandbox.__bridgeExpect = (matcherName, subjectRef, args, negate) => {
20435
+ if (!SUPPORTED_EXPECT_MATCHERS.has(matcherName)) throw new Error(`${BRIDGE_ERROR_PREFIX} expect matcher not supported: ${matcherName}`);
20436
+ let subject;
20437
+ if (subjectRef.kind === "page") subject = page;
20438
+ else {
20439
+ const real = locators.get(subjectRef.locatorId);
20440
+ if (!real) throw new Error(`${BRIDGE_ERROR_PREFIX} Unknown locator handle for expect: ${subjectRef.locatorId}`);
20441
+ subject = real;
20442
+ }
20443
+ const normalizedArgs = applyExpectDefaults(matcherName, args);
20444
+ const expectation = negate ? expect(subject).not : expect(subject);
20445
+ const matcher = expectation[matcherName];
20446
+ if (typeof matcher !== "function") throw new Error(`${BRIDGE_ERROR_PREFIX} expect().${matcherName} is not available on the subject`);
20447
+ return tracePlaywrightAction(`playwright.postcondition.${matcherName}`, {
20448
+ timeout: timeoutAttrFromBridgeArgs(normalizedArgs),
20449
+ kind: "EVALUATOR"
20450
+ }, () => {
20451
+ const result = Reflect.apply(matcher, expectation, normalizedArgs);
20452
+ if (result instanceof Promise) return raceWithAbort(result, signal);
20453
+ return result;
20454
+ });
20455
+ };
18732
20456
  sandbox.__bridgeDelay = (ms) => new Promise((resolve) => setTimeout(resolve, Math.max(0, Number(ms) || 0)));
18733
20457
  sandbox.__bridgeTestData = async (methodName, args) => {
18734
20458
  const api = testData;
18735
20459
  if (!api) throw new Error("context.testData is not available (testData is not available) — no resolutionContext on this step");
18736
20460
  switch (methodName) {
20461
+ case "set": {
20462
+ const [key, value, opts] = args;
20463
+ await api.set(key, value, opts);
20464
+ return {
20465
+ type: "value",
20466
+ value: void 0
20467
+ };
20468
+ }
20469
+ case "get": {
20470
+ const [key] = args;
20471
+ return {
20472
+ type: "value",
20473
+ value: await api.get(key)
20474
+ };
20475
+ }
18737
20476
  case "setRuntime": {
18738
20477
  const [key, value, opts] = args;
18739
20478
  await api.setRuntime(key, value, opts);
@@ -18878,6 +20617,11 @@ async function executePlaywrightCode({ page, code, context, timeoutMs = PLAYWRIG
18878
20617
  //#endregion
18879
20618
  //#region ../../core/bvt-agent/src/agent/utils.ts
18880
20619
  const hasUnresolvedTokens = (obj) => {
20620
+ if (obj && typeof obj === "object" && obj.type === "custom.code") {
20621
+ const { code: _code, ...rest } = obj;
20622
+ const str = JSON.stringify(rest);
20623
+ return /{{.*}}/.test(str);
20624
+ }
18881
20625
  const str = JSON.stringify(obj);
18882
20626
  return /{{.*}}/.test(str);
18883
20627
  };
@@ -19147,13 +20891,14 @@ var Tester = class {
19147
20891
  fileResolver;
19148
20892
  downloadStore;
19149
20893
  getDownloadTargetPath;
20894
+ customCodeRuntime;
19150
20895
  pageList = new Array();
19151
20896
  sessionToken = "";
19152
20897
  activeBrowserContext = null;
19153
20898
  reportId = ulid();
19154
20899
  constructor(getAPIClient = unconfiguredGetAPIClient, observabilityOrOptions, optionsArg = {}) {
19155
20900
  this.getAPIClient = getAPIClient;
19156
- const isTesterOptions = observabilityOrOptions !== null && typeof observabilityOrOptions === "object" && ("commandPreprocessors" in observabilityOrOptions || "recoveryController" in observabilityOrOptions || "restoreStepStartForRepair" in observabilityOrOptions || "provider" in observabilityOrOptions || "getApiFetchImpl" in observabilityOrOptions || "stepTraceChunkCallbacks" in observabilityOrOptions || "context" in observabilityOrOptions || "onTestDataChange" in observabilityOrOptions);
20901
+ const isTesterOptions = observabilityOrOptions !== null && typeof observabilityOrOptions === "object" && ("commandPreprocessors" in observabilityOrOptions || "recoveryController" in observabilityOrOptions || "restoreStepStartForRepair" in observabilityOrOptions || "provider" in observabilityOrOptions || "getApiFetchImpl" in observabilityOrOptions || "stepTraceChunkCallbacks" in observabilityOrOptions || "context" in observabilityOrOptions || "onTestDataChange" in observabilityOrOptions || "customCodeRuntime" in observabilityOrOptions);
19157
20902
  const observability = isTesterOptions ? void 0 : observabilityOrOptions;
19158
20903
  const options = isTesterOptions ? observabilityOrOptions : optionsArg;
19159
20904
  this.obs = resolveAgentObservability(observability);
@@ -19168,6 +20913,7 @@ var Tester = class {
19168
20913
  this.fileResolver = options.fileResolver;
19169
20914
  this.downloadStore = options.downloadStore;
19170
20915
  this.getDownloadTargetPath = options.getDownloadTargetPath;
20916
+ this.customCodeRuntime = options.customCodeRuntime;
19171
20917
  }
19172
20918
  setContext(context) {
19173
20919
  this.dataContext = context;
@@ -19213,6 +20959,7 @@ var Tester = class {
19213
20959
  getCommandText(command) {
19214
20960
  switch (command.type) {
19215
20961
  case "custom": return `Custom`;
20962
+ case "custom.code": return "Custom code";
19216
20963
  case "element.action":
19217
20964
  case "element.assertion": return `${command.data.type} ${command.target.name ? `"${command.target.name}"` : ""}`.trim();
19218
20965
  case "element.extract": return `${command.data.type} ${command.target.name ? `"${command.target.name}"` : ""}`.trim();
@@ -19579,7 +21326,7 @@ var Tester = class {
19579
21326
  command,
19580
21327
  context: commandContext
19581
21328
  });
19582
- if (command.type === "custom" && commandResult && isFailedCustomCommandResult(commandResult)) throw new Error(commandResult.error || `Custom command "${command._id}" failed.`);
21329
+ if ((command.type === "custom" || command.type === "custom.code") && commandResult && isFailedCustomCommandResult(commandResult)) throw new Error(commandResult.error || `Custom command "${command._id}" failed.`);
19583
21330
  this.obs.logger.log(`Finished executing command: ${command}`);
19584
21331
  yield await this.onCommandPass(command, stepDefinitionId, session);
19585
21332
  } catch (error) {
@@ -20513,28 +22260,63 @@ var Tester = class {
20513
22260
  const data = command.data;
20514
22261
  await this.executeUtilityCommand(data, input.page, context);
20515
22262
  return;
20516
- case "custom": return executePlaywrightCode({
20517
- page: input.page,
20518
- code: command.code,
20519
- context: {
20520
- stepId: command._id,
20521
- variables: context.stepParameters ?? {}
20522
- },
20523
- testData: context.testDataApi,
20524
- signal: context.abortSignal,
20525
- traceDelegate: {
20526
- startGroup: async (name) => {
20527
- try {
20528
- await this.activeBrowserContext?.tracing.group(name);
20529
- } catch {}
20530
- },
20531
- endGroup: async () => {
20532
- try {
20533
- await this.activeBrowserContext?.tracing.groupEnd();
20534
- } catch {}
20535
- }
22263
+ case "custom": {
22264
+ const defaultDialogHandler = (dialog) => {
22265
+ dialog.dismiss().catch(() => {});
22266
+ };
22267
+ const pageAsEventEmitter = input.page;
22268
+ const hasDialogSupport = typeof pageAsEventEmitter.on === "function" && typeof pageAsEventEmitter.off === "function";
22269
+ if (hasDialogSupport) pageAsEventEmitter.on("dialog", defaultDialogHandler);
22270
+ try {
22271
+ return await executePlaywrightCode({
22272
+ page: input.page,
22273
+ code: command.code,
22274
+ context: {
22275
+ stepId: command._id,
22276
+ variables: context.stepParameters ?? {}
22277
+ },
22278
+ testData: context.testDataApi,
22279
+ signal: context.abortSignal,
22280
+ traceDelegate: {
22281
+ startGroup: async (name) => {
22282
+ try {
22283
+ await this.activeBrowserContext?.tracing.group(name);
22284
+ } catch {}
22285
+ },
22286
+ endGroup: async () => {
22287
+ try {
22288
+ await this.activeBrowserContext?.tracing.groupEnd();
22289
+ } catch {}
22290
+ }
22291
+ }
22292
+ });
22293
+ } finally {
22294
+ if (hasDialogSupport) pageAsEventEmitter.off("dialog", defaultDialogHandler);
20536
22295
  }
20537
- });
22296
+ }
22297
+ case "custom.code": {
22298
+ if (!this.customCodeRuntime) return {
22299
+ success: false,
22300
+ error: "Custom code runtime is not configured for this worker.",
22301
+ errorKind: "feature_disabled"
22302
+ };
22303
+ const fetchImpl = this.getApiFetchImpl?.() ?? fetch;
22304
+ return await this.customCodeRuntime.execute({
22305
+ commandId: command._id,
22306
+ code: command.code,
22307
+ variables: context.stepParameters ?? {},
22308
+ page: input.page,
22309
+ testData: context.testDataApi,
22310
+ fetchImpl,
22311
+ checkpoint: async (label, data) => {
22312
+ this.obs.logger.info("customCode.checkpoint", {
22313
+ label,
22314
+ data
22315
+ });
22316
+ },
22317
+ signal: context.abortSignal
22318
+ });
22319
+ }
20538
22320
  case "api.action": {
20539
22321
  const fetchImpl = this.getApiFetchImpl?.();
20540
22322
  const apiResponse = await executeApiRequest(command.data, {
@@ -20573,12 +22355,24 @@ var Tester = class {
20573
22355
  });
20574
22356
  }
20575
22357
  }
20576
- async extractToTestData(input) {
20577
- if (!this.dataProvider || !this.dataContext) return;
20578
- await new TestDataApi(this.dataProvider, this.dataContext, {
22358
+ /**
22359
+ * Runtime test-data accessor bound to the tester's current data provider and
22360
+ * resolution context. Returns `undefined` when no provider/context is
22361
+ * configured (e.g. a tester constructed without a test-data layer). A fresh
22362
+ * instance is returned each access so it always reflects the latest context
22363
+ * set via `setContext`.
22364
+ */
22365
+ get testDataApi() {
22366
+ if (!this.dataProvider || !this.dataContext) return void 0;
22367
+ return new TestDataApi(this.dataProvider, this.dataContext, {
20579
22368
  onChange: this.onTestDataChange,
20580
22369
  logger: this.obs.logger
20581
- }).setRuntime(input.key, input.value, { dataType: input.dataType });
22370
+ });
22371
+ }
22372
+ async extractToTestData(input) {
22373
+ const api = this.testDataApi;
22374
+ if (!api) return;
22375
+ await api.setRuntime(input.key, input.value, { dataType: input.dataType });
20582
22376
  }
20583
22377
  async executePageExtraction(page, extract, storageDetails) {
20584
22378
  switch (extract.type) {
@@ -20746,6 +22540,13 @@ function createDataResolverPreprocessor(resolver) {
20746
22540
  code
20747
22541
  };
20748
22542
  }
22543
+ if (command.type === "custom.code" && typeof command.code === "string") {
22544
+ const { code, ...rest } = command;
22545
+ return {
22546
+ ...await resolver.resolveObject(rest, context.resolutionContext),
22547
+ code
22548
+ };
22549
+ }
20749
22550
  return resolver.resolveObject(command, context.resolutionContext);
20750
22551
  };
20751
22552
  }
@@ -23724,6 +25525,16 @@ function resolveSelectorString(selector) {
23724
25525
  if (selector.type === "pw.selectorString") return selector.selectorString;
23725
25526
  throw new Error(`Unsupported selector type "${selector.type}". bvt-playwright-js currently only resolves "pw.selectorString". Support for "bvt.selectorObject" needs to be ported from bvt-agent.`);
23726
25527
  }
25528
+ function toMatcherValue(value) {
25529
+ if (value === void 0) return;
25530
+ switch (value.type) {
25531
+ case "string":
25532
+ case "number":
25533
+ case "boolean": return value.value;
25534
+ case "regex": return new RegExp(value.source, value.flags);
25535
+ default: throw new Error(`Invalid matcher value: unknown type "${value.type}"`);
25536
+ }
25537
+ }
23727
25538
  const DEFAULT_PROJECT_ID = "01K00000000000000000000000";
23728
25539
  const BLINQ_ENVIRONMENT_ENV_VAR = "BLINQ_ENVIRONMENT";
23729
25540
  function toFilePath(target) {
@@ -24068,10 +25879,13 @@ function createBlinqTest(options = {}) {
24068
25879
  ...runtimeFilePath ? { testDataFilePath: runtimeFilePath } : { testDataFilePath: path.join(tmpdir(), `blinq-bvt-playwright-${process.pid}-${testInfo.workerIndex}-${testInfo.testId}.json`) }
24069
25880
  } }, { logger });
24070
25881
  runner.attach(page);
25882
+ const testDataApi = runner.tester.testDataApi;
25883
+ if (!testDataApi) throw new Error("bvt.testDataApi is unavailable: the runner has no test-data provider/context. Extract steps require a configured test-data layer.");
24071
25884
  try {
24072
25885
  await use({
24073
25886
  page,
24074
25887
  parameters: runner.parameters,
25888
+ testDataApi,
24075
25889
  executeCommand: (command, stepParameters) => runner.executeCommand(command, stepParameters),
24076
25890
  resolveCommand: (command, stepParameters) => runner.resolveCommand(command, stepParameters),
24077
25891
  find: (command) => runner.find(command),
@@ -24089,5 +25903,5 @@ function createBlinqTest(options = {}) {
24089
25903
  }
24090
25904
 
24091
25905
  //#endregion
24092
- export { PlaywrightRunner, TempFileTestDataProvider, createBlinqTest, createBlinqTest as default };
25906
+ export { PlaywrightRunner, TempFileTestDataProvider, createBlinqTest, createBlinqTest as default, toMatcherValue };
24093
25907
  //# sourceMappingURL=index.mjs.map