@usecrow/client 0.1.41 → 0.1.43
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 +2 -0
- package/dist/index.js +18 -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,subdomain:e.subdomain},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,subdomain:this.config.subdomain,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
|
@@ -304,6 +304,8 @@ export declare interface CrowClientConfig {
|
|
|
304
304
|
apiUrl?: string;
|
|
305
305
|
/** Default model to use */
|
|
306
306
|
model?: string;
|
|
307
|
+
/** Subdomain for multi-endpoint products (routes to specific backend config) */
|
|
308
|
+
subdomain?: string;
|
|
307
309
|
}
|
|
308
310
|
|
|
309
311
|
export declare interface CrowEventCallbacks {
|
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,19 @@ 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,
|
|
424
|
+
subdomain: e.subdomain
|
|
435
425
|
}, this.identity = new _(), this.tools = new k(), this.conversations = new C(
|
|
436
426
|
this.config.productId,
|
|
437
427
|
this.config.apiUrl
|
|
438
|
-
), this.tools.register(w), console.log("[Crow] Default tools registered:",
|
|
428
|
+
), this.tools.register(w), console.log("[Crow] Default tools registered:", T.join(", ")), this.identity.subscribe((t) => {
|
|
439
429
|
var s, r;
|
|
440
430
|
(r = (s = this.callbacks).onVerificationStatus) == null || r.call(s, t.isVerified);
|
|
441
431
|
});
|
|
@@ -670,6 +660,7 @@ class U {
|
|
|
670
660
|
conversation_id: this.conversations.getCurrentId(),
|
|
671
661
|
identity_token: this.identity.getToken(),
|
|
672
662
|
model: this.config.model,
|
|
663
|
+
subdomain: this.config.subdomain,
|
|
673
664
|
context: Object.keys(this.context).length > 0 ? this.context : void 0
|
|
674
665
|
}),
|
|
675
666
|
signal: this.abortController.signal
|
|
@@ -754,7 +745,7 @@ class U {
|
|
|
754
745
|
this.stop(), this.messageListeners.clear(), this.loadingListeners.clear();
|
|
755
746
|
}
|
|
756
747
|
}
|
|
757
|
-
function
|
|
748
|
+
function L(o, e, t) {
|
|
758
749
|
const s = o.find(
|
|
759
750
|
(n) => n.name.toLowerCase() === e.toLowerCase()
|
|
760
751
|
);
|
|
@@ -765,13 +756,13 @@ function x(o, e, t) {
|
|
|
765
756
|
r = r.replace(`:${n}`, String(i));
|
|
766
757
|
return r;
|
|
767
758
|
}
|
|
768
|
-
function
|
|
759
|
+
function U(o, e) {
|
|
769
760
|
return async (t) => {
|
|
770
761
|
try {
|
|
771
762
|
const s = t.page, r = t.params, n = t.url;
|
|
772
763
|
let i = null;
|
|
773
764
|
if (s) {
|
|
774
|
-
if (i =
|
|
765
|
+
if (i = L(o, s, r), !i)
|
|
775
766
|
return {
|
|
776
767
|
status: "error",
|
|
777
768
|
error: `Unknown page: "${s}". Available pages: ${o.map((h) => h.name).join(", ")}`
|
|
@@ -812,16 +803,16 @@ function N(o, e) {
|
|
|
812
803
|
}
|
|
813
804
|
export {
|
|
814
805
|
C as ConversationManager,
|
|
815
|
-
|
|
816
|
-
|
|
806
|
+
A as CrowBrowserUse,
|
|
807
|
+
x as CrowClient,
|
|
817
808
|
w as DEFAULT_TOOLS,
|
|
818
|
-
|
|
809
|
+
T as DEFAULT_TOOL_NAMES,
|
|
819
810
|
_ as IdentityManager,
|
|
820
811
|
k as ToolManager,
|
|
821
|
-
|
|
822
|
-
|
|
812
|
+
R as WorkflowExecutor,
|
|
813
|
+
U as createNavigateToPageTool,
|
|
823
814
|
I as parseSSEChunk,
|
|
824
815
|
b as parseSSEData,
|
|
825
|
-
|
|
816
|
+
L as resolveRoute,
|
|
826
817
|
M as streamResponse
|
|
827
818
|
};
|