@usecrow/client 0.1.40 → 0.1.42
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 -1
- package/dist/index.d.ts +8 -0
- package/dist/index.js +16 -27
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const _=require("./workflowExecutor-D1pVvfZw.cjs");class k{constructor(){this.state={token:null,metadata:{},isVerified:!1},this.listeners=new Set}identify(e){const{token:t,...s}=e;this.state={token:t,metadata:s,isVerified:!1},this.notify(),console.log("[Crow] User identified")}setVerified(e){this.state={...this.state,isVerified:e},this.notify()}reset(){this.state={token:null,metadata:{},isVerified:!1},this.notify(),console.log("[Crow] User reset")}getToken(){return this.state.token}getState(){return{...this.state}}isIdentified(){return this.state.token!==null}isVerified(){return this.state.isVerified}subscribe(e){return this.listeners.add(e),()=>this.listeners.delete(e)}notify(){const e=this.getState();for(const t of this.listeners)t(e)}}class v{constructor(){this.handlers={}}register(e){for(const[t,s]of Object.entries(e))typeof s=="function"?(this.handlers[t]=s,console.log(`[Crow] Registered client tool: ${t}`)):console.warn(`[Crow] Skipping ${t}: handler is not a function`)}unregister(e){delete this.handlers[e],console.log(`[Crow] Unregistered client tool: ${e}`)}has(e){return e in this.handlers}getRegisteredTools(){return Object.keys(this.handlers)}async execute(e,t){const s=this.handlers[e];if(!s)return console.warn(`[Crow] No handler registered for tool: ${e}`),{status:"error",error:`No handler registered for tool: ${e}`};try{console.log(`[Crow] Executing client tool: ${e}`,t);const r=await s(t);return console.log(`[Crow] Tool ${e} completed:`,r),r}catch(r){const n=r instanceof Error?r.message:String(r);return console.error(`[Crow] Tool ${e} failed:`,r),{status:"error",error:n}}}}const E="crow_conv_";class C{constructor(e,t){this.currentId=null,this.productId=e,this.apiUrl=t,this.currentId=this.loadFromStorage()}getStorageKey(){return`${E}${this.productId}`}loadFromStorage(){try{return localStorage.getItem(this.getStorageKey())}catch{return null}}saveToStorage(e){try{localStorage.setItem(this.getStorageKey(),e)}catch{}}clearStorage(){try{localStorage.removeItem(this.getStorageKey())}catch{}}getCurrentId(){return this.currentId}setCurrentId(e){this.currentId=e,e?this.saveToStorage(e):this.clearStorage()}hasRestoredConversation(){return this.currentId!==null}clear(){this.currentId=null,this.clearStorage()}async getConversations(e){try{const t=await fetch(`${this.apiUrl}/api/chat/conversations?product_id=${this.productId}&identity_token=${encodeURIComponent(e)}`);if(!t.ok)throw new Error(`HTTP error: ${t.status}`);return(await t.json()).conversations||[]}catch(t){return console.error("[Crow] Failed to load conversations:",t),[]}}async loadHistory(e,t){try{const s=await fetch(`${this.apiUrl}/api/chat/conversations/${e}/history?product_id=${this.productId}&identity_token=${encodeURIComponent(t)}`);if(!s.ok)throw new Error(`HTTP error: ${s.status}`);const r=await s.json();return this.parseHistoryMessages(r.messages||[])}catch(s){return console.error("[Crow] Failed to load conversation history:",s),[]}}async loadAnonymousHistory(e){try{const t=await fetch(`${this.apiUrl}/api/chat/conversations/${e}/history/anonymous?product_id=${this.productId}`);if(!t.ok)throw new Error(`HTTP error: ${t.status}`);const s=await t.json();return this.parseHistoryMessages(s.messages||[])}catch(t){return console.error("[Crow] Failed to load anonymous conversation history:",t),[]}}parseHistoryMessages(e){return e.filter(t=>t.role!=="tool"&&!t.content.startsWith("[Client Tool Result:")).map((t,s)=>({id:`history-${s}`,content:this.parseContent(t.content),role:t.role==="assistant"?"assistant":"user",timestamp:new Date}))}parseContent(e){try{const t=JSON.parse(e);if(Array.isArray(t)){const s=t.find(r=>r.type==="text");return(s==null?void 0:s.text)||e}}catch{}if(e.includes("'type': 'text'")){const t=e.match(/\{'text':\s*'((?:[^'\\]|\\.)*)'\s*,\s*'type':\s*'text'/);if(t)return t[1].replace(/\\n/g,`
|
|
2
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(){
|
|
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;
|
package/dist/index.d.ts
CHANGED
|
@@ -814,6 +814,9 @@ export declare type StreamEvent = {
|
|
|
814
814
|
message: string;
|
|
815
815
|
} | {
|
|
816
816
|
type: 'done';
|
|
817
|
+
} | {
|
|
818
|
+
type: 'suggested_actions';
|
|
819
|
+
actions: SuggestedAction[];
|
|
817
820
|
} | {
|
|
818
821
|
type: 'browser_use_confirmation';
|
|
819
822
|
instruction: string;
|
|
@@ -834,6 +837,11 @@ export declare type StreamEvent = {
|
|
|
834
837
|
*/
|
|
835
838
|
export declare function streamResponse(response: Response, signal?: AbortSignal): AsyncGenerator<StreamEvent>;
|
|
836
839
|
|
|
840
|
+
export declare interface SuggestedAction {
|
|
841
|
+
label: string;
|
|
842
|
+
message: string;
|
|
843
|
+
}
|
|
844
|
+
|
|
837
845
|
declare interface TextDomNode {
|
|
838
846
|
type: 'TEXT_NODE';
|
|
839
847
|
text: string;
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as
|
|
1
|
+
import { C as A, W as R } from "./workflowExecutor-ijFlX3nx.js";
|
|
2
2
|
class _ {
|
|
3
3
|
constructor() {
|
|
4
4
|
this.state = {
|
|
@@ -393,16 +393,6 @@ async function* M(o, e) {
|
|
|
393
393
|
}
|
|
394
394
|
}
|
|
395
395
|
async function S() {
|
|
396
|
-
try {
|
|
397
|
-
return window.location.reload(), { status: "success", data: { refreshed: !0 } };
|
|
398
|
-
} catch (o) {
|
|
399
|
-
return {
|
|
400
|
-
status: "error",
|
|
401
|
-
error: o instanceof Error ? o.message : "Failed to refresh page"
|
|
402
|
-
};
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
async function T() {
|
|
406
396
|
var o;
|
|
407
397
|
try {
|
|
408
398
|
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();
|
|
@@ -423,19 +413,18 @@ async function T() {
|
|
|
423
413
|
}
|
|
424
414
|
}
|
|
425
415
|
const w = {
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
class U {
|
|
416
|
+
whatsOnScreen: S
|
|
417
|
+
}, T = Object.keys(w), $ = "https://api.usecrow.org", E = "claude-sonnet-4-20250514";
|
|
418
|
+
class x {
|
|
430
419
|
constructor(e) {
|
|
431
420
|
this.context = {}, this.abortController = null, this.callbacks = {}, this._messages = [], this.messageListeners = /* @__PURE__ */ new Set(), this._isLoading = !1, this.loadingListeners = /* @__PURE__ */ new Set(), this.config = {
|
|
432
421
|
productId: e.productId,
|
|
433
|
-
apiUrl: e.apiUrl ||
|
|
434
|
-
model: e.model ||
|
|
422
|
+
apiUrl: e.apiUrl || $,
|
|
423
|
+
model: e.model || E
|
|
435
424
|
}, this.identity = new _(), this.tools = new k(), this.conversations = new C(
|
|
436
425
|
this.config.productId,
|
|
437
426
|
this.config.apiUrl
|
|
438
|
-
), this.tools.register(w), console.log("[Crow] Default tools registered:",
|
|
427
|
+
), this.tools.register(w), console.log("[Crow] Default tools registered:", T.join(", ")), this.identity.subscribe((t) => {
|
|
439
428
|
var s, r;
|
|
440
429
|
(r = (s = this.callbacks).onVerificationStatus) == null || r.call(s, t.isVerified);
|
|
441
430
|
});
|
|
@@ -754,7 +743,7 @@ class U {
|
|
|
754
743
|
this.stop(), this.messageListeners.clear(), this.loadingListeners.clear();
|
|
755
744
|
}
|
|
756
745
|
}
|
|
757
|
-
function
|
|
746
|
+
function L(o, e, t) {
|
|
758
747
|
const s = o.find(
|
|
759
748
|
(n) => n.name.toLowerCase() === e.toLowerCase()
|
|
760
749
|
);
|
|
@@ -765,13 +754,13 @@ function x(o, e, t) {
|
|
|
765
754
|
r = r.replace(`:${n}`, String(i));
|
|
766
755
|
return r;
|
|
767
756
|
}
|
|
768
|
-
function
|
|
757
|
+
function U(o, e) {
|
|
769
758
|
return async (t) => {
|
|
770
759
|
try {
|
|
771
760
|
const s = t.page, r = t.params, n = t.url;
|
|
772
761
|
let i = null;
|
|
773
762
|
if (s) {
|
|
774
|
-
if (i =
|
|
763
|
+
if (i = L(o, s, r), !i)
|
|
775
764
|
return {
|
|
776
765
|
status: "error",
|
|
777
766
|
error: `Unknown page: "${s}". Available pages: ${o.map((h) => h.name).join(", ")}`
|
|
@@ -812,16 +801,16 @@ function N(o, e) {
|
|
|
812
801
|
}
|
|
813
802
|
export {
|
|
814
803
|
C as ConversationManager,
|
|
815
|
-
|
|
816
|
-
|
|
804
|
+
A as CrowBrowserUse,
|
|
805
|
+
x as CrowClient,
|
|
817
806
|
w as DEFAULT_TOOLS,
|
|
818
|
-
|
|
807
|
+
T as DEFAULT_TOOL_NAMES,
|
|
819
808
|
_ as IdentityManager,
|
|
820
809
|
k as ToolManager,
|
|
821
|
-
|
|
822
|
-
|
|
810
|
+
R as WorkflowExecutor,
|
|
811
|
+
U as createNavigateToPageTool,
|
|
823
812
|
I as parseSSEChunk,
|
|
824
813
|
b as parseSSEData,
|
|
825
|
-
|
|
814
|
+
L as resolveRoute,
|
|
826
815
|
M as streamResponse
|
|
827
816
|
};
|