@usecrow/client 0.1.32 → 0.1.34

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.js CHANGED
@@ -1,6 +1,5 @@
1
- import { P as _ } from "./browserUse-DHVE_OuS.js";
2
- import { C as R } from "./browserUse-DHVE_OuS.js";
3
- class k {
1
+ import { C as D } from "./browserUse-Btg7osSj.js";
2
+ class _ {
4
3
  constructor() {
5
4
  this.state = {
6
5
  token: null,
@@ -11,10 +10,10 @@ class k {
11
10
  /**
12
11
  * Identify the current user with a JWT token
13
12
  */
14
- identify(t) {
15
- const { token: e, ...s } = t;
13
+ identify(e) {
14
+ const { token: t, ...s } = e;
16
15
  this.state = {
17
- token: e,
16
+ token: t,
18
17
  metadata: s,
19
18
  isVerified: !1
20
19
  // Will be set when server confirms
@@ -23,8 +22,8 @@ class k {
23
22
  /**
24
23
  * Update verification status (called when server confirms)
25
24
  */
26
- setVerified(t) {
27
- this.state = { ...this.state, isVerified: t }, this.notify();
25
+ setVerified(e) {
26
+ this.state = { ...this.state, isVerified: e }, this.notify();
28
27
  }
29
28
  /**
30
29
  * Reset user identity (call on logout)
@@ -63,37 +62,37 @@ class k {
63
62
  /**
64
63
  * Subscribe to identity changes
65
64
  */
66
- subscribe(t) {
67
- return this.listeners.add(t), () => this.listeners.delete(t);
65
+ subscribe(e) {
66
+ return this.listeners.add(e), () => this.listeners.delete(e);
68
67
  }
69
68
  notify() {
70
- const t = this.getState();
71
- for (const e of this.listeners)
72
- e(t);
69
+ const e = this.getState();
70
+ for (const t of this.listeners)
71
+ t(e);
73
72
  }
74
73
  }
75
- class C {
74
+ class k {
76
75
  constructor() {
77
76
  this.handlers = {};
78
77
  }
79
78
  /**
80
79
  * Register client-side tool handlers
81
80
  */
82
- register(t) {
83
- for (const [e, s] of Object.entries(t))
84
- typeof s == "function" ? (this.handlers[e] = s, console.log(`[Crow] Registered client tool: ${e}`)) : console.warn(`[Crow] Skipping ${e}: handler is not a function`);
81
+ register(e) {
82
+ for (const [t, s] of Object.entries(e))
83
+ typeof s == "function" ? (this.handlers[t] = s, console.log(`[Crow] Registered client tool: ${t}`)) : console.warn(`[Crow] Skipping ${t}: handler is not a function`);
85
84
  }
86
85
  /**
87
86
  * Unregister a tool handler
88
87
  */
89
- unregister(t) {
90
- delete this.handlers[t], console.log(`[Crow] Unregistered client tool: ${t}`);
88
+ unregister(e) {
89
+ delete this.handlers[e], console.log(`[Crow] Unregistered client tool: ${e}`);
91
90
  }
92
91
  /**
93
92
  * Check if a tool is registered
94
93
  */
95
- has(t) {
96
- return t in this.handlers;
94
+ has(e) {
95
+ return e in this.handlers;
97
96
  }
98
97
  /**
99
98
  * Get all registered tool names
@@ -104,36 +103,36 @@ class C {
104
103
  /**
105
104
  * Execute a client-side tool
106
105
  */
107
- async execute(t, e) {
108
- const s = this.handlers[t];
106
+ async execute(e, t) {
107
+ const s = this.handlers[e];
109
108
  if (!s)
110
- return console.warn(`[Crow] No handler registered for tool: ${t}`), {
109
+ return console.warn(`[Crow] No handler registered for tool: ${e}`), {
111
110
  status: "error",
112
- error: `No handler registered for tool: ${t}`
111
+ error: `No handler registered for tool: ${e}`
113
112
  };
114
113
  try {
115
- console.log(`[Crow] Executing client tool: ${t}`, e);
116
- const r = await s(e);
117
- return console.log(`[Crow] Tool ${t} completed:`, r), r;
114
+ console.log(`[Crow] Executing client tool: ${e}`, t);
115
+ const r = await s(t);
116
+ return console.log(`[Crow] Tool ${e} completed:`, r), r;
118
117
  } catch (r) {
119
- const i = r instanceof Error ? r.message : String(r);
120
- return console.error(`[Crow] Tool ${t} failed:`, r), {
118
+ const n = r instanceof Error ? r.message : String(r);
119
+ return console.error(`[Crow] Tool ${e} failed:`, r), {
121
120
  status: "error",
122
- error: i
121
+ error: n
123
122
  };
124
123
  }
125
124
  }
126
125
  }
127
- const v = "crow_conv_";
128
- class b {
129
- constructor(t, e) {
130
- this.currentId = null, this.productId = t, this.apiUrl = e, this.currentId = this.loadFromStorage();
126
+ const C = "crow_conv_";
127
+ class v {
128
+ constructor(e, t) {
129
+ this.currentId = null, this.productId = e, this.apiUrl = t, this.currentId = this.loadFromStorage();
131
130
  }
132
131
  /**
133
132
  * Get localStorage key for this product
134
133
  */
135
134
  getStorageKey() {
136
- return `${v}${this.productId}`;
135
+ return `${C}${this.productId}`;
137
136
  }
138
137
  /**
139
138
  * Load conversation ID from localStorage
@@ -148,9 +147,9 @@ class b {
148
147
  /**
149
148
  * Save conversation ID to localStorage
150
149
  */
151
- saveToStorage(t) {
150
+ saveToStorage(e) {
152
151
  try {
153
- localStorage.setItem(this.getStorageKey(), t);
152
+ localStorage.setItem(this.getStorageKey(), e);
154
153
  } catch {
155
154
  }
156
155
  }
@@ -172,8 +171,8 @@ class b {
172
171
  /**
173
172
  * Set current conversation ID
174
173
  */
175
- setCurrentId(t) {
176
- this.currentId = t, t ? this.saveToStorage(t) : this.clearStorage();
174
+ setCurrentId(e) {
175
+ this.currentId = e, e ? this.saveToStorage(e) : this.clearStorage();
177
176
  }
178
177
  /**
179
178
  * Check if there's a restored conversation
@@ -190,25 +189,25 @@ class b {
190
189
  /**
191
190
  * Fetch list of conversations for verified user
192
191
  */
193
- async getConversations(t) {
192
+ async getConversations(e) {
194
193
  try {
195
- const e = await fetch(
196
- `${this.apiUrl}/api/chat/conversations?product_id=${this.productId}&identity_token=${encodeURIComponent(t)}`
194
+ const t = await fetch(
195
+ `${this.apiUrl}/api/chat/conversations?product_id=${this.productId}&identity_token=${encodeURIComponent(e)}`
197
196
  );
198
- if (!e.ok)
199
- throw new Error(`HTTP error: ${e.status}`);
200
- return (await e.json()).conversations || [];
201
- } catch (e) {
202
- return console.error("[Crow] Failed to load conversations:", e), [];
197
+ if (!t.ok)
198
+ throw new Error(`HTTP error: ${t.status}`);
199
+ return (await t.json()).conversations || [];
200
+ } catch (t) {
201
+ return console.error("[Crow] Failed to load conversations:", t), [];
203
202
  }
204
203
  }
205
204
  /**
206
205
  * Load conversation history for verified user
207
206
  */
208
- async loadHistory(t, e) {
207
+ async loadHistory(e, t) {
209
208
  try {
210
209
  const s = await fetch(
211
- `${this.apiUrl}/api/chat/conversations/${t}/history?product_id=${this.productId}&identity_token=${encodeURIComponent(e)}`
210
+ `${this.apiUrl}/api/chat/conversations/${e}/history?product_id=${this.productId}&identity_token=${encodeURIComponent(t)}`
212
211
  );
213
212
  if (!s.ok)
214
213
  throw new Error(`HTTP error: ${s.status}`);
@@ -221,124 +220,124 @@ class b {
221
220
  /**
222
221
  * Load conversation history for anonymous user
223
222
  */
224
- async loadAnonymousHistory(t) {
223
+ async loadAnonymousHistory(e) {
225
224
  try {
226
- const e = await fetch(
227
- `${this.apiUrl}/api/chat/conversations/${t}/history/anonymous?product_id=${this.productId}`
225
+ const t = await fetch(
226
+ `${this.apiUrl}/api/chat/conversations/${e}/history/anonymous?product_id=${this.productId}`
228
227
  );
229
- if (!e.ok)
230
- throw new Error(`HTTP error: ${e.status}`);
231
- const s = await e.json();
228
+ if (!t.ok)
229
+ throw new Error(`HTTP error: ${t.status}`);
230
+ const s = await t.json();
232
231
  return this.parseHistoryMessages(s.messages || []);
233
- } catch (e) {
234
- return console.error("[Crow] Failed to load anonymous conversation history:", e), [];
232
+ } catch (t) {
233
+ return console.error("[Crow] Failed to load anonymous conversation history:", t), [];
235
234
  }
236
235
  }
237
236
  /**
238
237
  * Parse history messages from API format
239
238
  */
240
- parseHistoryMessages(t) {
241
- return t.filter((e) => e.role !== "tool" && !e.content.startsWith("[Client Tool Result:")).map((e, s) => ({
239
+ parseHistoryMessages(e) {
240
+ return e.filter((t) => t.role !== "tool" && !t.content.startsWith("[Client Tool Result:")).map((t, s) => ({
242
241
  id: `history-${s}`,
243
- content: this.parseContent(e.content),
244
- role: e.role === "assistant" ? "assistant" : "user",
242
+ content: this.parseContent(t.content),
243
+ role: t.role === "assistant" ? "assistant" : "user",
245
244
  timestamp: /* @__PURE__ */ new Date()
246
245
  }));
247
246
  }
248
247
  /**
249
248
  * Parse structured content (with thinking/text blocks) and extract just text
250
249
  */
251
- parseContent(t) {
250
+ parseContent(e) {
252
251
  try {
253
- const e = JSON.parse(t);
254
- if (Array.isArray(e)) {
255
- const s = e.find(
252
+ const t = JSON.parse(e);
253
+ if (Array.isArray(t)) {
254
+ const s = t.find(
256
255
  (r) => r.type === "text"
257
256
  );
258
- return (s == null ? void 0 : s.text) || t;
257
+ return (s == null ? void 0 : s.text) || e;
259
258
  }
260
259
  } catch {
261
260
  }
262
- if (t.includes("'type': 'text'")) {
263
- const e = t.match(
261
+ if (e.includes("'type': 'text'")) {
262
+ const t = e.match(
264
263
  /\{'text':\s*'((?:[^'\\]|\\.)*)'\s*,\s*'type':\s*'text'/
265
264
  );
266
- if (e)
267
- return e[1].replace(/\\n/g, `
265
+ if (t)
266
+ return t[1].replace(/\\n/g, `
268
267
  `).replace(/\\'/g, "'");
269
268
  }
270
- return t;
269
+ return e;
271
270
  }
272
271
  }
273
- function I(o) {
272
+ function b(o) {
274
273
  if (o === "[DONE]")
275
274
  return { type: "done" };
276
275
  try {
277
- const t = JSON.parse(o);
278
- switch (t.type) {
276
+ const e = JSON.parse(o);
277
+ switch (e.type) {
279
278
  case "verification_status":
280
279
  return {
281
280
  type: "verification_status",
282
- isVerified: t.is_verified === !0
281
+ isVerified: e.is_verified === !0
283
282
  };
284
283
  case "conversation_id":
285
284
  return {
286
285
  type: "conversation_id",
287
- conversationId: t.conversation_id
286
+ conversationId: e.conversation_id
288
287
  };
289
288
  case "thinking":
290
- return t.status === "complete" ? { type: "thinking_complete" } : null;
289
+ return e.status === "complete" ? { type: "thinking_complete" } : null;
291
290
  case "thinking_token":
292
291
  return {
293
292
  type: "thinking",
294
- content: t.content || ""
293
+ content: e.content || ""
295
294
  };
296
295
  case "content":
297
296
  return {
298
297
  type: "content",
299
- text: t.content || "",
298
+ text: e.content || "",
300
299
  accumulated: ""
301
300
  // Will be set by caller
302
301
  };
303
302
  case "citations":
304
303
  return {
305
304
  type: "citations",
306
- citations: t.citations
305
+ citations: e.citations
307
306
  };
308
307
  case "error":
309
308
  return {
310
309
  type: "error",
311
- message: t.message || "Unknown error"
310
+ message: e.message || "Unknown error"
312
311
  };
313
312
  case "tool_call_start":
314
313
  return {
315
314
  type: "tool_call_start",
316
- toolName: t.tool_name,
317
- arguments: t.arguments || {}
315
+ toolName: e.tool_name,
316
+ arguments: e.arguments || {}
318
317
  };
319
318
  case "tool_call_complete":
320
319
  return {
321
320
  type: "tool_call_complete",
322
- toolName: t.tool_name,
323
- success: t.success
321
+ toolName: e.tool_name,
322
+ success: e.success
324
323
  };
325
324
  case "client_tool_call":
326
325
  return {
327
326
  type: "client_tool_call",
328
- toolName: t.tool_name,
329
- arguments: t.arguments || {}
327
+ toolName: e.tool_name,
328
+ arguments: e.arguments || {}
330
329
  };
331
330
  case "workflow_started":
332
331
  return {
333
332
  type: "workflow_started",
334
- name: t.name,
335
- todos: t.todos
333
+ name: e.name,
334
+ todos: e.todos
336
335
  };
337
336
  case "todo_updated":
338
337
  return {
339
338
  type: "workflow_todo_updated",
340
- todoId: t.id,
341
- status: t.status
339
+ todoId: e.id,
340
+ status: e.status
342
341
  };
343
342
  case "workflow_ended":
344
343
  return { type: "workflow_ended" };
@@ -351,84 +350,84 @@ function I(o) {
351
350
  return console.error("[Crow] Failed to parse SSE data:", o), null;
352
351
  }
353
352
  }
354
- function* M(o) {
355
- const t = o.split(`
353
+ function* I(o) {
354
+ const e = o.split(`
356
355
  `);
357
- for (const e of t)
358
- e.startsWith("data: ") && (yield e.slice(6).trim());
356
+ for (const t of e)
357
+ t.startsWith("data: ") && (yield t.slice(6).trim());
359
358
  }
360
- async function* S(o, t) {
361
- var i;
362
- const e = (i = o.body) == null ? void 0 : i.getReader();
363
- if (!e)
359
+ async function* M(o, e) {
360
+ var n;
361
+ const t = (n = o.body) == null ? void 0 : n.getReader();
362
+ if (!t)
364
363
  throw new Error("Response body is not readable");
365
364
  const s = new TextDecoder();
366
365
  let r = "";
367
366
  try {
368
367
  for (; ; ) {
369
- if (t != null && t.aborted) {
370
- e.cancel();
368
+ if (e != null && e.aborted) {
369
+ t.cancel();
371
370
  return;
372
371
  }
373
- const { done: l, value: d } = await e.read();
374
- if (l) break;
372
+ const { done: i, value: d } = await t.read();
373
+ if (i) break;
375
374
  const h = s.decode(d);
376
- for (const u of M(h)) {
377
- const c = I(u);
378
- if (c && (c.type === "content" ? (r += c.text, yield { ...c, accumulated: r }) : yield c, c.type === "done"))
375
+ for (const u of I(h)) {
376
+ const l = b(u);
377
+ if (l && (l.type === "content" ? (r += l.text, yield { ...l, accumulated: r }) : yield l, l.type === "done"))
379
378
  return;
380
379
  }
381
380
  }
382
381
  } finally {
383
- e.releaseLock();
382
+ t.releaseLock();
384
383
  }
385
384
  }
386
- const m = {
387
- /**
388
- * Refresh the current page in the user's browser
389
- */
390
- refreshPage: async () => {
391
- try {
392
- return window.location.reload(), { status: "success", data: { message: "Page refresh initiated" } };
393
- } catch (o) {
394
- return { status: "error", error: String(o) };
395
- }
396
- },
397
- /**
398
- * Capture what's on the user's screen (DOM snapshot)
399
- */
400
- whatsOnScreen: async () => {
401
- try {
402
- const o = new _({ viewportExpansion: 500 }), t = await o.getBrowserState();
403
- return o.dispose(), {
404
- status: "success",
405
- data: {
406
- url: t.url,
407
- title: t.title,
408
- content: `${t.header}
409
-
410
- ${t.content}
411
-
412
- ${t.footer}`
413
- }
414
- };
415
- } catch (o) {
416
- return console.error("[Crow] whatsOnScreen error:", o), { status: "error", error: String(o) };
417
- }
385
+ async function S() {
386
+ try {
387
+ return window.location.reload(), { status: "success", data: { refreshed: !0 } };
388
+ } catch (o) {
389
+ return {
390
+ status: "error",
391
+ error: o instanceof Error ? o.message : "Failed to refresh page"
392
+ };
393
+ }
394
+ }
395
+ async function T() {
396
+ var o;
397
+ try {
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();
399
+ return {
400
+ status: "success",
401
+ data: {
402
+ title: e,
403
+ url: t,
404
+ pathname: s,
405
+ visibleText: r
406
+ }
407
+ };
408
+ } catch (e) {
409
+ return {
410
+ status: "error",
411
+ error: e instanceof Error ? e.message : "Failed to read screen"
412
+ };
418
413
  }
419
- }, T = Object.keys(m), $ = "https://api.usecrow.org", E = "claude-sonnet-4-20250514";
420
- class U {
421
- constructor(t) {
414
+ }
415
+ const w = {
416
+ refreshPage: S,
417
+ whatsOnScreen: T
418
+ }, $ = Object.keys(w), E = "https://api.usecrow.org", L = "claude-sonnet-4-20250514";
419
+ class x {
420
+ constructor(e) {
422
421
  this.context = {}, this.abortController = null, this.callbacks = {}, this._messages = [], this.messageListeners = /* @__PURE__ */ new Set(), this._isLoading = !1, this.loadingListeners = /* @__PURE__ */ new Set(), this.config = {
423
- productId: t.productId,
424
- apiUrl: t.apiUrl || $,
425
- model: t.model || E
426
- }, this.identity = new k(), this.tools = new C(), this.conversations = new b(
422
+ productId: e.productId,
423
+ apiUrl: e.apiUrl || E,
424
+ model: e.model || L
425
+ }, this.identity = new _(), this.tools = new k(), this.conversations = new v(
427
426
  this.config.productId,
428
427
  this.config.apiUrl
429
- ), this.tools.register(m), console.log("[Crow] Default tools registered:", T.join(", ")), this.identity.subscribe((e) => {
428
+ ), this.tools.register(w), console.log("[Crow] Default tools registered:", $.join(", ")), this.identity.subscribe((t) => {
430
429
  var s, r;
431
- (r = (s = this.callbacks).onVerificationStatus) == null || r.call(s, e.isVerified);
430
+ (r = (s = this.callbacks).onVerificationStatus) == null || r.call(s, t.isVerified);
432
431
  });
433
432
  }
434
433
  // ============================================================================
@@ -452,8 +451,8 @@ class U {
452
451
  get model() {
453
452
  return this.config.model;
454
453
  }
455
- set model(t) {
456
- this.config.model = t;
454
+ set model(e) {
455
+ this.config.model = e;
457
456
  }
458
457
  // ============================================================================
459
458
  // Event Callbacks
@@ -461,8 +460,8 @@ class U {
461
460
  /**
462
461
  * Register event callbacks
463
462
  */
464
- on(t) {
465
- this.callbacks = { ...this.callbacks, ...t };
463
+ on(e) {
464
+ this.callbacks = { ...this.callbacks, ...e };
466
465
  }
467
466
  // ============================================================================
468
467
  // Identity
@@ -470,8 +469,8 @@ class U {
470
469
  /**
471
470
  * Identify the current user with a JWT token
472
471
  */
473
- identify(t) {
474
- this.identity.identify(t);
472
+ identify(e) {
473
+ this.identity.identify(e);
475
474
  }
476
475
  /**
477
476
  * Reset user identity (call on logout)
@@ -497,14 +496,14 @@ class U {
497
496
  /**
498
497
  * Register client-side tool handlers
499
498
  */
500
- registerTools(t) {
501
- this.tools.register(t);
499
+ registerTools(e) {
500
+ this.tools.register(e);
502
501
  }
503
502
  /**
504
503
  * Unregister a tool handler
505
504
  */
506
- unregisterTool(t) {
507
- this.tools.unregister(t);
505
+ unregisterTool(e) {
506
+ this.tools.unregister(e);
508
507
  }
509
508
  /**
510
509
  * Get list of registered tool names
@@ -518,8 +517,8 @@ class U {
518
517
  /**
519
518
  * Set context data to be sent with messages
520
519
  */
521
- setContext(t) {
522
- this.context = { ...this.context, ...t };
520
+ setContext(e) {
521
+ this.context = { ...this.context, ...e };
523
522
  }
524
523
  /**
525
524
  * Clear context data
@@ -545,14 +544,14 @@ class U {
545
544
  /**
546
545
  * Subscribe to message changes
547
546
  */
548
- onMessages(t) {
549
- return this.messageListeners.add(t), () => this.messageListeners.delete(t);
547
+ onMessages(e) {
548
+ return this.messageListeners.add(e), () => this.messageListeners.delete(e);
550
549
  }
551
550
  /**
552
551
  * Subscribe to loading state changes
553
552
  */
554
- onLoading(t) {
555
- return this.loadingListeners.add(t), () => this.loadingListeners.delete(t);
553
+ onLoading(e) {
554
+ return this.loadingListeners.add(e), () => this.loadingListeners.delete(e);
556
555
  }
557
556
  /**
558
557
  * Clear all messages and start new conversation
@@ -563,31 +562,31 @@ class U {
563
562
  /**
564
563
  * Load messages from history
565
564
  */
566
- loadMessages(t) {
567
- this._messages = t, this.notifyMessages();
565
+ loadMessages(e) {
566
+ this._messages = e, this.notifyMessages();
568
567
  }
569
568
  notifyMessages() {
570
- const t = this.messages;
571
- for (const e of this.messageListeners)
572
- e(t);
569
+ const e = this.messages;
570
+ for (const t of this.messageListeners)
571
+ t(e);
573
572
  }
574
- setLoading(t) {
575
- this._isLoading = t;
576
- for (const e of this.loadingListeners)
577
- e(t);
573
+ setLoading(e) {
574
+ this._isLoading = e;
575
+ for (const t of this.loadingListeners)
576
+ t(e);
578
577
  }
579
- addMessage(t) {
580
- var e, s;
581
- this._messages = [...this._messages, t], this.notifyMessages(), (s = (e = this.callbacks).onMessage) == null || s.call(e, t);
578
+ addMessage(e) {
579
+ var t, s;
580
+ this._messages = [...this._messages, e], this.notifyMessages(), (s = (t = this.callbacks).onMessage) == null || s.call(t, e);
582
581
  }
583
- updateMessage(t, e) {
582
+ updateMessage(e, t) {
584
583
  var s, r;
585
584
  this._messages = this._messages.map(
586
- (i) => i.id === t ? { ...i, ...e } : i
587
- ), this.notifyMessages(), (r = (s = this.callbacks).onMessageUpdate) == null || r.call(s, t, e);
585
+ (n) => n.id === e ? { ...n, ...t } : n
586
+ ), this.notifyMessages(), (r = (s = this.callbacks).onMessageUpdate) == null || r.call(s, e, t);
588
587
  }
589
- generateMessageId(t) {
590
- return `${t}-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
588
+ generateMessageId(e) {
589
+ return `${e}-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
591
590
  }
592
591
  // ============================================================================
593
592
  // Conversations
@@ -601,29 +600,29 @@ class U {
601
600
  /**
602
601
  * Set current conversation ID
603
602
  */
604
- set conversationId(t) {
605
- this.conversations.setCurrentId(t);
603
+ set conversationId(e) {
604
+ this.conversations.setCurrentId(e);
606
605
  }
607
606
  /**
608
607
  * Get list of conversations for verified user
609
608
  */
610
609
  async getConversations() {
611
- const t = this.identity.getToken();
612
- return t ? this.conversations.getConversations(t) : (console.warn("[Crow] Cannot get conversations: user not identified"), []);
610
+ const e = this.identity.getToken();
611
+ return e ? this.conversations.getConversations(e) : (console.warn("[Crow] Cannot get conversations: user not identified"), []);
613
612
  }
614
613
  /**
615
614
  * Load conversation history
616
615
  */
617
- async loadHistory(t) {
618
- const e = this.identity.getToken();
619
- return e ? this.conversations.loadHistory(t, e) : this.conversations.loadAnonymousHistory(t);
616
+ async loadHistory(e) {
617
+ const t = this.identity.getToken();
618
+ return t ? this.conversations.loadHistory(e, t) : this.conversations.loadAnonymousHistory(e);
620
619
  }
621
620
  /**
622
621
  * Switch to a different conversation
623
622
  */
624
- async switchConversation(t) {
625
- const e = await this.loadHistory(t);
626
- this.conversations.setCurrentId(t), this.loadMessages(e);
623
+ async switchConversation(e) {
624
+ const t = await this.loadHistory(e);
625
+ this.conversations.setCurrentId(e), this.loadMessages(t);
627
626
  }
628
627
  // ============================================================================
629
628
  // Messaging
@@ -632,14 +631,14 @@ class U {
632
631
  * Send a message and receive streaming response
633
632
  * Returns an async generator of stream events
634
633
  */
635
- async *sendMessage(t) {
636
- var l, d, h, u, c, g, f, p, y, w;
637
- if (!t.trim())
634
+ async *sendMessage(e) {
635
+ var i, d, h, u, l, g, f, p, y, m;
636
+ if (!e.trim())
638
637
  return;
639
- const e = this.generateMessageId("user");
638
+ const t = this.generateMessageId("user");
640
639
  this.addMessage({
641
- id: e,
642
- content: t,
640
+ id: t,
641
+ content: e,
643
642
  role: "user",
644
643
  timestamp: /* @__PURE__ */ new Date()
645
644
  });
@@ -650,14 +649,14 @@ class U {
650
649
  role: "assistant",
651
650
  timestamp: /* @__PURE__ */ new Date()
652
651
  }), this.setLoading(!0), this.abortController = new AbortController();
653
- let r = "", i = "";
652
+ let r = "", n = "";
654
653
  try {
655
- const a = await fetch(`${this.config.apiUrl}/api/chat/message`, {
654
+ const c = await fetch(`${this.config.apiUrl}/api/chat/message`, {
656
655
  method: "POST",
657
656
  headers: { "Content-Type": "application/json" },
658
657
  body: JSON.stringify({
659
658
  product_id: this.config.productId,
660
- message: t,
659
+ message: e,
661
660
  conversation_id: this.conversations.getCurrentId(),
662
661
  identity_token: this.identity.getToken(),
663
662
  model: this.config.model,
@@ -665,55 +664,55 @@ class U {
665
664
  }),
666
665
  signal: this.abortController.signal
667
666
  });
668
- if (!a.ok)
669
- throw new Error(`HTTP error: ${a.status}`);
670
- for await (const n of S(a, this.abortController.signal)) {
671
- switch (n.type) {
667
+ if (!c.ok)
668
+ throw new Error(`HTTP error: ${c.status}`);
669
+ for await (const a of M(c, this.abortController.signal)) {
670
+ switch (a.type) {
672
671
  case "content":
673
- r = n.accumulated, this.updateMessage(s, { content: r });
672
+ r = a.accumulated, this.updateMessage(s, { content: r });
674
673
  break;
675
674
  case "thinking":
676
- i += n.content, this.updateMessage(s, { thinking: i });
675
+ n += a.content, this.updateMessage(s, { thinking: n });
677
676
  break;
678
677
  case "thinking_complete":
679
678
  this.updateMessage(s, { thinkingComplete: !0 });
680
679
  break;
681
680
  case "citations":
682
- this.updateMessage(s, { citations: n.citations });
681
+ this.updateMessage(s, { citations: a.citations });
683
682
  break;
684
683
  case "verification_status":
685
- this.identity.setVerified(n.isVerified);
684
+ this.identity.setVerified(a.isVerified);
686
685
  break;
687
686
  case "conversation_id":
688
- this.conversations.setCurrentId(n.conversationId);
687
+ this.conversations.setCurrentId(a.conversationId);
689
688
  break;
690
689
  case "client_tool_call":
691
- await this.tools.execute(n.toolName, n.arguments), (d = (l = this.callbacks).onToolCall) == null || d.call(l, n);
690
+ await this.tools.execute(a.toolName, a.arguments), (d = (i = this.callbacks).onToolCall) == null || d.call(i, a);
692
691
  break;
693
692
  case "tool_call_start":
694
693
  case "tool_call_complete":
695
- (u = (h = this.callbacks).onToolCall) == null || u.call(h, n);
694
+ (u = (h = this.callbacks).onToolCall) == null || u.call(h, a);
696
695
  break;
697
696
  case "workflow_started":
698
697
  case "workflow_todo_updated":
699
698
  case "workflow_ended":
700
699
  case "workflow_complete_prompt":
701
- (g = (c = this.callbacks).onWorkflow) == null || g.call(c, n);
700
+ (g = (l = this.callbacks).onWorkflow) == null || g.call(l, a);
702
701
  break;
703
702
  case "error":
704
- this.updateMessage(s, { content: n.message }), (p = (f = this.callbacks).onError) == null || p.call(f, new Error(n.message));
703
+ this.updateMessage(s, { content: a.message }), (p = (f = this.callbacks).onError) == null || p.call(f, new Error(a.message));
705
704
  break;
706
705
  }
707
- yield n;
706
+ yield a;
708
707
  }
709
- } catch (a) {
710
- if (a instanceof Error && a.name === "AbortError") {
711
- r ? this.updateMessage(s, { content: r }) : (this._messages = this._messages.filter((n) => n.id !== s), this.notifyMessages());
708
+ } catch (c) {
709
+ if (c instanceof Error && c.name === "AbortError") {
710
+ r ? this.updateMessage(s, { content: r }) : (this._messages = this._messages.filter((a) => a.id !== s), this.notifyMessages());
712
711
  return;
713
712
  }
714
- console.error("[Crow] Error:", a), this.updateMessage(s, {
713
+ console.error("[Crow] Error:", c), this.updateMessage(s, {
715
714
  content: "Sorry, I encountered an error. Please try again."
716
- }), (w = (y = this.callbacks).onError) == null || w.call(y, a instanceof Error ? a : new Error(String(a)));
715
+ }), (m = (y = this.callbacks).onError) == null || m.call(y, c instanceof Error ? c : new Error(String(c)));
717
716
  } finally {
718
717
  this.setLoading(!1), this.abortController = null;
719
718
  }
@@ -721,13 +720,13 @@ class U {
721
720
  /**
722
721
  * Send a message and wait for complete response (non-streaming)
723
722
  */
724
- async send(t) {
725
- let e = null;
726
- for await (const r of this.sendMessage(t))
723
+ async send(e) {
724
+ let t = null;
725
+ for await (const r of this.sendMessage(e))
727
726
  if (r.type === "done")
728
727
  break;
729
728
  const s = this.messages;
730
- return s.length > 0 && (e = s[s.length - 1], e.role === "assistant") ? e : null;
729
+ return s.length > 0 && (t = s[s.length - 1], t.role === "assistant") ? t : null;
731
730
  }
732
731
  /**
733
732
  * Stop current generation
@@ -745,15 +744,73 @@ class U {
745
744
  this.stop(), this.messageListeners.clear(), this.loadingListeners.clear();
746
745
  }
747
746
  }
747
+ function U(o, e, t) {
748
+ const s = o.find(
749
+ (n) => n.name.toLowerCase() === e.toLowerCase()
750
+ );
751
+ if (!s) return null;
752
+ let r = s.path;
753
+ if (t)
754
+ for (const [n, i] of Object.entries(t))
755
+ r = r.replace(`:${n}`, String(i));
756
+ return r;
757
+ }
758
+ function O(o, e) {
759
+ return async (t) => {
760
+ try {
761
+ const s = t.page, r = t.params, n = t.url;
762
+ let i = null;
763
+ if (s) {
764
+ if (i = U(o, s, r), !i)
765
+ return {
766
+ status: "error",
767
+ error: `Unknown page: "${s}". Available pages: ${o.map((h) => h.name).join(", ")}`
768
+ };
769
+ } else if (n)
770
+ i = n;
771
+ else
772
+ return {
773
+ status: "error",
774
+ error: 'Either "page" or "url" parameter is required'
775
+ };
776
+ const d = i.match(/:([a-zA-Z_][a-zA-Z0-9_]*)/g);
777
+ return d ? {
778
+ status: "error",
779
+ error: `Missing parameters: ${d.join(", ")}. Please provide values for these parameters.`
780
+ } : e ? (e(i), {
781
+ status: "success",
782
+ data: {
783
+ navigated_to: i,
784
+ page: s || void 0,
785
+ method: "spa_router"
786
+ }
787
+ }) : (window.location.href = i, {
788
+ status: "success",
789
+ data: {
790
+ navigated_to: i,
791
+ page: s || void 0,
792
+ method: "full_navigation"
793
+ }
794
+ });
795
+ } catch (s) {
796
+ return {
797
+ status: "error",
798
+ error: String(s)
799
+ };
800
+ }
801
+ };
802
+ }
748
803
  export {
749
- b as ConversationManager,
750
- R as CrowBrowserUse,
751
- U as CrowClient,
752
- m as DEFAULT_TOOLS,
753
- T as DEFAULT_TOOL_NAMES,
754
- k as IdentityManager,
755
- C as ToolManager,
756
- M as parseSSEChunk,
757
- I as parseSSEData,
758
- S as streamResponse
804
+ v as ConversationManager,
805
+ D as CrowBrowserUse,
806
+ x as CrowClient,
807
+ w as DEFAULT_TOOLS,
808
+ $ as DEFAULT_TOOL_NAMES,
809
+ _ as IdentityManager,
810
+ k as ToolManager,
811
+ O as createNavigateToPageTool,
812
+ I as parseSSEChunk,
813
+ b as parseSSEData,
814
+ U as resolveRoute,
815
+ M as streamResponse
759
816
  };