@usecrow/client 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 +1 -3
- package/dist/index.d.ts +59 -9
- package/dist/index.js +50 -788
- package/dist/index.native.cjs +3 -0
- package/dist/index.native.d.ts +517 -0
- package/dist/index.native.js +788 -0
- package/package.json +3 -1
package/dist/index.cjs
CHANGED
|
@@ -1,3 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
2
|
-
`).replace(/\\'/g,"'")}return e}}function b(o){if(o==="[DONE]")return{type:"done"};try{const e=JSON.parse(o);switch(e.type){case"verification_status":return{type:"verification_status",isVerified:e.is_verified===!0};case"conversation_id":return{type:"conversation_id",conversationId:e.conversation_id};case"thinking":return e.status==="complete"?{type:"thinking_complete"}:null;case"thinking_token":return{type:"thinking",content:e.content||""};case"content":return{type:"content",text:e.content||"",accumulated:""};case"citations":return{type:"citations",citations:e.citations};case"error":return{type:"error",message:e.message||"Unknown error"};case"tool_call_start":return{type:"tool_call_start",toolName:e.tool_name,displayName:e.display_name||void 0,arguments:e.arguments||{}};case"tool_call_complete":return{type:"tool_call_complete",toolName:e.tool_name,displayName:e.display_name||void 0,success:e.success};case"client_tool_call":return{type:"client_tool_call",toolName:e.tool_name,displayName:e.display_name||void 0,arguments:e.arguments||{}};case"tool_consent_required":return{type:"tool_consent_required",toolName:e.tool_name,displayName:e.display_name||void 0,arguments:e.arguments||{}};case"workflow_started":return{type:"workflow_started",name:e.name,todos:e.todos};case"todo_updated":return{type:"workflow_todo_updated",todoId:e.id,status:e.status};case"workflow_ended":return{type:"workflow_ended"};case"workflow_complete_prompt":return{type:"workflow_complete_prompt"};default:return null}}catch{return console.error("[Crow] Failed to parse SSE data:",o),null}}function*M(o){const e=o.split(`
|
|
3
|
-
`);for(const t of e)t.startsWith("data: ")&&(yield t.slice(6).trim())}async function*S(o,e){var n;const t=(n=o.body)==null?void 0:n.getReader();if(!t)throw new Error("Response body is not readable");const s=new TextDecoder;let r="";try{for(;;){if(e!=null&&e.aborted){t.cancel();return}const{done:i,value:d}=await t.read();if(i)break;const u=s.decode(d);for(const h of M(u)){const l=b(h);if(l&&(l.type==="content"?(r+=l.text,yield{...l,accumulated:r}):yield l,l.type==="done"))return}}}finally{t.releaseLock()}}async function L(){var o;try{const e=document.title,t=window.location.href,s=window.location.pathname,r=(((o=document.body)==null?void 0:o.innerText)||"").slice(0,2e3).trim();return{status:"success",data:{title:e,url:t,pathname:s,visibleText:r}}}catch(e){return{status:"error",error:e instanceof Error?e.message:"Failed to read screen"}}}const g={whatsOnScreen:L},T=Object.keys(g),$="https://api.usecrow.org",U="claude-sonnet-4-20250514";class x{constructor(e){this.context={},this.abortController=null,this.callbacks={},this._messages=[],this.messageListeners=new Set,this._isLoading=!1,this.loadingListeners=new Set,this.config={productId:e.productId,apiUrl:e.apiUrl||$,model:e.model||U},this.identity=new k,this.tools=new v,this.conversations=new C(this.config.productId,this.config.apiUrl),this.tools.register(g),console.log("[Crow] Default tools registered:",T.join(", ")),this.identity.subscribe(t=>{var s,r;(r=(s=this.callbacks).onVerificationStatus)==null||r.call(s,t.isVerified)})}get productId(){return this.config.productId}get apiUrl(){return this.config.apiUrl}get model(){return this.config.model}set model(e){this.config.model=e}on(e){this.callbacks={...this.callbacks,...e}}identify(e){this.identity.identify(e)}resetUser(){this.identity.reset(),this.clearMessages()}isIdentified(){return this.identity.isIdentified()}isVerified(){return this.identity.isVerified()}registerTools(e){this.tools.register(e)}unregisterTool(e){this.tools.unregister(e)}getRegisteredTools(){return this.tools.getRegisteredTools()}setContext(e){this.context={...this.context,...e}}clearContext(){this.context={}}get messages(){return[...this._messages]}get isLoading(){return this._isLoading}onMessages(e){return this.messageListeners.add(e),()=>this.messageListeners.delete(e)}onLoading(e){return this.loadingListeners.add(e),()=>this.loadingListeners.delete(e)}clearMessages(){this._messages=[],this.conversations.clear(),this.notifyMessages()}loadMessages(e){this._messages=e,this.notifyMessages()}notifyMessages(){const e=this.messages;for(const t of this.messageListeners)t(e)}setLoading(e){this._isLoading=e;for(const t of this.loadingListeners)t(e)}addMessage(e){var t,s;this._messages=[...this._messages,e],this.notifyMessages(),(s=(t=this.callbacks).onMessage)==null||s.call(t,e)}updateMessage(e,t){var s,r;this._messages=this._messages.map(n=>n.id===e?{...n,...t}:n),this.notifyMessages(),(r=(s=this.callbacks).onMessageUpdate)==null||r.call(s,e,t)}generateMessageId(e){return`${e}-${Date.now()}-${Math.random().toString(36).slice(2,9)}`}get conversationId(){return this.conversations.getCurrentId()}set conversationId(e){this.conversations.setCurrentId(e)}async getConversations(){const e=this.identity.getToken();return e?this.conversations.getConversations(e):(console.warn("[Crow] Cannot get conversations: user not identified"),[])}async loadHistory(e){const t=this.identity.getToken();return t?this.conversations.loadHistory(e,t):this.conversations.loadAnonymousHistory(e)}async switchConversation(e){const t=await this.loadHistory(e);this.conversations.setCurrentId(e),this.loadMessages(t)}async*sendMessage(e){var i,d,u,h,l,f,p,y,m,w;if(!e.trim())return;const t=this.generateMessageId("user");this.addMessage({id:t,content:e,role:"user",timestamp:new Date});const s=this.generateMessageId("assistant");this.addMessage({id:s,content:"",role:"assistant",timestamp:new Date}),this.setLoading(!0),this.abortController=new AbortController;let r="",n="";try{const c=await fetch(`${this.config.apiUrl}/api/chat/message`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({product_id:this.config.productId,message:e,conversation_id:this.conversations.getCurrentId(),identity_token:this.identity.getToken(),model:this.config.model,context:Object.keys(this.context).length>0?this.context:void 0}),signal:this.abortController.signal});if(!c.ok)throw new Error(`HTTP error: ${c.status}`);for await(const a of S(c,this.abortController.signal)){switch(a.type){case"content":r=a.accumulated,this.updateMessage(s,{content:r});break;case"thinking":n+=a.content,this.updateMessage(s,{thinking:n});break;case"thinking_complete":this.updateMessage(s,{thinkingComplete:!0});break;case"citations":this.updateMessage(s,{citations:a.citations});break;case"verification_status":this.identity.setVerified(a.isVerified);break;case"conversation_id":this.conversations.setCurrentId(a.conversationId);break;case"client_tool_call":await this.tools.execute(a.toolName,a.arguments),(d=(i=this.callbacks).onToolCall)==null||d.call(i,a);break;case"tool_call_start":case"tool_call_complete":(h=(u=this.callbacks).onToolCall)==null||h.call(u,a);break;case"workflow_started":case"workflow_todo_updated":case"workflow_ended":case"workflow_complete_prompt":(f=(l=this.callbacks).onWorkflow)==null||f.call(l,a);break;case"error":this.updateMessage(s,{content:a.message}),(y=(p=this.callbacks).onError)==null||y.call(p,new Error(a.message));break}yield a}}catch(c){if(c instanceof Error&&c.name==="AbortError"){r?this.updateMessage(s,{content:r}):(this._messages=this._messages.filter(a=>a.id!==s),this.notifyMessages());return}console.error("[Crow] Error:",c),this.updateMessage(s,{content:"Sorry, I encountered an error. Please try again."}),(w=(m=this.callbacks).onError)==null||w.call(m,c instanceof Error?c:new Error(String(c)))}finally{this.setLoading(!1),this.abortController=null}}async send(e){let t=null;for await(const r of this.sendMessage(e))if(r.type==="done")break;const s=this.messages;return s.length>0&&(t=s[s.length-1],t.role==="assistant")?t:null}stop(){this.abortController&&(this.abortController.abort(),this.setLoading(!1))}destroy(){this.stop(),this.messageListeners.clear(),this.loadingListeners.clear()}}function I(o,e,t){const s=o.find(n=>n.name.toLowerCase()===e.toLowerCase());if(!s)return null;let r=s.path;if(t)for(const[n,i]of Object.entries(t))r=r.replace(`:${n}`,String(i));return r}function O(o,e){return async t=>{try{const s=t.page,r=t.params,n=t.url;let i=null;if(s){if(i=I(o,s,r),!i)return{status:"error",error:`Unknown page: "${s}". Available pages: ${o.map(u=>u.name).join(", ")}`}}else if(n)i=n;else return{status:"error",error:'Either "page" or "url" parameter is required'};const d=i.match(/:([a-zA-Z_][a-zA-Z0-9_]*)/g);return d?{status:"error",error:`Missing parameters: ${d.join(", ")}. Please provide values for these parameters.`}:e?(e(i),{status:"success",data:{navigated_to:i,page:s||void 0,method:"spa_router"}}):(window.location.href=i,{status:"success",data:{navigated_to:i,page:s||void 0,method:"full_navigation"}})}catch(s){return{status:"error",error:String(s)}}}}exports.CrowBrowserUse=_.CrowBrowserUse;exports.WorkflowExecutor=_.WorkflowExecutor;exports.ConversationManager=C;exports.CrowClient=x;exports.DEFAULT_TOOLS=g;exports.DEFAULT_TOOL_NAMES=T;exports.IdentityManager=k;exports.ToolManager=v;exports.createNavigateToPageTool=O;exports.parseSSEChunk=M;exports.parseSSEData=b;exports.resolveRoute=I;exports.streamResponse=S;
|
|
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;
|
package/dist/index.d.ts
CHANGED
|
@@ -58,22 +58,23 @@ export declare interface Conversation {
|
|
|
58
58
|
export declare class ConversationManager {
|
|
59
59
|
private productId;
|
|
60
60
|
private apiUrl;
|
|
61
|
+
private storage;
|
|
61
62
|
private currentId;
|
|
62
|
-
constructor(productId: string, apiUrl: string);
|
|
63
|
+
constructor(productId: string, apiUrl: string, storage: StorageAdapter);
|
|
63
64
|
/**
|
|
64
|
-
* Get
|
|
65
|
+
* Get storage key for this product
|
|
65
66
|
*/
|
|
66
67
|
private getStorageKey;
|
|
67
68
|
/**
|
|
68
|
-
* Load conversation ID from
|
|
69
|
+
* Load conversation ID from storage
|
|
69
70
|
*/
|
|
70
71
|
private loadFromStorage;
|
|
71
72
|
/**
|
|
72
|
-
* Save conversation ID to
|
|
73
|
+
* Save conversation ID to storage
|
|
73
74
|
*/
|
|
74
75
|
private saveToStorage;
|
|
75
76
|
/**
|
|
76
|
-
* Clear conversation ID from
|
|
77
|
+
* Clear conversation ID from storage
|
|
77
78
|
*/
|
|
78
79
|
private clearStorage;
|
|
79
80
|
/**
|
|
@@ -114,6 +115,18 @@ export declare class ConversationManager {
|
|
|
114
115
|
private parseContent;
|
|
115
116
|
}
|
|
116
117
|
|
|
118
|
+
/**
|
|
119
|
+
* localStorage-backed adapter (default for browsers).
|
|
120
|
+
* Falls back to in-memory when localStorage is unavailable.
|
|
121
|
+
*/
|
|
122
|
+
export declare function createLocalStorageAdapter(): StorageAdapter;
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* In-memory adapter. Useful for React Native, SSR, or tests.
|
|
126
|
+
* Data does not persist across sessions.
|
|
127
|
+
*/
|
|
128
|
+
export declare function createMemoryStorageAdapter(): StorageAdapter;
|
|
129
|
+
|
|
117
130
|
/**
|
|
118
131
|
* Create a navigateToPage tool handler for the given routes.
|
|
119
132
|
*
|
|
@@ -165,6 +178,7 @@ export declare class CrowClient {
|
|
|
165
178
|
private identity;
|
|
166
179
|
private tools;
|
|
167
180
|
private conversations;
|
|
181
|
+
private readStream;
|
|
168
182
|
private context;
|
|
169
183
|
private abortController;
|
|
170
184
|
private callbacks;
|
|
@@ -294,9 +308,6 @@ export declare class CrowClient {
|
|
|
294
308
|
destroy(): void;
|
|
295
309
|
}
|
|
296
310
|
|
|
297
|
-
/**
|
|
298
|
-
* Core types for @usecrow/client
|
|
299
|
-
*/
|
|
300
311
|
export declare interface CrowClientConfig {
|
|
301
312
|
/** Your Crow product ID from the dashboard */
|
|
302
313
|
productId: string;
|
|
@@ -304,6 +315,24 @@ export declare interface CrowClientConfig {
|
|
|
304
315
|
apiUrl?: string;
|
|
305
316
|
/** Default model to use */
|
|
306
317
|
model?: string;
|
|
318
|
+
/**
|
|
319
|
+
* Storage adapter for persisting conversation state.
|
|
320
|
+
* Defaults to localStorage (browser) or in-memory if unavailable.
|
|
321
|
+
*/
|
|
322
|
+
storage?: StorageAdapter;
|
|
323
|
+
/**
|
|
324
|
+
* Custom stream reader for SSE responses.
|
|
325
|
+
* Override this for React Native or other non-browser runtimes
|
|
326
|
+
* where Response.body.getReader() is not available.
|
|
327
|
+
*/
|
|
328
|
+
streamReader?: StreamReader;
|
|
329
|
+
/**
|
|
330
|
+
* Whether to register browser-only default tools (whatsOnScreen).
|
|
331
|
+
* Defaults to true in browser environments, false otherwise.
|
|
332
|
+
*/
|
|
333
|
+
enableBrowserTools?: boolean;
|
|
334
|
+
/** Subdomain for multi-endpoint products (routes to specific backend config) */
|
|
335
|
+
subdomain?: string;
|
|
307
336
|
}
|
|
308
337
|
|
|
309
338
|
export declare interface CrowEventCallbacks {
|
|
@@ -334,9 +363,12 @@ export declare interface CrowEventCallbacks {
|
|
|
334
363
|
|
|
335
364
|
export declare const DEFAULT_TOOL_NAMES: DefaultToolName[];
|
|
336
365
|
|
|
366
|
+
/**
|
|
367
|
+
* Browser default tools. Empty object in non-browser runtimes.
|
|
368
|
+
*/
|
|
337
369
|
export declare const DEFAULT_TOOLS: ToolHandlers;
|
|
338
370
|
|
|
339
|
-
export declare type DefaultToolName =
|
|
371
|
+
export declare type DefaultToolName = 'whatsOnScreen';
|
|
340
372
|
|
|
341
373
|
declare namespace dom {
|
|
342
374
|
export {
|
|
@@ -759,6 +791,16 @@ export declare interface StepResult {
|
|
|
759
791
|
element_index?: number;
|
|
760
792
|
}
|
|
761
793
|
|
|
794
|
+
/**
|
|
795
|
+
* Synchronous key-value storage interface.
|
|
796
|
+
* Matches the subset of Web Storage API used by ConversationManager.
|
|
797
|
+
*/
|
|
798
|
+
export declare interface StorageAdapter {
|
|
799
|
+
getItem(key: string): string | null;
|
|
800
|
+
setItem(key: string, value: string): void;
|
|
801
|
+
removeItem(key: string): void;
|
|
802
|
+
}
|
|
803
|
+
|
|
762
804
|
export declare type StreamEvent = {
|
|
763
805
|
type: 'content';
|
|
764
806
|
text: string;
|
|
@@ -832,6 +874,14 @@ export declare type StreamEvent = {
|
|
|
832
874
|
action?: string;
|
|
833
875
|
};
|
|
834
876
|
|
|
877
|
+
/**
|
|
878
|
+
* A function that reads SSE events from an HTTP Response.
|
|
879
|
+
*
|
|
880
|
+
* Browser default: uses Response.body.getReader() + TextDecoder.
|
|
881
|
+
* React Native: uses XMLHttpRequest onprogress or text-based parsing.
|
|
882
|
+
*/
|
|
883
|
+
export declare type StreamReader = (response: Response, signal?: AbortSignal) => AsyncGenerator<StreamEvent>;
|
|
884
|
+
|
|
835
885
|
/**
|
|
836
886
|
* Create an async generator that streams events from a Response
|
|
837
887
|
*/
|