@usecrow/client 0.1.45 → 0.1.47

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
@@ -1 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index.native.cjs"),l=require("./workflowExecutor-D1pVvfZw.cjs");function c(s,i,t){const r=s.find(o=>o.name.toLowerCase()===i.toLowerCase());if(!r)return null;let n=r.path;if(t)for(const[o,a]of Object.entries(t))n=n.replace(`:${o}`,String(a));return n}function d(s,i){return async t=>{try{const r=t.page,n=t.params,o=t.url;let a=null;if(r){if(a=c(s,r,n),!a)return{status:"error",error:`Unknown page: "${r}". Available pages: ${s.map(g=>g.name).join(", ")}`}}else if(o)a=o;else return{status:"error",error:'Either "page" or "url" parameter is required'};const u=a.match(/:([a-zA-Z_][a-zA-Z0-9_]*)/g);return u?{status:"error",error:`Missing parameters: ${u.join(", ")}. Please provide values for these parameters.`}:i?(i(a),{status:"success",data:{navigated_to:a,page:r||void 0,method:"spa_router"}}):typeof window<"u"?(window.location.href=a,{status:"success",data:{navigated_to:a,page:r||void 0,method:"full_navigation"}}):{status:"error",error:"No navigateFn provided and window.location is unavailable (non-browser runtime). Pass a navigateFn to createNavigateToPageTool."}}catch(r){return{status:"error",error:String(r)}}}}exports.ConversationManager=e.ConversationManager;exports.CrowClient=e.CrowClient;exports.DEFAULT_TOOLS=e.DEFAULT_TOOLS;exports.DEFAULT_TOOL_NAMES=e.DEFAULT_TOOL_NAMES;exports.IdentityManager=e.IdentityManager;exports.ToolManager=e.ToolManager;exports.createLocalStorageAdapter=e.createLocalStorageAdapter;exports.createMemoryStorageAdapter=e.createMemoryStorageAdapter;exports.parseSSEChunk=e.parseSSEChunk;exports.parseSSEData=e.parseSSEData;exports.streamResponse=e.streamResponse;exports.CrowBrowserUse=l.CrowBrowserUse;exports.WorkflowExecutor=l.WorkflowExecutor;exports.createNavigateToPageTool=d;exports.resolveRoute=c;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("./index.native.cjs"),A=require("./workflowExecutor-D1pVvfZw.cjs");function C(l){const{apiUrl:c,productId:o,query:r,conversationId:n=null,context:s={},onChunk:e,onNavigate:u,onCheckingDocs:i,onToolResult:g,onDone:d,onError:p}=l,w=new AbortController;return(async()=>{var _;try{const f=await fetch(`${c}/api/chat/message`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({product_id:o,message:r,conversation_id:n??null,context:s??{}}),signal:w.signal});if(!f.ok||!f.body){p==null||p();return}const b=f.body.getReader(),E=new TextDecoder;let v="",m=n??null;for(;;){const{done:L,value:M}=await b.read();if(L)break;v+=E.decode(M,{stream:!0});const y=v.split(`
2
+ `);v=y.pop()??"";for(const S of y){if(!S.startsWith("data: "))continue;const T=S.slice(6);if(T==="[DONE]"){d==null||d(m);return}try{const t=JSON.parse(T);if(t.type==="conversation_id"&&t.conversation_id)m=t.conversation_id;else if(t.type==="content"&&t.content)e==null||e(t.content);else if(t.type==="client_tool_call"&&t.tool_name==="navigateToPage"){const h=((_=t.arguments)==null?void 0:_.url)??null;h&&(u==null||u(h))}else t.type==="tool_call_start"?i==null||i(!0):t.type==="tool_call_complete"?i==null||i(!1):t.type==="tool_result"&&(g==null||g(t.tool_name,t))}catch{}}}d==null||d(m)}catch(f){f.name!=="AbortError"&&(p==null||p())}})(),w}function O(l,c,o){const r=l.find(s=>s.name.toLowerCase()===c.toLowerCase());if(!r)return null;let n=r.path;if(o)for(const[s,e]of Object.entries(o))n=n.replace(`:${s}`,String(e));return n}function P(l,c){return async o=>{try{const r=o.page,n=o.params,s=o.url;let e=null;if(r){if(e=O(l,r,n),!e)return{status:"error",error:`Unknown page: "${r}". Available pages: ${l.map(i=>i.name).join(", ")}`}}else if(s)e=s;else return{status:"error",error:'Either "page" or "url" parameter is required'};const u=e.match(/:([a-zA-Z_][a-zA-Z0-9_]*)/g);return u?{status:"error",error:`Missing parameters: ${u.join(", ")}. Please provide values for these parameters.`}:c?(c(e),{status:"success",data:{navigated_to:e,page:r||void 0,method:"spa_router"}}):typeof window<"u"?(window.location.href=e,{status:"success",data:{navigated_to:e,page:r||void 0,method:"full_navigation"}}):{status:"error",error:"No navigateFn provided and window.location is unavailable (non-browser runtime). Pass a navigateFn to createNavigateToPageTool."}}catch(r){return{status:"error",error:String(r)}}}}exports.ConversationManager=a.ConversationManager;exports.CrowClient=a.CrowClient;exports.DEFAULT_TOOLS=a.DEFAULT_TOOLS;exports.DEFAULT_TOOL_NAMES=a.DEFAULT_TOOL_NAMES;exports.IdentityManager=a.IdentityManager;exports.ToolManager=a.ToolManager;exports.createLocalStorageAdapter=a.createLocalStorageAdapter;exports.createMemoryStorageAdapter=a.createMemoryStorageAdapter;exports.parseSSEChunk=a.parseSSEChunk;exports.parseSSEData=a.parseSSEData;exports.streamResponse=a.streamResponse;exports.CrowBrowserUse=A.CrowBrowserUse;exports.WorkflowExecutor=A.WorkflowExecutor;exports.createNavigateToPageTool=P;exports.crowAsk=C;exports.resolveRoute=O;
package/dist/index.d.ts CHANGED
@@ -9,6 +9,42 @@ export declare interface ActiveWorkflow {
9
9
  isComplete?: boolean;
10
10
  }
11
11
 
12
+ /**
13
+ * crowAsk - Headless AI query function
14
+ *
15
+ * Streams a question to the Crow API and delivers results via callbacks.
16
+ * Works without any React or UI dependency — usable anywhere window.crow('ask') is called.
17
+ * Returns an AbortController so the caller can cancel mid-stream.
18
+ */
19
+ export declare interface AskOptions {
20
+ /** Crow API base URL (e.g. "https://api.usecrow.ai") */
21
+ apiUrl: string;
22
+ /** Product ID from your Crow dashboard */
23
+ productId: string;
24
+ /** The user's question */
25
+ query: string;
26
+ /** Conversation ID for follow-up messages; null for a new conversation */
27
+ conversationId?: string | null;
28
+ /** Page context sent with the request (e.g. { page: "/settings/teams" }) */
29
+ context?: Record<string, unknown>;
30
+ /** Called incrementally as the AI streams text tokens */
31
+ onChunk?: (text: string) => void;
32
+ /** Called when the AI emits a navigateToPage tool call with the target URL */
33
+ onNavigate?: (href: string) => void;
34
+ /** Called with true when an MCP/doc-search tool starts, false when it completes */
35
+ onCheckingDocs?: (checking: boolean) => void;
36
+ /**
37
+ * Called when a server-side tool result arrives.
38
+ * The raw SSE event object is passed so callers can extract custom data
39
+ * (e.g. extracting source URLs from MCP search blobs).
40
+ */
41
+ onToolResult?: (toolName: string, result: unknown) => void;
42
+ /** Called when the stream ends; receives the conversation ID for follow-up messages */
43
+ onDone?: (conversationId: string | null) => void;
44
+ /** Called on non-abort errors (network failures, non-2xx responses) */
45
+ onError?: () => void;
46
+ }
47
+
12
48
  /**
13
49
  * Structured browser state for LLM consumption
14
50
  */
@@ -136,6 +172,8 @@ export declare function createMemoryStorageAdapter(): StorageAdapter;
136
172
  */
137
173
  export declare function createNavigateToPageTool(routes: NavigationRoute[], navigateFn?: (path: string) => void): (args: Record<string, unknown>) => Promise<ToolResult>;
138
174
 
175
+ export declare function crowAsk(opts: AskOptions): AbortController;
176
+
139
177
  export declare class CrowBrowserUse {
140
178
  private config;
141
179
  private pageController;
package/dist/index.js CHANGED
@@ -1,78 +1,147 @@
1
- import { ConversationManager as g, CrowClient as f, DEFAULT_TOOLS as m, DEFAULT_TOOL_NAMES as v, IdentityManager as w, ToolManager as h, createLocalStorageAdapter as S, createMemoryStorageAdapter as T, parseSSEChunk as _, parseSSEData as A, streamResponse as C } from "./index.native.js";
2
- import { C as L, W as y } from "./workflowExecutor-ijFlX3nx.js";
3
- function l(n, s, a) {
4
- const e = n.find(
5
- (t) => t.name.toLowerCase() === s.toLowerCase()
1
+ import { ConversationManager as E, CrowClient as M, DEFAULT_TOOLS as U, DEFAULT_TOOL_NAMES as $, IdentityManager as j, ToolManager as I, createLocalStorageAdapter as k, createMemoryStorageAdapter as F, parseSSEChunk as W, parseSSEData as q, streamResponse as z } from "./index.native.js";
2
+ import { C as R, W as Z } from "./workflowExecutor-ijFlX3nx.js";
3
+ function x(i) {
4
+ const {
5
+ apiUrl: l,
6
+ productId: a,
7
+ query: r,
8
+ conversationId: o = null,
9
+ context: n = {},
10
+ onChunk: e,
11
+ onNavigate: c,
12
+ onCheckingDocs: s,
13
+ onToolResult: f,
14
+ onDone: u,
15
+ onError: d
16
+ } = i, v = new AbortController();
17
+ return (async () => {
18
+ var _;
19
+ try {
20
+ const p = await fetch(`${l}/api/chat/message`, {
21
+ method: "POST",
22
+ headers: { "Content-Type": "application/json" },
23
+ body: JSON.stringify({
24
+ product_id: a,
25
+ message: r,
26
+ conversation_id: o ?? null,
27
+ context: n ?? {}
28
+ }),
29
+ signal: v.signal
30
+ });
31
+ if (!p.ok || !p.body) {
32
+ d == null || d();
33
+ return;
34
+ }
35
+ const T = p.body.getReader(), b = new TextDecoder();
36
+ let g = "", m = o ?? null;
37
+ for (; ; ) {
38
+ const { done: A, value: O } = await T.read();
39
+ if (A) break;
40
+ g += b.decode(O, { stream: !0 });
41
+ const y = g.split(`
42
+ `);
43
+ g = y.pop() ?? "";
44
+ for (const w of y) {
45
+ if (!w.startsWith("data: ")) continue;
46
+ const h = w.slice(6);
47
+ if (h === "[DONE]") {
48
+ u == null || u(m);
49
+ return;
50
+ }
51
+ try {
52
+ const t = JSON.parse(h);
53
+ if (t.type === "conversation_id" && t.conversation_id)
54
+ m = t.conversation_id;
55
+ else if (t.type === "content" && t.content)
56
+ e == null || e(t.content);
57
+ else if (t.type === "client_tool_call" && t.tool_name === "navigateToPage") {
58
+ const S = ((_ = t.arguments) == null ? void 0 : _.url) ?? null;
59
+ S && (c == null || c(S));
60
+ } else t.type === "tool_call_start" ? s == null || s(!0) : t.type === "tool_call_complete" ? s == null || s(!1) : t.type === "tool_result" && (f == null || f(t.tool_name, t));
61
+ } catch {
62
+ }
63
+ }
64
+ }
65
+ u == null || u(m);
66
+ } catch (p) {
67
+ p.name !== "AbortError" && (d == null || d());
68
+ }
69
+ })(), v;
70
+ }
71
+ function P(i, l, a) {
72
+ const r = i.find(
73
+ (n) => n.name.toLowerCase() === l.toLowerCase()
6
74
  );
7
- if (!e) return null;
8
- let o = e.path;
75
+ if (!r) return null;
76
+ let o = r.path;
9
77
  if (a)
10
- for (const [t, r] of Object.entries(a))
11
- o = o.replace(`:${t}`, String(r));
78
+ for (const [n, e] of Object.entries(a))
79
+ o = o.replace(`:${n}`, String(e));
12
80
  return o;
13
81
  }
14
- function c(n, s) {
82
+ function C(i, l) {
15
83
  return async (a) => {
16
84
  try {
17
- const e = a.page, o = a.params, t = a.url;
18
- let r = null;
19
- if (e) {
20
- if (r = l(n, e, o), !r)
85
+ const r = a.page, o = a.params, n = a.url;
86
+ let e = null;
87
+ if (r) {
88
+ if (e = P(i, r, o), !e)
21
89
  return {
22
90
  status: "error",
23
- error: `Unknown page: "${e}". Available pages: ${n.map((u) => u.name).join(", ")}`
91
+ error: `Unknown page: "${r}". Available pages: ${i.map((s) => s.name).join(", ")}`
24
92
  };
25
- } else if (t)
26
- r = t;
93
+ } else if (n)
94
+ e = n;
27
95
  else
28
96
  return {
29
97
  status: "error",
30
98
  error: 'Either "page" or "url" parameter is required'
31
99
  };
32
- const i = r.match(/:([a-zA-Z_][a-zA-Z0-9_]*)/g);
33
- return i ? {
100
+ const c = e.match(/:([a-zA-Z_][a-zA-Z0-9_]*)/g);
101
+ return c ? {
34
102
  status: "error",
35
- error: `Missing parameters: ${i.join(", ")}. Please provide values for these parameters.`
36
- } : s ? (s(r), {
103
+ error: `Missing parameters: ${c.join(", ")}. Please provide values for these parameters.`
104
+ } : l ? (l(e), {
37
105
  status: "success",
38
106
  data: {
39
- navigated_to: r,
40
- page: e || void 0,
107
+ navigated_to: e,
108
+ page: r || void 0,
41
109
  method: "spa_router"
42
110
  }
43
- }) : typeof window < "u" ? (window.location.href = r, {
111
+ }) : typeof window < "u" ? (window.location.href = e, {
44
112
  status: "success",
45
113
  data: {
46
- navigated_to: r,
47
- page: e || void 0,
114
+ navigated_to: e,
115
+ page: r || void 0,
48
116
  method: "full_navigation"
49
117
  }
50
118
  }) : {
51
119
  status: "error",
52
120
  error: "No navigateFn provided and window.location is unavailable (non-browser runtime). Pass a navigateFn to createNavigateToPageTool."
53
121
  };
54
- } catch (e) {
122
+ } catch (r) {
55
123
  return {
56
124
  status: "error",
57
- error: String(e)
125
+ error: String(r)
58
126
  };
59
127
  }
60
128
  };
61
129
  }
62
130
  export {
63
- g as ConversationManager,
64
- L as CrowBrowserUse,
65
- f as CrowClient,
66
- m as DEFAULT_TOOLS,
67
- v as DEFAULT_TOOL_NAMES,
68
- w as IdentityManager,
69
- h as ToolManager,
70
- y as WorkflowExecutor,
71
- S as createLocalStorageAdapter,
72
- T as createMemoryStorageAdapter,
73
- c as createNavigateToPageTool,
74
- _ as parseSSEChunk,
75
- A as parseSSEData,
76
- l as resolveRoute,
77
- C as streamResponse
131
+ E as ConversationManager,
132
+ R as CrowBrowserUse,
133
+ M as CrowClient,
134
+ U as DEFAULT_TOOLS,
135
+ $ as DEFAULT_TOOL_NAMES,
136
+ j as IdentityManager,
137
+ I as ToolManager,
138
+ Z as WorkflowExecutor,
139
+ k as createLocalStorageAdapter,
140
+ F as createMemoryStorageAdapter,
141
+ C as createNavigateToPageTool,
142
+ x as crowAsk,
143
+ W as parseSSEChunk,
144
+ q as parseSSEData,
145
+ P as resolveRoute,
146
+ z as streamResponse
78
147
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@usecrow/client",
3
- "version": "0.1.45",
3
+ "version": "0.1.47",
4
4
  "description": "Headless client for Crow AI agents - streaming, auth, tools",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",