@modelnex/sdk 0.5.46 → 0.5.48

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -4732,6 +4732,13 @@ function useTourPlayback({
4732
4732
  },
4733
4733
  resolve: async () => {
4734
4734
  let targetEl = null;
4735
+ if (typeof params.selector === "string" && params.selector.trim()) {
4736
+ try {
4737
+ targetEl = document.querySelector(params.selector.trim());
4738
+ } catch {
4739
+ targetEl = null;
4740
+ }
4741
+ }
4735
4742
  if (params.uid) {
4736
4743
  const { getElementByUid: getElementByUid2 } = await Promise.resolve().then(() => (init_aom(), aom_exports));
4737
4744
  targetEl = getElementByUid2(params.uid);
@@ -4876,6 +4883,49 @@ function useTourPlayback({
4876
4883
  const resolution = typeof action.params?.resolution === "string" ? action.params.resolution : void 0;
4877
4884
  return { result: await captureScreenshot(selector, resolution) };
4878
4885
  }
4886
+ if (action.type === "get_ui_messages") {
4887
+ const includeHidden = action.params?.includeHidden === true;
4888
+ const maxItems = Number.isFinite(action.params?.maxItems) ? Number(action.params.maxItems) : void 0;
4889
+ const messages = collectUiMessages({ includeHidden, maxItems });
4890
+ return {
4891
+ result: {
4892
+ messages,
4893
+ total: messages.length,
4894
+ capturedAt: Date.now()
4895
+ }
4896
+ };
4897
+ }
4898
+ if (action.type === "get_last_action_effect") {
4899
+ return {
4900
+ result: {
4901
+ effect: getLastActionEffectRecord()
4902
+ }
4903
+ };
4904
+ }
4905
+ if (action.type === "inspect_element_state") {
4906
+ const targetEl = await resolveTargetElement2(action.params, currentStep);
4907
+ if (!targetEl) {
4908
+ return {
4909
+ success: false,
4910
+ result: {
4911
+ found: false,
4912
+ reason: "Element not found from the provided fingerprint, selector, uid, or text hint."
4913
+ },
4914
+ error: "inspect_element_not_found"
4915
+ };
4916
+ }
4917
+ const resolvedVia = typeof action.params?.selector === "string" && action.params.selector.trim() ? "selector" : action.params?.uid ? "uid" : action.params?.fingerprint ? "fingerprint" : action.params?.textContaining ? "textContaining" : "fallback";
4918
+ return {
4919
+ result: {
4920
+ found: true,
4921
+ target: {
4922
+ fingerprint: targetEl.getAttribute("data-modelnex-fp") || null,
4923
+ resolvedVia
4924
+ },
4925
+ element: inspectDomElementState(targetEl)
4926
+ }
4927
+ };
4928
+ }
4879
4929
  if (action.type === "navigate_to_url") {
4880
4930
  const nextUrl = typeof action.params?.url === "string" ? action.params.url : "";
4881
4931
  if (!nextUrl) {
@@ -4928,8 +4978,13 @@ function useTourPlayback({
4928
4978
  handleTourEnd();
4929
4979
  return { result: "ended" };
4930
4980
  }
4931
- console.warn(`[TourClient] Unknown action type: ${String(action?.type ?? "unknown")}. Skipping.`);
4932
- return { result: "unknown_action_skipped" };
4981
+ const unknownAction = String(action?.type ?? "unknown");
4982
+ console.warn(`[TourClient] Unknown action type: ${unknownAction}. Skipping.`);
4983
+ return {
4984
+ success: false,
4985
+ result: "unknown_action_skipped",
4986
+ error: `Unknown action type: ${unknownAction}`
4987
+ };
4933
4988
  };
4934
4989
  try {
4935
4990
  const resultsBuffer = new Array(payload.commands.length);
@@ -4943,9 +4998,27 @@ function useTourPlayback({
4943
4998
  pendingUIActions.length = 0;
4944
4999
  }
4945
5000
  const executionPromise = (async () => {
5001
+ const beforeSnapshot = captureDebugSnapshot();
5002
+ const startedAt = Date.now();
4946
5003
  const execution = await executeOne(command);
4947
5004
  await execution.settlePromise;
4948
- resultsBuffer[commandIndex] = { type: command.type, success: true, result: execution.result };
5005
+ const success = execution.success !== false;
5006
+ const error = typeof execution.error === "string" ? execution.error : null;
5007
+ recordLastActionEffect({
5008
+ actionId: command.type,
5009
+ success,
5010
+ error,
5011
+ startedAt,
5012
+ finishedAt: Date.now(),
5013
+ before: beforeSnapshot,
5014
+ after: captureDebugSnapshot()
5015
+ });
5016
+ resultsBuffer[commandIndex] = {
5017
+ type: command.type,
5018
+ success,
5019
+ result: execution.result,
5020
+ ...error ? { error } : {}
5021
+ };
4949
5022
  })();
4950
5023
  if (isTerminal) {
4951
5024
  await executionPromise;
@@ -5189,27 +5262,33 @@ function useTourPlayback({
5189
5262
  skipRequestedRef.current = false;
5190
5263
  startRequestedRef.current = false;
5191
5264
  const total = tourData.totalSteps ?? tour?.steps?.length ?? 0;
5265
+ const requestedStepIndex = typeof tourData.currentStepIndex === "number" ? tourData.currentStepIndex : 0;
5266
+ const clampedStepIndex = Math.max(0, Math.min(requestedStepIndex, Math.max(0, total - 1)));
5192
5267
  isActiveRef.current = true;
5193
5268
  setIsActive(true);
5194
5269
  setActiveTour(tour ?? null);
5195
5270
  tourRef.current = tour ?? null;
5196
5271
  setTotalSteps(total);
5197
- stepIndexRef.current = 0;
5198
- setCurrentStepIndex(0);
5272
+ stepIndexRef.current = clampedStepIndex;
5273
+ setCurrentStepIndex(clampedStepIndex);
5199
5274
  setPlaybackState("intro");
5200
5275
  if (reviewModeRef.current && tour?.id && previewRunIdRef.current) {
5201
5276
  void logPreviewEvent(serverUrl, toursApiBaseRef.current, tour.id, previewRunIdRef.current, websiteId, {
5202
- stepOrder: 0,
5277
+ stepOrder: clampedStepIndex,
5203
5278
  eventType: "tour_started",
5204
5279
  payload: {
5205
5280
  totalSteps: total,
5206
- source: "sdk_test_preview"
5281
+ source: "sdk_test_preview",
5282
+ resumed: Boolean(tourData.resumed)
5207
5283
  },
5208
- currentStepOrder: 0
5284
+ currentStepOrder: clampedStepIndex
5209
5285
  });
5210
5286
  } else if (tour?.id && userProfile?.userId) {
5211
5287
  void recordTourEvent(serverUrl, toursApiBaseRef.current, tour.id, userProfile.userId, "started", websiteId);
5212
5288
  }
5289
+ if (tour && total > 0) {
5290
+ onStepChangeRef.current?.(clampedStepIndex, total, tour);
5291
+ }
5213
5292
  try {
5214
5293
  const { generateMinifiedAOM: generateMinifiedAOM2 } = await Promise.resolve().then(() => (init_aom(), aom_exports));
5215
5294
  const aom = generateMinifiedAOM2();
package/dist/index.mjs CHANGED
@@ -3903,6 +3903,13 @@ function useTourPlayback({
3903
3903
  },
3904
3904
  resolve: async () => {
3905
3905
  let targetEl = null;
3906
+ if (typeof params.selector === "string" && params.selector.trim()) {
3907
+ try {
3908
+ targetEl = document.querySelector(params.selector.trim());
3909
+ } catch {
3910
+ targetEl = null;
3911
+ }
3912
+ }
3906
3913
  if (params.uid) {
3907
3914
  const { getElementByUid } = await import("./aom-SP2LMWQI.mjs");
3908
3915
  targetEl = getElementByUid(params.uid);
@@ -4047,6 +4054,49 @@ function useTourPlayback({
4047
4054
  const resolution = typeof action.params?.resolution === "string" ? action.params.resolution : void 0;
4048
4055
  return { result: await captureScreenshot(selector, resolution) };
4049
4056
  }
4057
+ if (action.type === "get_ui_messages") {
4058
+ const includeHidden = action.params?.includeHidden === true;
4059
+ const maxItems = Number.isFinite(action.params?.maxItems) ? Number(action.params.maxItems) : void 0;
4060
+ const messages = collectUiMessages({ includeHidden, maxItems });
4061
+ return {
4062
+ result: {
4063
+ messages,
4064
+ total: messages.length,
4065
+ capturedAt: Date.now()
4066
+ }
4067
+ };
4068
+ }
4069
+ if (action.type === "get_last_action_effect") {
4070
+ return {
4071
+ result: {
4072
+ effect: getLastActionEffectRecord()
4073
+ }
4074
+ };
4075
+ }
4076
+ if (action.type === "inspect_element_state") {
4077
+ const targetEl = await resolveTargetElement2(action.params, currentStep);
4078
+ if (!targetEl) {
4079
+ return {
4080
+ success: false,
4081
+ result: {
4082
+ found: false,
4083
+ reason: "Element not found from the provided fingerprint, selector, uid, or text hint."
4084
+ },
4085
+ error: "inspect_element_not_found"
4086
+ };
4087
+ }
4088
+ const resolvedVia = typeof action.params?.selector === "string" && action.params.selector.trim() ? "selector" : action.params?.uid ? "uid" : action.params?.fingerprint ? "fingerprint" : action.params?.textContaining ? "textContaining" : "fallback";
4089
+ return {
4090
+ result: {
4091
+ found: true,
4092
+ target: {
4093
+ fingerprint: targetEl.getAttribute("data-modelnex-fp") || null,
4094
+ resolvedVia
4095
+ },
4096
+ element: inspectDomElementState(targetEl)
4097
+ }
4098
+ };
4099
+ }
4050
4100
  if (action.type === "navigate_to_url") {
4051
4101
  const nextUrl = typeof action.params?.url === "string" ? action.params.url : "";
4052
4102
  if (!nextUrl) {
@@ -4099,8 +4149,13 @@ function useTourPlayback({
4099
4149
  handleTourEnd();
4100
4150
  return { result: "ended" };
4101
4151
  }
4102
- console.warn(`[TourClient] Unknown action type: ${String(action?.type ?? "unknown")}. Skipping.`);
4103
- return { result: "unknown_action_skipped" };
4152
+ const unknownAction = String(action?.type ?? "unknown");
4153
+ console.warn(`[TourClient] Unknown action type: ${unknownAction}. Skipping.`);
4154
+ return {
4155
+ success: false,
4156
+ result: "unknown_action_skipped",
4157
+ error: `Unknown action type: ${unknownAction}`
4158
+ };
4104
4159
  };
4105
4160
  try {
4106
4161
  const resultsBuffer = new Array(payload.commands.length);
@@ -4114,9 +4169,27 @@ function useTourPlayback({
4114
4169
  pendingUIActions.length = 0;
4115
4170
  }
4116
4171
  const executionPromise = (async () => {
4172
+ const beforeSnapshot = captureDebugSnapshot();
4173
+ const startedAt = Date.now();
4117
4174
  const execution = await executeOne(command);
4118
4175
  await execution.settlePromise;
4119
- resultsBuffer[commandIndex] = { type: command.type, success: true, result: execution.result };
4176
+ const success = execution.success !== false;
4177
+ const error = typeof execution.error === "string" ? execution.error : null;
4178
+ recordLastActionEffect({
4179
+ actionId: command.type,
4180
+ success,
4181
+ error,
4182
+ startedAt,
4183
+ finishedAt: Date.now(),
4184
+ before: beforeSnapshot,
4185
+ after: captureDebugSnapshot()
4186
+ });
4187
+ resultsBuffer[commandIndex] = {
4188
+ type: command.type,
4189
+ success,
4190
+ result: execution.result,
4191
+ ...error ? { error } : {}
4192
+ };
4120
4193
  })();
4121
4194
  if (isTerminal) {
4122
4195
  await executionPromise;
@@ -4360,27 +4433,33 @@ function useTourPlayback({
4360
4433
  skipRequestedRef.current = false;
4361
4434
  startRequestedRef.current = false;
4362
4435
  const total = tourData.totalSteps ?? tour?.steps?.length ?? 0;
4436
+ const requestedStepIndex = typeof tourData.currentStepIndex === "number" ? tourData.currentStepIndex : 0;
4437
+ const clampedStepIndex = Math.max(0, Math.min(requestedStepIndex, Math.max(0, total - 1)));
4363
4438
  isActiveRef.current = true;
4364
4439
  setIsActive(true);
4365
4440
  setActiveTour(tour ?? null);
4366
4441
  tourRef.current = tour ?? null;
4367
4442
  setTotalSteps(total);
4368
- stepIndexRef.current = 0;
4369
- setCurrentStepIndex(0);
4443
+ stepIndexRef.current = clampedStepIndex;
4444
+ setCurrentStepIndex(clampedStepIndex);
4370
4445
  setPlaybackState("intro");
4371
4446
  if (reviewModeRef.current && tour?.id && previewRunIdRef.current) {
4372
4447
  void logPreviewEvent(serverUrl, toursApiBaseRef.current, tour.id, previewRunIdRef.current, websiteId, {
4373
- stepOrder: 0,
4448
+ stepOrder: clampedStepIndex,
4374
4449
  eventType: "tour_started",
4375
4450
  payload: {
4376
4451
  totalSteps: total,
4377
- source: "sdk_test_preview"
4452
+ source: "sdk_test_preview",
4453
+ resumed: Boolean(tourData.resumed)
4378
4454
  },
4379
- currentStepOrder: 0
4455
+ currentStepOrder: clampedStepIndex
4380
4456
  });
4381
4457
  } else if (tour?.id && userProfile?.userId) {
4382
4458
  void recordTourEvent(serverUrl, toursApiBaseRef.current, tour.id, userProfile.userId, "started", websiteId);
4383
4459
  }
4460
+ if (tour && total > 0) {
4461
+ onStepChangeRef.current?.(clampedStepIndex, total, tour);
4462
+ }
4384
4463
  try {
4385
4464
  const { generateMinifiedAOM: generateMinifiedAOM2 } = await import("./aom-SP2LMWQI.mjs");
4386
4465
  const aom = generateMinifiedAOM2();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@modelnex/sdk",
3
- "version": "0.5.46",
3
+ "version": "0.5.48",
4
4
  "description": "React SDK for natural language control of web apps via AI agents",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",