@usecrow/ui 0.1.42 → 0.1.44

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.cjs CHANGED
@@ -905,11 +905,44 @@ function useCrowAPI({ onIdentified, onReset } = {}) {
905
905
  window.__crow_page_context = void 0;
906
906
  console.log("[Crow] Context cleared");
907
907
  break;
908
+ case "setIdentityTokenFetcher":
909
+ if (typeof opts !== "function") {
910
+ console.error("[Crow] setIdentityTokenFetcher() requires a function");
911
+ return;
912
+ }
913
+ window.__crow_identity_token_fetcher = opts;
914
+ console.log("[Crow] Identity token fetcher registered");
915
+ break;
916
+ case "onToolResult":
917
+ if (typeof opts !== "function") {
918
+ console.error("[Crow] onToolResult() requires a function");
919
+ return;
920
+ }
921
+ window.__crow_on_tool_result = opts;
922
+ console.log("[Crow] onToolResult callback registered");
923
+ break;
924
+ case "registerToolRenderers":
925
+ if (!opts || typeof opts !== "object") {
926
+ console.error("[Crow] registerToolRenderers() requires an object");
927
+ return;
928
+ }
929
+ window.__crow_tool_renderers = {
930
+ ...window.__crow_tool_renderers || {},
931
+ ...opts
932
+ };
933
+ console.log("[Crow] Tool renderers registered");
934
+ break;
908
935
  default:
909
936
  console.warn(`[Crow] Unknown command: ${command}`);
910
937
  }
911
938
  };
912
939
  console.log("[Crow] API ready");
940
+ const queue = window.__crow_queue;
941
+ if (queue?.length) {
942
+ console.log(`[Crow] Replaying ${queue.length} queued command(s)`);
943
+ queue.forEach(([cmd, opts]) => window.crow(cmd, opts));
944
+ window.__crow_queue = void 0;
945
+ }
913
946
  const handleIdentified = () => onIdentifiedRef.current?.();
914
947
  const handleReset = () => onResetRef.current?.();
915
948
  window.addEventListener("crow:identified", handleIdentified);
@@ -1941,6 +1974,23 @@ function ThinkingBlock({
1941
1974
  ) })
1942
1975
  ] });
1943
1976
  }
