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