@webless/agent 0.3.0 → 0.3.2

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/embed.cjs CHANGED
@@ -178,11 +178,12 @@ function createAgentRuntimeCapability(options) {
178
178
  let pendingBootstrap;
179
179
  const bootstrap = async () => {
180
180
  let previewGrant;
181
+ const previewBuildId = options.previewBuildId?.trim();
181
182
  if (options.version === "unpublished") {
182
- previewGrant = (await options.getUnpublishedPreviewGrant?.())?.trim();
183
- if (!previewGrant) {
183
+ previewGrant = previewBuildId ? void 0 : (await options.getUnpublishedPreviewGrant?.())?.trim();
184
+ if (!previewGrant && !previewBuildId) {
184
185
  throw new Error(
185
- "An unpublished preview grant is required to use the Agent Runtime preview."
186
+ "Unpublished preview authorization is required to use the Agent Runtime preview."
186
187
  );
187
188
  }
188
189
  }
@@ -192,6 +193,7 @@ function createAgentRuntimeCapability(options) {
192
193
  body: JSON.stringify({
193
194
  clientSessionId: options.visitorSessionId,
194
195
  indexId: options.indexId,
196
+ ...previewBuildId ? { previewBuildId } : {},
195
197
  ...previewGrant ? { previewGrant } : {},
196
198
  version: options.version
197
199
  }),
@@ -511,7 +513,7 @@ function applyWorkEvent(event, handlers, workItems) {
511
513
  );
512
514
  }
513
515
  var AgentSession = class {
514
- constructor(indexId, version, runtimeOrigin, visitorSessionId, storeOptions, getUnpublishedPreviewGrant) {
516
+ constructor(indexId, version, runtimeOrigin, visitorSessionId, storeOptions, previewBuildId, getUnpublishedPreviewGrant) {
515
517
  this.indexId = indexId;
516
518
  this.version = version;
517
519
  this.runtimeOrigin = runtimeOrigin;
@@ -520,6 +522,7 @@ var AgentSession = class {
520
522
  this.capability = createAgentRuntimeCapability({
521
523
  getUnpublishedPreviewGrant,
522
524
  indexId,
525
+ previewBuildId,
523
526
  runtimeOrigin,
524
527
  version,
525
528
  visitorSessionId
@@ -764,6 +767,7 @@ function createAgentClient(options) {
764
767
  runtimeOrigin,
765
768
  visitorSessionId,
766
769
  storeOptions,
770
+ options.previewBuildId,
767
771
  options.getUnpublishedPreviewGrant
768
772
  );
769
773
  return {
@@ -790,6 +794,16 @@ function createAgentClient(options) {
790
794
 
791
795
  // src/runtime/errors.ts
792
796
  var import_client3 = require("eve/client");
797
+ var TRANSIENT_AGENT_ERROR_MESSAGE = "I couldn\u2019t finish that answer. Please try again.";
798
+ var PREVIEW_AUTHORIZATION_ERROR_MESSAGE = "This preview could not be authorized. Open the latest preview from Webless.";
799
+ function isTransientRuntimeMessage(message) {
800
+ const normalized = message.trim().toLowerCase();
801
+ return normalized.includes("empty response from runtime") || normalized.includes("failed to fetch") || normalized.includes("networkerror") || normalized.includes("load failed");
802
+ }
803
+ function isPreviewAuthorizationMessage(message) {
804
+ const normalized = message.trim().toLowerCase();
805
+ return normalized.includes("unpublished preview authorization") || normalized.includes("unpublished preview grant") || normalized.includes("agent studio preview grant") || normalized.includes("preview authorization");
806
+ }
793
807
  function formatAgentError(error) {
794
808
  if (error instanceof import_client3.ClientError) {
795
809
  if (error.status === 401 && error.code === "index_required") {
@@ -801,13 +815,24 @@ function formatAgentError(error) {
801
815
  if (error.status === 409 && error.code === "session_not_active") {
802
816
  return "Session expired \u2014 send a new message to start again.";
803
817
  }
804
- return error.message || `Runtime error (${error.status})`;
818
+ if (error.message && isPreviewAuthorizationMessage(error.message)) {
819
+ return PREVIEW_AUTHORIZATION_ERROR_MESSAGE;
820
+ }
821
+ if (error.status >= 500 || error.message && isTransientRuntimeMessage(error.message)) {
822
+ return TRANSIENT_AGENT_ERROR_MESSAGE;
823
+ }
824
+ return error.message || "This assistant is unavailable right now.";
805
825
  }
806
826
  if (error instanceof DOMException && error.name === "AbortError") {
807
827
  return "";
808
828
  }
809
- if (error instanceof Error) return error.message;
810
- return "Runtime request failed";
829
+ if (error instanceof Error) {
830
+ if (isPreviewAuthorizationMessage(error.message)) {
831
+ return PREVIEW_AUTHORIZATION_ERROR_MESSAGE;
832
+ }
833
+ return isTransientRuntimeMessage(error.message) ? TRANSIENT_AGENT_ERROR_MESSAGE : error.message;
834
+ }
835
+ return TRANSIENT_AGENT_ERROR_MESSAGE;
811
836
  }
812
837
 
813
838
  // src/react/persisted-conversation.ts
@@ -916,6 +941,7 @@ function useAgentChat({
916
941
  customerId,
917
942
  getUnpublishedPreviewGrant,
918
943
  indexId,
944
+ previewBuildId,
919
945
  version,
920
946
  runtimeOrigin,
921
947
  visitorSessionId,
@@ -966,13 +992,14 @@ function useAgentChat({
966
992
  customerId,
967
993
  getUnpublishedPreviewGrant: resolveUnpublishedPreviewGrant,
968
994
  indexId,
995
+ previewBuildId,
969
996
  version,
970
997
  runtimeOrigin,
971
998
  visitorSessionId: visitorId,
972
999
  storageKeyPrefix: resolvedStorageKeyPrefix
973
1000
  })
974
1001
  );
975
- const identityKey = `${customerId ?? ""}|${indexId}|${version ?? "published"}|${runtimeOrigin ?? ""}|${resolvedStorageKeyPrefix}|${visitorId}|${greeting ?? ""}`;
1002
+ const identityKey = `${customerId ?? ""}|${indexId}|${version ?? "published"}|${runtimeOrigin ?? ""}|${previewBuildId ?? ""}|${resolvedStorageKeyPrefix}|${visitorId}|${greeting ?? ""}`;
976
1003
  const identityRef = (0, import_react2.useRef)(identityKey);
977
1004
  (0, import_react2.useEffect)(() => {
978
1005
  if (identityRef.current === identityKey) {
@@ -985,6 +1012,7 @@ function useAgentChat({
985
1012
  customerId,
986
1013
  getUnpublishedPreviewGrant: resolveUnpublishedPreviewGrant,
987
1014
  indexId,
1015
+ previewBuildId,
988
1016
  version,
989
1017
  runtimeOrigin,
990
1018
  visitorSessionId: visitorId,
@@ -1001,6 +1029,7 @@ function useAgentChat({
1001
1029
  identityKey,
1002
1030
  indexId,
1003
1031
  initialState,
1032
+ previewBuildId,
1004
1033
  runtimeOrigin,
1005
1034
  resolvedStorageKeyPrefix,
1006
1035
  version,
@@ -1104,8 +1133,8 @@ function useAgentChat({
1104
1133
  if (!message) return;
1105
1134
  setState((prev) => ({
1106
1135
  ...prev,
1107
- phase: "complete",
1108
- toolSteps: prev.toolSteps.map(
1136
+ phase: "error",
1137
+ toolSteps: prev.toolSteps.length === 1 && prev.toolSteps[0]?.kind === "planning" ? [] : prev.toolSteps.map(
1109
1138
  (step) => step.state === "active" ? {
1110
1139
  ...step,
1111
1140
  detail: "Couldn\u2019t complete this step",
@@ -1264,11 +1293,12 @@ var defaultAgentRailTheme = {
1264
1293
 
1265
1294
  // src/react/components/AgentActivityBubble/AgentActivityBubble.tsx
1266
1295
  var import_jsx_runtime = require("react/jsx-runtime");
1267
- function workSummary(steps) {
1296
+ function workSummary(steps, failed) {
1268
1297
  const active = [...steps].reverse().find((step) => step.state === "active");
1269
1298
  if (active?.kind === "specialist") return `Working with ${active.label}`;
1270
1299
  if (active?.kind === "search") return "Searching this site";
1271
1300
  if (active) return active.label;
1301
+ if (failed) return "Couldn\u2019t complete this request";
1272
1302
  const hasError = steps.some((step) => step.state === "error");
1273
1303
  const specialists = steps.filter(
1274
1304
  (step) => step.kind === "specialist" && step.state === "completed"
@@ -1283,18 +1313,21 @@ function workSummary(steps) {
1283
1313
  if (searched) return "Searched this site";
1284
1314
  return "Prepared a response";
1285
1315
  }
1286
- function AgentActivityBubble({ steps }) {
1316
+ function AgentActivityBubble({
1317
+ failed = false,
1318
+ steps
1319
+ }) {
1287
1320
  const active = steps.some((step) => step.state === "active");
1288
1321
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("article", { className: "agent-activity-bubble", children: [
1289
1322
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("p", { className: "agent-activity-bubble__status", "aria-live": "polite", children: [
1290
1323
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1291
1324
  "span",
1292
1325
  {
1293
- className: `agent-activity-bubble__pulse${active ? " is-active" : ""}`,
1326
+ className: `agent-activity-bubble__pulse${active ? " is-active" : failed ? " is-error" : ""}`,
1294
1327
  "aria-hidden": "true"
1295
1328
  }
1296
1329
  ),
1297
- workSummary(steps)
1330
+ workSummary(steps, failed)
1298
1331
  ] }),
1299
1332
  /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("details", { className: "agent-activity-bubble__details", open: active, children: [
1300
1333
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)("summary", { children: "Work details" }),
@@ -1602,7 +1635,13 @@ function AgentRail({
1602
1635
  /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { ref: transcriptRef, className: "agent-rail__transcript", children: [
1603
1636
  state.messages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MessageBubble, { message }, message.id)),
1604
1637
  streamingMessage ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MessageBubble, { message: streamingMessage }) : null,
1605
- showActivity ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(AgentActivityBubble, { steps: state.toolSteps }) : null,
1638
+ showActivity ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1639
+ AgentActivityBubble,
1640
+ {
1641
+ failed: state.phase === "error",
1642
+ steps: state.toolSteps
1643
+ }
1644
+ ) : null,
1606
1645
  !expanded && showIdleFollowUps ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "agent-rail__followups-slot", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1607
1646
  FollowUpChips,
1608
1647
  {
@@ -1814,6 +1853,7 @@ function AgentWidget({
1814
1853
  indexId,
1815
1854
  customerId,
1816
1855
  getUnpublishedPreviewGrant,
1856
+ previewBuildId,
1817
1857
  version,
1818
1858
  runtimeOrigin,
1819
1859
  placement: placementInput,
@@ -1841,6 +1881,7 @@ function AgentWidget({
1841
1881
  customerId,
1842
1882
  getUnpublishedPreviewGrant,
1843
1883
  indexId,
1884
+ previewBuildId,
1844
1885
  version,
1845
1886
  runtimeOrigin,
1846
1887
  greeting: branding?.greeting
@@ -1946,6 +1987,19 @@ function AgentWidget({
1946
1987
  ] });
1947
1988
  }
1948
1989
 
1990
+ // src/embed/preview-build.ts
1991
+ var PREVIEW_BUILD_ID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/iu;
1992
+ function readUnpublishedPreviewBuildId(href) {
1993
+ const source = href ?? (typeof window === "undefined" ? void 0 : window.location.href);
1994
+ if (!source) return void 0;
1995
+ try {
1996
+ const buildId = new URL(source).searchParams.get("v")?.trim();
1997
+ return buildId && PREVIEW_BUILD_ID_PATTERN.test(buildId) ? buildId : void 0;
1998
+ } catch {
1999
+ return void 0;
2000
+ }
2001
+ }
2002
+
1949
2003
  // src/embed/AgentWidget.tsx
1950
2004
  var import_jsx_runtime8 = require("react/jsx-runtime");
1951
2005
  function AgentWidget2({
@@ -1958,6 +2012,7 @@ function AgentWidget2({
1958
2012
  customerId: manifest.customerId,
1959
2013
  version: manifest.version,
1960
2014
  runtimeOrigin: manifest.runtimeOrigin,
2015
+ previewBuildId: manifest.version === "unpublished" ? readUnpublishedPreviewBuildId() : void 0,
1961
2016
  placement: manifest.placement,
1962
2017
  pageShift: manifest.pageShift,
1963
2018
  branding: manifest.branding,