1977
+ function RenderedToolResult({ renderer, result, status }) {
1978
+ const domRef = React3.useRef(null);
1979
+ const rendered = renderer({ result, status });
1980
+ React3.useEffect(() => {
1981
+ if (domRef.current && rendered instanceof HTMLElement) {
1982
+ domRef.current.innerHTML = "";
1983
+ domRef.current.appendChild(rendered);
1984
+ }
1985
+ }, [rendered]);
1986
+ if (rendered instanceof HTMLElement) {
1987
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "crow-mt-1.5 crow-mb-0.5", ref: domRef });
1988
+ }
1989
+ if (typeof rendered === "string") {
1990
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "crow-mt-1.5 crow-mb-0.5", dangerouslySetInnerHTML: { __html: rendered } });
1991
+ }
1992
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "crow-mt-1.5 crow-mb-0.5", children: rendered });
1993
+ }
1944
1994
  function ToolCallBlock({
1945
1995
  toolCall,
1946
1996
  toolRenderers
@@ -1980,7 +2030,7 @@ function ToolCallBlock({
1980
2030
  ]
1981
2031
  }
1982
2032
  ),
1983
- hasCustomRender && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "crow-mt-1.5 crow-mb-0.5", children: customRenderer({ result: toolCall.result, status: toolCall.status }) }),
2033
+ hasCustomRender && /* @__PURE__ */ jsxRuntime.jsx(RenderedToolResult, { renderer: customRenderer, result: toolCall.result, status: toolCall.status }),
1984
2034
  /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { children: expanded && hasArgs && /* @__PURE__ */ jsxRuntime.jsx(
1985
2035
  framerMotion.motion.div,
1986
2036
  {
@@ -2939,8 +2989,12 @@ function CrowWidget({
2939
2989
  navigate,
2940
2990
  onToolResult,
2941
2991
  getIdentityToken,
2942
- context
2992
+ context,
2993
+ toolRenderers
2943
2994
  }) {
2995
+ const effectiveGetIdentityToken = getIdentityToken || window.__crow_identity_token_fetcher;
2996
+ const effectiveOnToolResult = onToolResult || window.__crow_on_tool_result;
2997
+ const effectiveToolRenderers = toolRenderers || window.__crow_tool_renderers;
2944
2998
  const {
2945
2999
  styles,
2946
3000
  isLoading: isLoadingStyles,
@@ -3019,7 +3073,7 @@ function CrowWidget({
3019
3073
  break;
3020
3074
  }
3021
3075
  },
3022
- onToolResult,
3076
+ onToolResult: effectiveOnToolResult,
3023
3077
  onToolCall: async (event) => {
3024
3078
  if (event.type === "client_call" && event.toolName && event.toolCallId) {
3025
3079
  try {
@@ -3118,11 +3172,11 @@ function CrowWidget({
3118
3172
  }
3119
3173
  }, [isLoadingStyles, onIdentify]);
3120
3174
  React3.useEffect(() => {
3121
- if (!getIdentityToken || isLoadingStyles) return;
3175
+ if (!effectiveGetIdentityToken || isLoadingStyles) return;
3122
3176
  let cancelled = false;
3123
3177
  const identify = async () => {
3124
3178
  try {
3125
- const token = await getIdentityToken();
3179
+ const token = await effectiveGetIdentityToken();
3126
3180
  if (!cancelled && token) {
3127
3181
  window.crow?.("identify", { token });
3128
3182
  }
@@ -3137,7 +3191,7 @@ function CrowWidget({
3137
3191
  cancelled = true;
3138
3192
  window.removeEventListener("crow:token-refresh-needed", handleRefresh);
3139
3193
  };
3140
- }, [getIdentityToken, isLoadingStyles]);
3194
+ }, [effectiveGetIdentityToken, isLoadingStyles]);
3141
3195
  React3.useEffect(() => {
3142
3196
  if (typeof window === "undefined") return;
3143
3197
  if (context && Object.keys(context).length > 0) {
@@ -3194,6 +3248,19 @@ function CrowWidget({
3194
3248
  });
3195
3249
  }
3196
3250
  }, [browserUseEnabled, isLoadingStyles, productId, apiUrl, autoTools]);
3251
+ React3.useEffect(() => {
3252
+ if (browserUseEnabled && !isLoadingStyles && !autoTools.execute_recorded_workflow) {
3253
+ import('@usecrow/client/browser').then(({ createExecuteRecordedWorkflowTool }) => {
3254
+ setAutoTools((prev) => ({
3255
+ ...prev,
3256
+ execute_recorded_workflow: createExecuteRecordedWorkflowTool({ productId, apiUrl })
3257
+ }));
3258
+ console.log("[Crow] execute_recorded_workflow tool auto-loaded");
3259
+ }).catch((err) => {
3260
+ console.warn("[Crow] Failed to load execute_recorded_workflow:", err);
3261
+ });
3262
+ }
3263
+ }, [browserUseEnabled, isLoadingStyles, productId, apiUrl, autoTools]);
3197
3264
  React3.useEffect(() => {
3198
3265
  if (pageNavigationEnabled && pageNavigationRoutes.length > 0 && !isLoadingStyles) {
3199
3266
  import('@usecrow/client').then(({ createNavigateToPageTool }) => {
@@ -3311,7 +3378,8 @@ function CrowWidget({
3311
3378
  messages: chat.messages,
3312
3379
  activeToolCalls: chat.activeToolCalls,
3313
3380
  isLoadingHistory: conversations.isLoadingHistory,
3314
- isGenerating: chat.isLoading
3381
+ isGenerating: chat.isLoading,
3382
+ toolRenderers: effectiveToolRenderers
3315
3383
  }
3316
3384
  ),
3317
3385
  pendingConfirmation && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "crow-px-4 crow-py-2", children: /* @__PURE__ */ jsxRuntime.jsx(
@@ -3511,6 +3579,9 @@ function CrowCopilot({
3511
3579
  getIdentityToken,
3512
3580
  context
3513
3581
  }) {
3582
+ const effectiveGetIdentityToken = getIdentityToken || window.__crow_identity_token_fetcher;
3583
+ const effectiveOnToolResult = onToolResult || window.__crow_on_tool_result;
3584
+ const effectiveToolRenderers = toolRenderers || window.__crow_tool_renderers;
3514
3585
  const {
3515
3586
  styles,
3516
3587
  isLoading: isLoadingStyles,
@@ -3614,7 +3685,7 @@ function CrowCopilot({
3614
3685
  break;
3615
3686
  }
3616
3687
  },
3617
- onToolResult,
3688
+ onToolResult: effectiveOnToolResult,
3618
3689
  onToolCall: async (event) => {
3619
3690
  if (event.type === "client_call" && event.toolName && event.toolCallId) {
3620
3691
  try {
@@ -3760,11 +3831,11 @@ function CrowCopilot({
3760
3831
  }
3761
3832
  }, [isLoadingStyles, onReady]);
3762
3833
  React3.useEffect(() => {
3763
- if (!getIdentityToken || isLoadingStyles) return;
3834
+ if (!effectiveGetIdentityToken || isLoadingStyles) return;
3764
3835
  let cancelled = false;
3765
3836
  const identify = async () => {
3766
3837
  try {
3767
- const token = await getIdentityToken();
3838
+ const token = await effectiveGetIdentityToken();
3768
3839
  if (!cancelled && token) {
3769
3840
  window.crow?.("identify", { token });
3770
3841
  }
@@ -3779,7 +3850,7 @@ function CrowCopilot({
3779
3850
  cancelled = true;
3780
3851
  window.removeEventListener("crow:token-refresh-needed", handleRefresh);
3781
3852
  };
3782
- }, [getIdentityToken, isLoadingStyles]);
3853
+ }, [effectiveGetIdentityToken, isLoadingStyles]);
3783
3854
  React3.useEffect(() => {
3784
3855
  if (typeof window === "undefined") return;
3785
3856
  if (context && Object.keys(context).length > 0) {
@@ -4142,7 +4213,7 @@ function CrowCopilot({
4142
4213
  activeToolCalls: chat.activeToolCalls,
4143
4214
  isLoadingHistory: conversations.isLoadingHistory,
4144
4215
  isGenerating: chat.isLoading,
4145
- toolRenderers
4216
+ toolRenderers: effectiveToolRenderers
4146
4217
  }
4147
4218
  ),
4148
4219
  pendingConfirmation && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "crow-px-4 crow-py-2", children: /* @__PURE__ */ jsxRuntime.jsx(