@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/PageController-BDcmu8Xe.cjs +9 -0
- package/dist/PageController-BweWYS-Z.js +1385 -0
- package/dist/browser.cjs +1 -1
- package/dist/browser.js +8 -7
- package/dist/browserUse-BjeJDX8x.cjs +1 -0
- package/dist/browserUse-Btg7osSj.js +235 -0
- package/dist/index.cjs +3 -7
- package/dist/index.d.ts +26 -13
- package/dist/index.js +291 -234
- package/package.json +1 -1
- package/dist/browserUse-CAnPpcJX.cjs +0 -9
- package/dist/browserUse-DHVE_OuS.js +0 -1622
package/dist/index.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
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(
|
|
15
|
-
const { token:
|
|
13
|
+
identify(e) {
|
|
14
|
+
const { token: t, ...s } = e;
|
|
16
15
|
this.state = {
|
|
17
|
-
token:
|
|
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(
|
|
27
|
-
this.state = { ...this.state, isVerified:
|
|
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(
|
|
67
|
-
return this.listeners.add(
|
|
65
|
+
subscribe(e) {
|
|
66
|
+
return this.listeners.add(e), () => this.listeners.delete(e);
|
|
68
67
|
}
|
|
69
68
|
notify() {
|
|
70
|
-
const
|
|
71
|
-
for (const
|
|
72
|
-
e
|
|
69
|
+
const e = this.getState();
|
|
70
|
+
for (const t of this.listeners)
|
|
71
|
+
t(e);
|
|
73
72
|
}
|
|
74
73
|
}
|
|
75
|
-
class
|
|
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(
|
|
83
|
-
for (const [
|
|
84
|
-
typeof s == "function" ? (this.handlers[
|
|
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(
|
|
90
|
-
delete this.handlers[
|
|
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(
|
|
96
|
-
return
|
|
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(
|
|
108
|
-
const s = this.handlers[
|
|
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: ${
|
|
109
|
+
return console.warn(`[Crow] No handler registered for tool: ${e}`), {
|
|
111
110
|
status: "error",
|
|
112
|
-
error: `No handler registered for tool: ${
|
|
111
|
+
error: `No handler registered for tool: ${e}`
|
|
113
112
|
};
|
|
114
113
|
try {
|
|
115
|
-
console.log(`[Crow] Executing client tool: ${
|
|
116
|
-
const r = await s(
|
|
117
|
-
return console.log(`[Crow] Tool ${
|
|
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
|
|
120
|
-
return console.error(`[Crow] Tool ${
|
|
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:
|
|
121
|
+
error: n
|
|
123
122
|
};
|
|
124
123
|
}
|
|
125
124
|
}
|
|
126
125
|
}
|
|
127
|
-
const
|
|
128
|
-
class
|
|
129
|
-
constructor(
|
|
130
|
-
this.currentId = null, this.productId =
|
|
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 `${
|
|
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(
|
|
150
|
+
saveToStorage(e) {
|
|
152
151
|
try {
|
|
153
|
-
localStorage.setItem(this.getStorageKey(),
|
|
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(
|
|
176
|
-
this.currentId =
|
|
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(
|
|
192
|
+
async getConversations(e) {
|
|
194
193
|
try {
|
|
195
|
-
const
|
|
196
|
-
`${this.apiUrl}/api/chat/conversations?product_id=${this.productId}&identity_token=${encodeURIComponent(
|
|
194
|
+
const t = await fetch(
|
|
195
|
+
`${this.apiUrl}/api/chat/conversations?product_id=${this.productId}&identity_token=${encodeURIComponent(e)}`
|
|
197
196
|
);
|
|
198
|
-
if (!
|
|
199
|
-
throw new Error(`HTTP error: ${
|
|
200
|
-
return (await
|
|
201
|
-
} catch (
|
|
202
|
-
return console.error("[Crow] Failed to load conversations:",
|
|
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(
|
|
207
|
+
async loadHistory(e, t) {
|
|
209
208
|
try {
|
|
210
209
|
const s = await fetch(
|
|
211
|
-
`${this.apiUrl}/api/chat/conversations/${
|
|
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(
|
|
223
|
+
async loadAnonymousHistory(e) {
|
|
225
224
|
try {
|
|
226
|
-
const
|
|
227
|
-
`${this.apiUrl}/api/chat/conversations/${
|
|
225
|
+
const t = await fetch(
|
|
226
|
+
`${this.apiUrl}/api/chat/conversations/${e}/history/anonymous?product_id=${this.productId}`
|
|
228
227
|
);
|
|
229
|
-
if (!
|
|
230
|
-
throw new Error(`HTTP error: ${
|
|
231
|
-
const s = await
|
|
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 (
|
|
234
|
-
return console.error("[Crow] Failed to load anonymous conversation history:",
|
|
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(
|
|
241
|
-
return
|
|
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(
|
|
244
|
-
role:
|
|
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(
|
|
250
|
+
parseContent(e) {
|
|
252
251
|
try {
|
|
253
|
-
const
|
|
254
|
-
if (Array.isArray(
|
|
255
|
-
const s =
|
|
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) ||
|
|
257
|
+
return (s == null ? void 0 : s.text) || e;
|
|
259
258
|
}
|
|
260
259
|
} catch {
|
|
261
260
|
}
|
|
262
|
-
if (
|
|
263
|
-
const
|
|
261
|
+
if (e.includes("'type': 'text'")) {
|
|
262
|
+
const t = e.match(
|
|
264
263
|
/\{'text':\s*'((?:[^'\\]|\\.)*)'\s*,\s*'type':\s*'text'/
|
|
265
264
|
);
|
|
266
|
-
if (
|
|
267
|
-
return
|
|
265
|
+
if (t)
|
|
266
|
+
return t[1].replace(/\\n/g, `
|
|
268
267
|
`).replace(/\\'/g, "'");
|
|
269
268
|
}
|
|
270
|
-
return
|
|
269
|
+
return e;
|
|
271
270
|
}
|
|
272
271
|
}
|
|
273
|
-
function
|
|
272
|
+
function b(o) {
|
|
274
273
|
if (o === "[DONE]")
|
|
275
274
|
return { type: "done" };
|
|
276
275
|
try {
|
|
277
|
-
const
|
|
278
|
-
switch (
|
|
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:
|
|
281
|
+
isVerified: e.is_verified === !0
|
|
283
282
|
};
|
|
284
283
|
case "conversation_id":
|
|
285
284
|
return {
|
|
286
285
|
type: "conversation_id",
|
|
287
|
-
conversationId:
|
|
286
|
+
conversationId: e.conversation_id
|
|
288
287
|
};
|
|
289
288
|
case "thinking":
|
|
290
|
-
return
|
|
289
|
+
return e.status === "complete" ? { type: "thinking_complete" } : null;
|
|
291
290
|
case "thinking_token":
|
|
292
291
|
return {
|
|
293
292
|
type: "thinking",
|
|
294
|
-
content:
|
|
293
|
+
content: e.content || ""
|
|
295
294
|
};
|
|
296
295
|
case "content":
|
|
297
296
|
return {
|
|
298
297
|
type: "content",
|
|
299
|
-
text:
|
|
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:
|
|
305
|
+
citations: e.citations
|
|
307
306
|
};
|
|
308
307
|
case "error":
|
|
309
308
|
return {
|
|
310
309
|
type: "error",
|
|
311
|
-
message:
|
|
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:
|
|
317
|
-
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:
|
|
323
|
-
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:
|
|
329
|
-
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:
|
|
335
|
-
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:
|
|
341
|
-
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*
|
|
355
|
-
const
|
|
353
|
+
function* I(o) {
|
|
354
|
+
const e = o.split(`
|
|
356
355
|
`);
|
|
357
|
-
for (const
|
|
358
|
-
|
|
356
|
+
for (const t of e)
|
|
357
|
+
t.startsWith("data: ") && (yield t.slice(6).trim());
|
|
359
358
|
}
|
|
360
|
-
async function*
|
|
361
|
-
var
|
|
362
|
-
const
|
|
363
|
-
if (!
|
|
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 (
|
|
370
|
-
|
|
368
|
+
if (e != null && e.aborted) {
|
|
369
|
+
t.cancel();
|
|
371
370
|
return;
|
|
372
371
|
}
|
|
373
|
-
const { done:
|
|
374
|
-
if (
|
|
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
|
|
377
|
-
const
|
|
378
|
-
if (
|
|
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
|
-
|
|
382
|
+
t.releaseLock();
|
|
384
383
|
}
|
|
385
384
|
}
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
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
|
-
}
|
|
420
|
-
|
|
421
|
-
|
|
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:
|
|
424
|
-
apiUrl:
|
|
425
|
-
model:
|
|
426
|
-
}, this.identity = new
|
|
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(
|
|
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,
|
|
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(
|
|
456
|
-
this.config.model =
|
|
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(
|
|
465
|
-
this.callbacks = { ...this.callbacks, ...
|
|
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(
|
|
474
|
-
this.identity.identify(
|
|
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(
|
|
501
|
-
this.tools.register(
|
|
499
|
+
registerTools(e) {
|
|
500
|
+
this.tools.register(e);
|
|
502
501
|
}
|
|
503
502
|
/**
|
|
504
503
|
* Unregister a tool handler
|
|
505
504
|
*/
|
|
506
|
-
unregisterTool(
|
|
507
|
-
this.tools.unregister(
|
|
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(
|
|
522
|
-
this.context = { ...this.context, ...
|
|
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(
|
|
549
|
-
return this.messageListeners.add(
|
|
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(
|
|
555
|
-
return this.loadingListeners.add(
|
|
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(
|
|
567
|
-
this._messages =
|
|
565
|
+
loadMessages(e) {
|
|
566
|
+
this._messages = e, this.notifyMessages();
|
|
568
567
|
}
|
|
569
568
|
notifyMessages() {
|
|
570
|
-
const
|
|
571
|
-
for (const
|
|
572
|
-
e
|
|
569
|
+
const e = this.messages;
|
|
570
|
+
for (const t of this.messageListeners)
|
|
571
|
+
t(e);
|
|
573
572
|
}
|
|
574
|
-
setLoading(
|
|
575
|
-
this._isLoading =
|
|
576
|
-
for (const
|
|
577
|
-
e
|
|
573
|
+
setLoading(e) {
|
|
574
|
+
this._isLoading = e;
|
|
575
|
+
for (const t of this.loadingListeners)
|
|
576
|
+
t(e);
|
|
578
577
|
}
|
|
579
|
-
addMessage(
|
|
580
|
-
var
|
|
581
|
-
this._messages = [...this._messages,
|
|
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(
|
|
582
|
+
updateMessage(e, t) {
|
|
584
583
|
var s, r;
|
|
585
584
|
this._messages = this._messages.map(
|
|
586
|
-
(
|
|
587
|
-
), this.notifyMessages(), (r = (s = this.callbacks).onMessageUpdate) == null || r.call(s,
|
|
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(
|
|
590
|
-
return `${
|
|
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(
|
|
605
|
-
this.conversations.setCurrentId(
|
|
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
|
|
612
|
-
return
|
|
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(
|
|
618
|
-
const
|
|
619
|
-
return
|
|
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(
|
|
625
|
-
const
|
|
626
|
-
this.conversations.setCurrentId(
|
|
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(
|
|
636
|
-
var
|
|
637
|
-
if (!
|
|
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
|
|
638
|
+
const t = this.generateMessageId("user");
|
|
640
639
|
this.addMessage({
|
|
641
|
-
id:
|
|
642
|
-
content:
|
|
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 = "",
|
|
652
|
+
let r = "", n = "";
|
|
654
653
|
try {
|
|
655
|
-
const
|
|
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:
|
|
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 (!
|
|
669
|
-
throw new Error(`HTTP error: ${
|
|
670
|
-
for await (const
|
|
671
|
-
switch (
|
|
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 =
|
|
672
|
+
r = a.accumulated, this.updateMessage(s, { content: r });
|
|
674
673
|
break;
|
|
675
674
|
case "thinking":
|
|
676
|
-
|
|
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:
|
|
681
|
+
this.updateMessage(s, { citations: a.citations });
|
|
683
682
|
break;
|
|
684
683
|
case "verification_status":
|
|
685
|
-
this.identity.setVerified(
|
|
684
|
+
this.identity.setVerified(a.isVerified);
|
|
686
685
|
break;
|
|
687
686
|
case "conversation_id":
|
|
688
|
-
this.conversations.setCurrentId(
|
|
687
|
+
this.conversations.setCurrentId(a.conversationId);
|
|
689
688
|
break;
|
|
690
689
|
case "client_tool_call":
|
|
691
|
-
await this.tools.execute(
|
|
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,
|
|
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 = (
|
|
700
|
+
(g = (l = this.callbacks).onWorkflow) == null || g.call(l, a);
|
|
702
701
|
break;
|
|
703
702
|
case "error":
|
|
704
|
-
this.updateMessage(s, { content:
|
|
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
|
|
706
|
+
yield a;
|
|
708
707
|
}
|
|
709
|
-
} catch (
|
|
710
|
-
if (
|
|
711
|
-
r ? this.updateMessage(s, { content: r }) : (this._messages = this._messages.filter((
|
|
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:",
|
|
713
|
+
console.error("[Crow] Error:", c), this.updateMessage(s, {
|
|
715
714
|
content: "Sorry, I encountered an error. Please try again."
|
|
716
|
-
}), (
|
|
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(
|
|
725
|
-
let
|
|
726
|
-
for await (const r of this.sendMessage(
|
|
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 && (
|
|
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
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
I as
|
|
758
|
-
|
|
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
|
};
|