@usecrow/client 0.1.43 → 0.1.45

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