@usecrow/client 0.1.21 → 0.1.26
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-GcMFZYwU.cjs +9 -0
- package/dist/PageController-KoeqDxMP.js +1377 -0
- package/dist/SimulatorMask-CgaoHOve.js +120 -0
- package/dist/SimulatorMask-DoBLczoQ.cjs +2 -0
- package/dist/browser.cjs +1 -284
- package/dist/browser.d.ts +342 -52
- package/dist/browser.js +18 -276
- package/dist/browserUse-BOc9kyBK.cjs +1 -0
- package/dist/browserUse-BbPG4pH1.js +205 -0
- package/dist/index.cjs +3 -1107
- package/dist/index.d.ts +474 -311
- package/dist/index.js +254 -614
- package/package.json +8 -6
- package/dist/browser.cjs.map +0 -1
- package/dist/browser.d.cts +0 -52
- package/dist/browser.js.map +0 -1
- package/dist/browserUse-CZNpayEF.d.cts +0 -188
- package/dist/browserUse-CZNpayEF.d.ts +0 -188
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -311
- package/dist/index.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,33 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { C as x } from "./browserUse-BbPG4pH1.js";
|
|
2
|
+
class _ {
|
|
3
3
|
constructor() {
|
|
4
4
|
this.state = {
|
|
5
5
|
token: null,
|
|
6
6
|
metadata: {},
|
|
7
|
-
isVerified:
|
|
8
|
-
};
|
|
9
|
-
this.listeners = /* @__PURE__ */ new Set();
|
|
7
|
+
isVerified: !1
|
|
8
|
+
}, this.listeners = /* @__PURE__ */ new Set();
|
|
10
9
|
}
|
|
11
10
|
/**
|
|
12
11
|
* Identify the current user with a JWT token
|
|
13
12
|
*/
|
|
14
|
-
identify(
|
|
15
|
-
const { token, ...
|
|
13
|
+
identify(t) {
|
|
14
|
+
const { token: e, ...s } = t;
|
|
16
15
|
this.state = {
|
|
17
|
-
token,
|
|
18
|
-
metadata,
|
|
19
|
-
isVerified:
|
|
16
|
+
token: e,
|
|
17
|
+
metadata: s,
|
|
18
|
+
isVerified: !1
|
|
20
19
|
// Will be set when server confirms
|
|
21
|
-
};
|
|
22
|
-
this.notify();
|
|
23
|
-
console.log("[Crow] User identified");
|
|
20
|
+
}, this.notify(), console.log("[Crow] User identified");
|
|
24
21
|
}
|
|
25
22
|
/**
|
|
26
23
|
* Update verification status (called when server confirms)
|
|
27
24
|
*/
|
|
28
|
-
setVerified(
|
|
29
|
-
this.state = { ...this.state, isVerified };
|
|
30
|
-
this.notify();
|
|
25
|
+
setVerified(t) {
|
|
26
|
+
this.state = { ...this.state, isVerified: t }, this.notify();
|
|
31
27
|
}
|
|
32
28
|
/**
|
|
33
29
|
* Reset user identity (call on logout)
|
|
@@ -36,10 +32,8 @@ var IdentityManager = class {
|
|
|
36
32
|
this.state = {
|
|
37
33
|
token: null,
|
|
38
34
|
metadata: {},
|
|
39
|
-
isVerified:
|
|
40
|
-
};
|
|
41
|
-
this.notify();
|
|
42
|
-
console.log("[Crow] User reset");
|
|
35
|
+
isVerified: !1
|
|
36
|
+
}, this.notify(), console.log("[Crow] User reset");
|
|
43
37
|
}
|
|
44
38
|
/**
|
|
45
39
|
* Get current identity token
|
|
@@ -68,48 +62,37 @@ var IdentityManager = class {
|
|
|
68
62
|
/**
|
|
69
63
|
* Subscribe to identity changes
|
|
70
64
|
*/
|
|
71
|
-
subscribe(
|
|
72
|
-
this.listeners.add(
|
|
73
|
-
return () => this.listeners.delete(callback);
|
|
65
|
+
subscribe(t) {
|
|
66
|
+
return this.listeners.add(t), () => this.listeners.delete(t);
|
|
74
67
|
}
|
|
75
68
|
notify() {
|
|
76
|
-
const
|
|
77
|
-
for (const
|
|
78
|
-
|
|
79
|
-
}
|
|
69
|
+
const t = this.getState();
|
|
70
|
+
for (const e of this.listeners)
|
|
71
|
+
e(t);
|
|
80
72
|
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// src/tools.ts
|
|
84
|
-
var ToolManager = class {
|
|
73
|
+
}
|
|
74
|
+
class k {
|
|
85
75
|
constructor() {
|
|
86
76
|
this.handlers = {};
|
|
87
77
|
}
|
|
88
78
|
/**
|
|
89
79
|
* Register client-side tool handlers
|
|
90
80
|
*/
|
|
91
|
-
register(
|
|
92
|
-
for (const [
|
|
93
|
-
|
|
94
|
-
this.handlers[name] = handler;
|
|
95
|
-
console.log(`[Crow] Registered client tool: ${name}`);
|
|
96
|
-
} else {
|
|
97
|
-
console.warn(`[Crow] Skipping ${name}: handler is not a function`);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
81
|
+
register(t) {
|
|
82
|
+
for (const [e, s] of Object.entries(t))
|
|
83
|
+
typeof s == "function" ? (this.handlers[e] = s, console.log(`[Crow] Registered client tool: ${e}`)) : console.warn(`[Crow] Skipping ${e}: handler is not a function`);
|
|
100
84
|
}
|
|
101
85
|
/**
|
|
102
86
|
* Unregister a tool handler
|
|
103
87
|
*/
|
|
104
|
-
unregister(
|
|
105
|
-
delete this.handlers[
|
|
106
|
-
console.log(`[Crow] Unregistered client tool: ${name}`);
|
|
88
|
+
unregister(t) {
|
|
89
|
+
delete this.handlers[t], console.log(`[Crow] Unregistered client tool: ${t}`);
|
|
107
90
|
}
|
|
108
91
|
/**
|
|
109
92
|
* Check if a tool is registered
|
|
110
93
|
*/
|
|
111
|
-
has(
|
|
112
|
-
return
|
|
94
|
+
has(t) {
|
|
95
|
+
return t in this.handlers;
|
|
113
96
|
}
|
|
114
97
|
/**
|
|
115
98
|
* Get all registered tool names
|
|
@@ -120,45 +103,36 @@ var ToolManager = class {
|
|
|
120
103
|
/**
|
|
121
104
|
* Execute a client-side tool
|
|
122
105
|
*/
|
|
123
|
-
async execute(
|
|
124
|
-
const
|
|
125
|
-
if (!
|
|
126
|
-
console.warn(`[Crow] No handler registered for tool: ${
|
|
127
|
-
return {
|
|
106
|
+
async execute(t, e) {
|
|
107
|
+
const s = this.handlers[t];
|
|
108
|
+
if (!s)
|
|
109
|
+
return console.warn(`[Crow] No handler registered for tool: ${t}`), {
|
|
128
110
|
status: "error",
|
|
129
|
-
error: `No handler registered for tool: ${
|
|
111
|
+
error: `No handler registered for tool: ${t}`
|
|
130
112
|
};
|
|
131
|
-
}
|
|
132
113
|
try {
|
|
133
|
-
console.log(`[Crow] Executing client tool: ${
|
|
134
|
-
const
|
|
135
|
-
console.log(`[Crow] Tool ${
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
console.error(`[Crow] Tool ${name} failed:`, error);
|
|
140
|
-
return {
|
|
114
|
+
console.log(`[Crow] Executing client tool: ${t}`, e);
|
|
115
|
+
const r = await s(e);
|
|
116
|
+
return console.log(`[Crow] Tool ${t} completed:`, r), r;
|
|
117
|
+
} catch (r) {
|
|
118
|
+
const i = r instanceof Error ? r.message : String(r);
|
|
119
|
+
return console.error(`[Crow] Tool ${t} failed:`, r), {
|
|
141
120
|
status: "error",
|
|
142
|
-
error:
|
|
121
|
+
error: i
|
|
143
122
|
};
|
|
144
123
|
}
|
|
145
124
|
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
constructor(productId, apiUrl) {
|
|
152
|
-
this.currentId = null;
|
|
153
|
-
this.productId = productId;
|
|
154
|
-
this.apiUrl = apiUrl;
|
|
155
|
-
this.currentId = this.loadFromStorage();
|
|
125
|
+
}
|
|
126
|
+
const C = "crow_conv_";
|
|
127
|
+
class b {
|
|
128
|
+
constructor(t, e) {
|
|
129
|
+
this.currentId = null, this.productId = t, this.apiUrl = e, this.currentId = this.loadFromStorage();
|
|
156
130
|
}
|
|
157
131
|
/**
|
|
158
132
|
* Get localStorage key for this product
|
|
159
133
|
*/
|
|
160
134
|
getStorageKey() {
|
|
161
|
-
return `${
|
|
135
|
+
return `${C}${this.productId}`;
|
|
162
136
|
}
|
|
163
137
|
/**
|
|
164
138
|
* Load conversation ID from localStorage
|
|
@@ -173,9 +147,9 @@ var ConversationManager = class {
|
|
|
173
147
|
/**
|
|
174
148
|
* Save conversation ID to localStorage
|
|
175
149
|
*/
|
|
176
|
-
saveToStorage(
|
|
150
|
+
saveToStorage(t) {
|
|
177
151
|
try {
|
|
178
|
-
localStorage.setItem(this.getStorageKey(),
|
|
152
|
+
localStorage.setItem(this.getStorageKey(), t);
|
|
179
153
|
} catch {
|
|
180
154
|
}
|
|
181
155
|
}
|
|
@@ -197,13 +171,8 @@ var ConversationManager = class {
|
|
|
197
171
|
/**
|
|
198
172
|
* Set current conversation ID
|
|
199
173
|
*/
|
|
200
|
-
setCurrentId(
|
|
201
|
-
this.currentId =
|
|
202
|
-
if (id) {
|
|
203
|
-
this.saveToStorage(id);
|
|
204
|
-
} else {
|
|
205
|
-
this.clearStorage();
|
|
206
|
-
}
|
|
174
|
+
setCurrentId(t) {
|
|
175
|
+
this.currentId = t, t ? this.saveToStorage(t) : this.clearStorage();
|
|
207
176
|
}
|
|
208
177
|
/**
|
|
209
178
|
* Check if there's a restored conversation
|
|
@@ -215,174 +184,160 @@ var ConversationManager = class {
|
|
|
215
184
|
* Clear current conversation (start new)
|
|
216
185
|
*/
|
|
217
186
|
clear() {
|
|
218
|
-
this.currentId = null;
|
|
219
|
-
this.clearStorage();
|
|
187
|
+
this.currentId = null, this.clearStorage();
|
|
220
188
|
}
|
|
221
189
|
/**
|
|
222
190
|
* Fetch list of conversations for verified user
|
|
223
191
|
*/
|
|
224
|
-
async getConversations(
|
|
192
|
+
async getConversations(t) {
|
|
225
193
|
try {
|
|
226
|
-
const
|
|
227
|
-
`${this.apiUrl}/api/chat/conversations?product_id=${this.productId}&identity_token=${encodeURIComponent(
|
|
194
|
+
const e = await fetch(
|
|
195
|
+
`${this.apiUrl}/api/chat/conversations?product_id=${this.productId}&identity_token=${encodeURIComponent(t)}`
|
|
228
196
|
);
|
|
229
|
-
if (!
|
|
230
|
-
throw new Error(`HTTP error: ${
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
return
|
|
234
|
-
} catch (error) {
|
|
235
|
-
console.error("[Crow] Failed to load conversations:", error);
|
|
236
|
-
return [];
|
|
197
|
+
if (!e.ok)
|
|
198
|
+
throw new Error(`HTTP error: ${e.status}`);
|
|
199
|
+
return (await e.json()).conversations || [];
|
|
200
|
+
} catch (e) {
|
|
201
|
+
return console.error("[Crow] Failed to load conversations:", e), [];
|
|
237
202
|
}
|
|
238
203
|
}
|
|
239
204
|
/**
|
|
240
205
|
* Load conversation history for verified user
|
|
241
206
|
*/
|
|
242
|
-
async loadHistory(
|
|
207
|
+
async loadHistory(t, e) {
|
|
243
208
|
try {
|
|
244
|
-
const
|
|
245
|
-
`${this.apiUrl}/api/chat/conversations/${
|
|
209
|
+
const s = await fetch(
|
|
210
|
+
`${this.apiUrl}/api/chat/conversations/${t}/history?product_id=${this.productId}&identity_token=${encodeURIComponent(e)}`
|
|
246
211
|
);
|
|
247
|
-
if (!
|
|
248
|
-
throw new Error(`HTTP error: ${
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
console.error("[Crow] Failed to load conversation history:", error);
|
|
254
|
-
return [];
|
|
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), [];
|
|
255
218
|
}
|
|
256
219
|
}
|
|
257
220
|
/**
|
|
258
221
|
* Load conversation history for anonymous user
|
|
259
222
|
*/
|
|
260
|
-
async loadAnonymousHistory(
|
|
223
|
+
async loadAnonymousHistory(t) {
|
|
261
224
|
try {
|
|
262
|
-
const
|
|
263
|
-
`${this.apiUrl}/api/chat/conversations/${
|
|
225
|
+
const e = await fetch(
|
|
226
|
+
`${this.apiUrl}/api/chat/conversations/${t}/history/anonymous?product_id=${this.productId}`
|
|
264
227
|
);
|
|
265
|
-
if (!
|
|
266
|
-
throw new Error(`HTTP error: ${
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
console.error("[Crow] Failed to load anonymous conversation history:", error);
|
|
272
|
-
return [];
|
|
228
|
+
if (!e.ok)
|
|
229
|
+
throw new Error(`HTTP error: ${e.status}`);
|
|
230
|
+
const s = await e.json();
|
|
231
|
+
return this.parseHistoryMessages(s.messages || []);
|
|
232
|
+
} catch (e) {
|
|
233
|
+
return console.error("[Crow] Failed to load anonymous conversation history:", e), [];
|
|
273
234
|
}
|
|
274
235
|
}
|
|
275
236
|
/**
|
|
276
237
|
* Parse history messages from API format
|
|
277
238
|
*/
|
|
278
|
-
parseHistoryMessages(
|
|
279
|
-
return
|
|
280
|
-
id: `history-${
|
|
281
|
-
content: this.parseContent(
|
|
282
|
-
role:
|
|
239
|
+
parseHistoryMessages(t) {
|
|
240
|
+
return t.filter((e) => e.role !== "tool" && !e.content.startsWith("[Client Tool Result:")).map((e, s) => ({
|
|
241
|
+
id: `history-${s}`,
|
|
242
|
+
content: this.parseContent(e.content),
|
|
243
|
+
role: e.role === "assistant" ? "assistant" : "user",
|
|
283
244
|
timestamp: /* @__PURE__ */ new Date()
|
|
284
245
|
}));
|
|
285
246
|
}
|
|
286
247
|
/**
|
|
287
248
|
* Parse structured content (with thinking/text blocks) and extract just text
|
|
288
249
|
*/
|
|
289
|
-
parseContent(
|
|
250
|
+
parseContent(t) {
|
|
290
251
|
try {
|
|
291
|
-
const
|
|
292
|
-
if (Array.isArray(
|
|
293
|
-
const
|
|
294
|
-
(
|
|
252
|
+
const e = JSON.parse(t);
|
|
253
|
+
if (Array.isArray(e)) {
|
|
254
|
+
const s = e.find(
|
|
255
|
+
(r) => r.type === "text"
|
|
295
256
|
);
|
|
296
|
-
return
|
|
257
|
+
return (s == null ? void 0 : s.text) || t;
|
|
297
258
|
}
|
|
298
259
|
} catch {
|
|
299
260
|
}
|
|
300
|
-
if (
|
|
301
|
-
const
|
|
261
|
+
if (t.includes("'type': 'text'")) {
|
|
262
|
+
const e = t.match(
|
|
302
263
|
/\{'text':\s*'((?:[^'\\]|\\.)*)'\s*,\s*'type':\s*'text'/
|
|
303
264
|
);
|
|
304
|
-
if (
|
|
305
|
-
return
|
|
306
|
-
|
|
265
|
+
if (e)
|
|
266
|
+
return e[1].replace(/\\n/g, `
|
|
267
|
+
`).replace(/\\'/g, "'");
|
|
307
268
|
}
|
|
308
|
-
return
|
|
269
|
+
return t;
|
|
309
270
|
}
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
function parseSSEData(data) {
|
|
314
|
-
if (data === "[DONE]") {
|
|
271
|
+
}
|
|
272
|
+
function v(n) {
|
|
273
|
+
if (n === "[DONE]")
|
|
315
274
|
return { type: "done" };
|
|
316
|
-
}
|
|
317
275
|
try {
|
|
318
|
-
const
|
|
319
|
-
switch (
|
|
276
|
+
const t = JSON.parse(n);
|
|
277
|
+
switch (t.type) {
|
|
320
278
|
case "verification_status":
|
|
321
279
|
return {
|
|
322
280
|
type: "verification_status",
|
|
323
|
-
isVerified:
|
|
281
|
+
isVerified: t.is_verified === !0
|
|
324
282
|
};
|
|
325
283
|
case "conversation_id":
|
|
326
284
|
return {
|
|
327
285
|
type: "conversation_id",
|
|
328
|
-
conversationId:
|
|
286
|
+
conversationId: t.conversation_id
|
|
329
287
|
};
|
|
330
288
|
case "thinking":
|
|
331
|
-
|
|
332
|
-
return { type: "thinking_complete" };
|
|
333
|
-
}
|
|
334
|
-
return null;
|
|
289
|
+
return t.status === "complete" ? { type: "thinking_complete" } : null;
|
|
335
290
|
case "thinking_token":
|
|
336
291
|
return {
|
|
337
292
|
type: "thinking",
|
|
338
|
-
content:
|
|
293
|
+
content: t.content || ""
|
|
339
294
|
};
|
|
340
295
|
case "content":
|
|
341
296
|
return {
|
|
342
297
|
type: "content",
|
|
343
|
-
text:
|
|
298
|
+
text: t.content || "",
|
|
344
299
|
accumulated: ""
|
|
345
300
|
// Will be set by caller
|
|
346
301
|
};
|
|
347
302
|
case "citations":
|
|
348
303
|
return {
|
|
349
304
|
type: "citations",
|
|
350
|
-
citations:
|
|
305
|
+
citations: t.citations
|
|
351
306
|
};
|
|
352
307
|
case "error":
|
|
353
308
|
return {
|
|
354
309
|
type: "error",
|
|
355
|
-
message:
|
|
310
|
+
message: t.message || "Unknown error"
|
|
356
311
|
};
|
|
357
312
|
case "tool_call_start":
|
|
358
313
|
return {
|
|
359
314
|
type: "tool_call_start",
|
|
360
|
-
toolName:
|
|
361
|
-
arguments:
|
|
315
|
+
toolName: t.tool_name,
|
|
316
|
+
arguments: t.arguments || {}
|
|
362
317
|
};
|
|
363
318
|
case "tool_call_complete":
|
|
364
319
|
return {
|
|
365
320
|
type: "tool_call_complete",
|
|
366
|
-
toolName:
|
|
367
|
-
success:
|
|
321
|
+
toolName: t.tool_name,
|
|
322
|
+
success: t.success
|
|
368
323
|
};
|
|
369
324
|
case "client_tool_call":
|
|
370
325
|
return {
|
|
371
326
|
type: "client_tool_call",
|
|
372
|
-
toolName:
|
|
373
|
-
arguments:
|
|
327
|
+
toolName: t.tool_name,
|
|
328
|
+
arguments: t.arguments || {}
|
|
374
329
|
};
|
|
375
330
|
case "workflow_started":
|
|
376
331
|
return {
|
|
377
332
|
type: "workflow_started",
|
|
378
|
-
name:
|
|
379
|
-
todos:
|
|
333
|
+
name: t.name,
|
|
334
|
+
todos: t.todos
|
|
380
335
|
};
|
|
381
336
|
case "todo_updated":
|
|
382
337
|
return {
|
|
383
338
|
type: "workflow_todo_updated",
|
|
384
|
-
todoId:
|
|
385
|
-
status:
|
|
339
|
+
todoId: t.id,
|
|
340
|
+
status: t.status
|
|
386
341
|
};
|
|
387
342
|
case "workflow_ended":
|
|
388
343
|
return { type: "workflow_ended" };
|
|
@@ -392,99 +347,65 @@ function parseSSEData(data) {
|
|
|
392
347
|
return null;
|
|
393
348
|
}
|
|
394
349
|
} catch {
|
|
395
|
-
console.error("[Crow] Failed to parse SSE data:",
|
|
396
|
-
return null;
|
|
350
|
+
return console.error("[Crow] Failed to parse SSE data:", n), null;
|
|
397
351
|
}
|
|
398
352
|
}
|
|
399
|
-
function*
|
|
400
|
-
const
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
}
|
|
405
|
-
}
|
|
353
|
+
function* I(n) {
|
|
354
|
+
const t = n.split(`
|
|
355
|
+
`);
|
|
356
|
+
for (const e of t)
|
|
357
|
+
e.startsWith("data: ") && (yield e.slice(6).trim());
|
|
406
358
|
}
|
|
407
|
-
async function*
|
|
408
|
-
|
|
409
|
-
|
|
359
|
+
async function* M(n, t) {
|
|
360
|
+
var i;
|
|
361
|
+
const e = (i = n.body) == null ? void 0 : i.getReader();
|
|
362
|
+
if (!e)
|
|
410
363
|
throw new Error("Response body is not readable");
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
let accumulatedContent = "";
|
|
364
|
+
const s = new TextDecoder();
|
|
365
|
+
let r = "";
|
|
414
366
|
try {
|
|
415
|
-
|
|
416
|
-
if (
|
|
417
|
-
|
|
367
|
+
for (; ; ) {
|
|
368
|
+
if (t != null && t.aborted) {
|
|
369
|
+
e.cancel();
|
|
418
370
|
return;
|
|
419
371
|
}
|
|
420
|
-
const { done, value } = await
|
|
421
|
-
if (
|
|
422
|
-
const
|
|
423
|
-
for (const
|
|
424
|
-
const
|
|
425
|
-
if (
|
|
426
|
-
|
|
427
|
-
accumulatedContent += event.text;
|
|
428
|
-
yield { ...event, accumulated: accumulatedContent };
|
|
429
|
-
} else {
|
|
430
|
-
yield event;
|
|
431
|
-
}
|
|
432
|
-
if (event.type === "done") {
|
|
433
|
-
return;
|
|
434
|
-
}
|
|
435
|
-
}
|
|
372
|
+
const { done: l, value: d } = await e.read();
|
|
373
|
+
if (l) break;
|
|
374
|
+
const h = s.decode(d);
|
|
375
|
+
for (const u of I(h)) {
|
|
376
|
+
const c = v(u);
|
|
377
|
+
if (c && (c.type === "content" ? (r += c.text, yield { ...c, accumulated: r }) : yield c, c.type === "done"))
|
|
378
|
+
return;
|
|
436
379
|
}
|
|
437
380
|
}
|
|
438
381
|
} finally {
|
|
439
|
-
|
|
382
|
+
e.releaseLock();
|
|
440
383
|
}
|
|
441
384
|
}
|
|
442
|
-
|
|
443
|
-
// src/defaultTools.ts
|
|
444
|
-
var DEFAULT_TOOLS = {
|
|
385
|
+
const w = {
|
|
445
386
|
/**
|
|
446
387
|
* Refresh the current page in the user's browser
|
|
447
388
|
*/
|
|
448
389
|
refreshPage: async () => {
|
|
449
390
|
try {
|
|
450
|
-
window.location.reload();
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
constructor(config) {
|
|
464
|
-
this.context = {};
|
|
465
|
-
this.abortController = null;
|
|
466
|
-
this.callbacks = {};
|
|
467
|
-
// Message state
|
|
468
|
-
this._messages = [];
|
|
469
|
-
this.messageListeners = /* @__PURE__ */ new Set();
|
|
470
|
-
// Loading state
|
|
471
|
-
this._isLoading = false;
|
|
472
|
-
this.loadingListeners = /* @__PURE__ */ new Set();
|
|
473
|
-
this.config = {
|
|
474
|
-
productId: config.productId,
|
|
475
|
-
apiUrl: config.apiUrl || DEFAULT_API_URL,
|
|
476
|
-
model: config.model || DEFAULT_MODEL
|
|
477
|
-
};
|
|
478
|
-
this.identity = new IdentityManager();
|
|
479
|
-
this.tools = new ToolManager();
|
|
480
|
-
this.conversations = new ConversationManager(
|
|
391
|
+
return window.location.reload(), { status: "success", data: { message: "Page refresh initiated" } };
|
|
392
|
+
} catch (n) {
|
|
393
|
+
return { status: "error", error: String(n) };
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}, S = Object.keys(w), T = "https://api.usecrow.org", $ = "claude-sonnet-4-20250514";
|
|
397
|
+
class E {
|
|
398
|
+
constructor(t) {
|
|
399
|
+
this.context = {}, this.abortController = null, this.callbacks = {}, this._messages = [], this.messageListeners = /* @__PURE__ */ new Set(), this._isLoading = !1, this.loadingListeners = /* @__PURE__ */ new Set(), this.config = {
|
|
400
|
+
productId: t.productId,
|
|
401
|
+
apiUrl: t.apiUrl || T,
|
|
402
|
+
model: t.model || $
|
|
403
|
+
}, this.identity = new _(), this.tools = new k(), this.conversations = new b(
|
|
481
404
|
this.config.productId,
|
|
482
405
|
this.config.apiUrl
|
|
483
|
-
)
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
this.identity.subscribe((state) => {
|
|
487
|
-
this.callbacks.onVerificationStatus?.(state.isVerified);
|
|
406
|
+
), this.tools.register(w), console.log("[Crow] Default tools registered:", S.join(", ")), this.identity.subscribe((e) => {
|
|
407
|
+
var s, r;
|
|
408
|
+
(r = (s = this.callbacks).onVerificationStatus) == null || r.call(s, e.isVerified);
|
|
488
409
|
});
|
|
489
410
|
}
|
|
490
411
|
// ============================================================================
|
|
@@ -508,8 +429,8 @@ var CrowClient = class {
|
|
|
508
429
|
get model() {
|
|
509
430
|
return this.config.model;
|
|
510
431
|
}
|
|
511
|
-
set model(
|
|
512
|
-
this.config.model =
|
|
432
|
+
set model(t) {
|
|
433
|
+
this.config.model = t;
|
|
513
434
|
}
|
|
514
435
|
// ============================================================================
|
|
515
436
|
// Event Callbacks
|
|
@@ -517,8 +438,8 @@ var CrowClient = class {
|
|
|
517
438
|
/**
|
|
518
439
|
* Register event callbacks
|
|
519
440
|
*/
|
|
520
|
-
on(
|
|
521
|
-
this.callbacks = { ...this.callbacks, ...
|
|
441
|
+
on(t) {
|
|
442
|
+
this.callbacks = { ...this.callbacks, ...t };
|
|
522
443
|
}
|
|
523
444
|
// ============================================================================
|
|
524
445
|
// Identity
|
|
@@ -526,15 +447,14 @@ var CrowClient = class {
|
|
|
526
447
|
/**
|
|
527
448
|
* Identify the current user with a JWT token
|
|
528
449
|
*/
|
|
529
|
-
identify(
|
|
530
|
-
this.identity.identify(
|
|
450
|
+
identify(t) {
|
|
451
|
+
this.identity.identify(t);
|
|
531
452
|
}
|
|
532
453
|
/**
|
|
533
454
|
* Reset user identity (call on logout)
|
|
534
455
|
*/
|
|
535
456
|
resetUser() {
|
|
536
|
-
this.identity.reset();
|
|
537
|
-
this.clearMessages();
|
|
457
|
+
this.identity.reset(), this.clearMessages();
|
|
538
458
|
}
|
|
539
459
|
/**
|
|
540
460
|
* Check if user is identified
|
|
@@ -554,14 +474,14 @@ var CrowClient = class {
|
|
|
554
474
|
/**
|
|
555
475
|
* Register client-side tool handlers
|
|
556
476
|
*/
|
|
557
|
-
registerTools(
|
|
558
|
-
this.tools.register(
|
|
477
|
+
registerTools(t) {
|
|
478
|
+
this.tools.register(t);
|
|
559
479
|
}
|
|
560
480
|
/**
|
|
561
481
|
* Unregister a tool handler
|
|
562
482
|
*/
|
|
563
|
-
unregisterTool(
|
|
564
|
-
this.tools.unregister(
|
|
483
|
+
unregisterTool(t) {
|
|
484
|
+
this.tools.unregister(t);
|
|
565
485
|
}
|
|
566
486
|
/**
|
|
567
487
|
* Get list of registered tool names
|
|
@@ -575,8 +495,8 @@ var CrowClient = class {
|
|
|
575
495
|
/**
|
|
576
496
|
* Set context data to be sent with messages
|
|
577
497
|
*/
|
|
578
|
-
setContext(
|
|
579
|
-
this.context = { ...this.context, ...
|
|
498
|
+
setContext(t) {
|
|
499
|
+
this.context = { ...this.context, ...t };
|
|
580
500
|
}
|
|
581
501
|
/**
|
|
582
502
|
* Clear context data
|
|
@@ -602,58 +522,49 @@ var CrowClient = class {
|
|
|
602
522
|
/**
|
|
603
523
|
* Subscribe to message changes
|
|
604
524
|
*/
|
|
605
|
-
onMessages(
|
|
606
|
-
this.messageListeners.add(
|
|
607
|
-
return () => this.messageListeners.delete(callback);
|
|
525
|
+
onMessages(t) {
|
|
526
|
+
return this.messageListeners.add(t), () => this.messageListeners.delete(t);
|
|
608
527
|
}
|
|
609
528
|
/**
|
|
610
529
|
* Subscribe to loading state changes
|
|
611
530
|
*/
|
|
612
|
-
onLoading(
|
|
613
|
-
this.loadingListeners.add(
|
|
614
|
-
return () => this.loadingListeners.delete(callback);
|
|
531
|
+
onLoading(t) {
|
|
532
|
+
return this.loadingListeners.add(t), () => this.loadingListeners.delete(t);
|
|
615
533
|
}
|
|
616
534
|
/**
|
|
617
535
|
* Clear all messages and start new conversation
|
|
618
536
|
*/
|
|
619
537
|
clearMessages() {
|
|
620
|
-
this._messages = [];
|
|
621
|
-
this.conversations.clear();
|
|
622
|
-
this.notifyMessages();
|
|
538
|
+
this._messages = [], this.conversations.clear(), this.notifyMessages();
|
|
623
539
|
}
|
|
624
540
|
/**
|
|
625
541
|
* Load messages from history
|
|
626
542
|
*/
|
|
627
|
-
loadMessages(
|
|
628
|
-
this._messages =
|
|
629
|
-
this.notifyMessages();
|
|
543
|
+
loadMessages(t) {
|
|
544
|
+
this._messages = t, this.notifyMessages();
|
|
630
545
|
}
|
|
631
546
|
notifyMessages() {
|
|
632
|
-
const
|
|
633
|
-
for (const
|
|
634
|
-
|
|
635
|
-
}
|
|
547
|
+
const t = this.messages;
|
|
548
|
+
for (const e of this.messageListeners)
|
|
549
|
+
e(t);
|
|
636
550
|
}
|
|
637
|
-
setLoading(
|
|
638
|
-
this._isLoading =
|
|
639
|
-
for (const
|
|
640
|
-
|
|
641
|
-
}
|
|
551
|
+
setLoading(t) {
|
|
552
|
+
this._isLoading = t;
|
|
553
|
+
for (const e of this.loadingListeners)
|
|
554
|
+
e(t);
|
|
642
555
|
}
|
|
643
|
-
addMessage(
|
|
644
|
-
|
|
645
|
-
this.notifyMessages();
|
|
646
|
-
this.callbacks.onMessage?.(message);
|
|
556
|
+
addMessage(t) {
|
|
557
|
+
var e, s;
|
|
558
|
+
this._messages = [...this._messages, t], this.notifyMessages(), (s = (e = this.callbacks).onMessage) == null || s.call(e, t);
|
|
647
559
|
}
|
|
648
|
-
updateMessage(
|
|
560
|
+
updateMessage(t, e) {
|
|
561
|
+
var s, r;
|
|
649
562
|
this._messages = this._messages.map(
|
|
650
|
-
(
|
|
651
|
-
);
|
|
652
|
-
this.notifyMessages();
|
|
653
|
-
this.callbacks.onMessageUpdate?.(id, updates);
|
|
563
|
+
(i) => i.id === t ? { ...i, ...e } : i
|
|
564
|
+
), this.notifyMessages(), (r = (s = this.callbacks).onMessageUpdate) == null || r.call(s, t, e);
|
|
654
565
|
}
|
|
655
|
-
generateMessageId(
|
|
656
|
-
return `${
|
|
566
|
+
generateMessageId(t) {
|
|
567
|
+
return `${t}-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
|
|
657
568
|
}
|
|
658
569
|
// ============================================================================
|
|
659
570
|
// Conversations
|
|
@@ -667,37 +578,29 @@ var CrowClient = class {
|
|
|
667
578
|
/**
|
|
668
579
|
* Set current conversation ID
|
|
669
580
|
*/
|
|
670
|
-
set conversationId(
|
|
671
|
-
this.conversations.setCurrentId(
|
|
581
|
+
set conversationId(t) {
|
|
582
|
+
this.conversations.setCurrentId(t);
|
|
672
583
|
}
|
|
673
584
|
/**
|
|
674
585
|
* Get list of conversations for verified user
|
|
675
586
|
*/
|
|
676
587
|
async getConversations() {
|
|
677
|
-
const
|
|
678
|
-
|
|
679
|
-
console.warn("[Crow] Cannot get conversations: user not identified");
|
|
680
|
-
return [];
|
|
681
|
-
}
|
|
682
|
-
return this.conversations.getConversations(token);
|
|
588
|
+
const t = this.identity.getToken();
|
|
589
|
+
return t ? this.conversations.getConversations(t) : (console.warn("[Crow] Cannot get conversations: user not identified"), []);
|
|
683
590
|
}
|
|
684
591
|
/**
|
|
685
592
|
* Load conversation history
|
|
686
593
|
*/
|
|
687
|
-
async loadHistory(
|
|
688
|
-
const
|
|
689
|
-
|
|
690
|
-
return this.conversations.loadHistory(conversationId, token);
|
|
691
|
-
}
|
|
692
|
-
return this.conversations.loadAnonymousHistory(conversationId);
|
|
594
|
+
async loadHistory(t) {
|
|
595
|
+
const e = this.identity.getToken();
|
|
596
|
+
return e ? this.conversations.loadHistory(t, e) : this.conversations.loadAnonymousHistory(t);
|
|
693
597
|
}
|
|
694
598
|
/**
|
|
695
599
|
* Switch to a different conversation
|
|
696
600
|
*/
|
|
697
|
-
async switchConversation(
|
|
698
|
-
const
|
|
699
|
-
this.conversations.setCurrentId(
|
|
700
|
-
this.loadMessages(messages);
|
|
601
|
+
async switchConversation(t) {
|
|
602
|
+
const e = await this.loadHistory(t);
|
|
603
|
+
this.conversations.setCurrentId(t), this.loadMessages(e);
|
|
701
604
|
}
|
|
702
605
|
// ============================================================================
|
|
703
606
|
// Messaging
|
|
@@ -706,35 +609,32 @@ var CrowClient = class {
|
|
|
706
609
|
* Send a message and receive streaming response
|
|
707
610
|
* Returns an async generator of stream events
|
|
708
611
|
*/
|
|
709
|
-
async *sendMessage(
|
|
710
|
-
|
|
612
|
+
async *sendMessage(t) {
|
|
613
|
+
var l, d, h, u, c, g, f, p, y, m;
|
|
614
|
+
if (!t.trim())
|
|
711
615
|
return;
|
|
712
|
-
|
|
713
|
-
const userMsgId = this.generateMessageId("user");
|
|
616
|
+
const e = this.generateMessageId("user");
|
|
714
617
|
this.addMessage({
|
|
715
|
-
id:
|
|
716
|
-
content,
|
|
618
|
+
id: e,
|
|
619
|
+
content: t,
|
|
717
620
|
role: "user",
|
|
718
621
|
timestamp: /* @__PURE__ */ new Date()
|
|
719
622
|
});
|
|
720
|
-
const
|
|
623
|
+
const s = this.generateMessageId("assistant");
|
|
721
624
|
this.addMessage({
|
|
722
|
-
id:
|
|
625
|
+
id: s,
|
|
723
626
|
content: "",
|
|
724
627
|
role: "assistant",
|
|
725
628
|
timestamp: /* @__PURE__ */ new Date()
|
|
726
|
-
});
|
|
727
|
-
|
|
728
|
-
this.abortController = new AbortController();
|
|
729
|
-
let accumulatedContent = "";
|
|
730
|
-
let accumulatedThinking = "";
|
|
629
|
+
}), this.setLoading(!0), this.abortController = new AbortController();
|
|
630
|
+
let r = "", i = "";
|
|
731
631
|
try {
|
|
732
|
-
const
|
|
632
|
+
const a = await fetch(`${this.config.apiUrl}/api/chat/message`, {
|
|
733
633
|
method: "POST",
|
|
734
634
|
headers: { "Content-Type": "application/json" },
|
|
735
635
|
body: JSON.stringify({
|
|
736
636
|
product_id: this.config.productId,
|
|
737
|
-
message:
|
|
637
|
+
message: t,
|
|
738
638
|
conversation_id: this.conversations.getCurrentId(),
|
|
739
639
|
identity_token: this.identity.getToken(),
|
|
740
640
|
model: this.config.model,
|
|
@@ -742,99 +642,75 @@ var CrowClient = class {
|
|
|
742
642
|
}),
|
|
743
643
|
signal: this.abortController.signal
|
|
744
644
|
});
|
|
745
|
-
if (!
|
|
746
|
-
throw new Error(`HTTP error: ${
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
switch (event.type) {
|
|
645
|
+
if (!a.ok)
|
|
646
|
+
throw new Error(`HTTP error: ${a.status}`);
|
|
647
|
+
for await (const o of M(a, this.abortController.signal)) {
|
|
648
|
+
switch (o.type) {
|
|
750
649
|
case "content":
|
|
751
|
-
|
|
752
|
-
this.updateMessage(botMsgId, { content: accumulatedContent });
|
|
650
|
+
r = o.accumulated, this.updateMessage(s, { content: r });
|
|
753
651
|
break;
|
|
754
652
|
case "thinking":
|
|
755
|
-
|
|
756
|
-
this.updateMessage(botMsgId, { thinking: accumulatedThinking });
|
|
653
|
+
i += o.content, this.updateMessage(s, { thinking: i });
|
|
757
654
|
break;
|
|
758
655
|
case "thinking_complete":
|
|
759
|
-
this.updateMessage(
|
|
656
|
+
this.updateMessage(s, { thinkingComplete: !0 });
|
|
760
657
|
break;
|
|
761
658
|
case "citations":
|
|
762
|
-
this.updateMessage(
|
|
659
|
+
this.updateMessage(s, { citations: o.citations });
|
|
763
660
|
break;
|
|
764
661
|
case "verification_status":
|
|
765
|
-
this.identity.setVerified(
|
|
662
|
+
this.identity.setVerified(o.isVerified);
|
|
766
663
|
break;
|
|
767
664
|
case "conversation_id":
|
|
768
|
-
this.conversations.setCurrentId(
|
|
665
|
+
this.conversations.setCurrentId(o.conversationId);
|
|
769
666
|
break;
|
|
770
667
|
case "client_tool_call":
|
|
771
|
-
await this.tools.execute(
|
|
772
|
-
this.callbacks.onToolCall?.(event);
|
|
668
|
+
await this.tools.execute(o.toolName, o.arguments), (d = (l = this.callbacks).onToolCall) == null || d.call(l, o);
|
|
773
669
|
break;
|
|
774
670
|
case "tool_call_start":
|
|
775
671
|
case "tool_call_complete":
|
|
776
|
-
this.callbacks.onToolCall
|
|
672
|
+
(u = (h = this.callbacks).onToolCall) == null || u.call(h, o);
|
|
777
673
|
break;
|
|
778
674
|
case "workflow_started":
|
|
779
675
|
case "workflow_todo_updated":
|
|
780
676
|
case "workflow_ended":
|
|
781
677
|
case "workflow_complete_prompt":
|
|
782
|
-
this.callbacks.onWorkflow
|
|
678
|
+
(g = (c = this.callbacks).onWorkflow) == null || g.call(c, o);
|
|
783
679
|
break;
|
|
784
680
|
case "error":
|
|
785
|
-
this.updateMessage(
|
|
786
|
-
this.callbacks.onError?.(new Error(event.message));
|
|
681
|
+
this.updateMessage(s, { content: o.message }), (p = (f = this.callbacks).onError) == null || p.call(f, new Error(o.message));
|
|
787
682
|
break;
|
|
788
683
|
}
|
|
789
|
-
yield
|
|
684
|
+
yield o;
|
|
790
685
|
}
|
|
791
|
-
} catch (
|
|
792
|
-
if (
|
|
793
|
-
|
|
794
|
-
this.updateMessage(botMsgId, { content: accumulatedContent });
|
|
795
|
-
} else {
|
|
796
|
-
this._messages = this._messages.filter((msg) => msg.id !== botMsgId);
|
|
797
|
-
this.notifyMessages();
|
|
798
|
-
}
|
|
686
|
+
} catch (a) {
|
|
687
|
+
if (a instanceof Error && a.name === "AbortError") {
|
|
688
|
+
r ? this.updateMessage(s, { content: r }) : (this._messages = this._messages.filter((o) => o.id !== s), this.notifyMessages());
|
|
799
689
|
return;
|
|
800
690
|
}
|
|
801
|
-
console.error("[Crow] Error:",
|
|
802
|
-
this.updateMessage(botMsgId, {
|
|
691
|
+
console.error("[Crow] Error:", a), this.updateMessage(s, {
|
|
803
692
|
content: "Sorry, I encountered an error. Please try again."
|
|
804
|
-
});
|
|
805
|
-
this.callbacks.onError?.(error instanceof Error ? error : new Error(String(error)));
|
|
693
|
+
}), (m = (y = this.callbacks).onError) == null || m.call(y, a instanceof Error ? a : new Error(String(a)));
|
|
806
694
|
} finally {
|
|
807
|
-
this.setLoading(
|
|
808
|
-
this.abortController = null;
|
|
695
|
+
this.setLoading(!1), this.abortController = null;
|
|
809
696
|
}
|
|
810
697
|
}
|
|
811
698
|
/**
|
|
812
699
|
* Send a message and wait for complete response (non-streaming)
|
|
813
700
|
*/
|
|
814
|
-
async send(
|
|
815
|
-
let
|
|
816
|
-
for await (const
|
|
817
|
-
if (
|
|
701
|
+
async send(t) {
|
|
702
|
+
let e = null;
|
|
703
|
+
for await (const r of this.sendMessage(t))
|
|
704
|
+
if (r.type === "done")
|
|
818
705
|
break;
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
const messages = this.messages;
|
|
822
|
-
if (messages.length > 0) {
|
|
823
|
-
lastMessage = messages[messages.length - 1];
|
|
824
|
-
if (lastMessage.role === "assistant") {
|
|
825
|
-
return lastMessage;
|
|
826
|
-
}
|
|
827
|
-
}
|
|
828
|
-
return null;
|
|
706
|
+
const s = this.messages;
|
|
707
|
+
return s.length > 0 && (e = s[s.length - 1], e.role === "assistant") ? e : null;
|
|
829
708
|
}
|
|
830
709
|
/**
|
|
831
710
|
* Stop current generation
|
|
832
711
|
*/
|
|
833
712
|
stop() {
|
|
834
|
-
|
|
835
|
-
this.abortController.abort();
|
|
836
|
-
this.setLoading(false);
|
|
837
|
-
}
|
|
713
|
+
this.abortController && (this.abortController.abort(), this.setLoading(!1));
|
|
838
714
|
}
|
|
839
715
|
// ============================================================================
|
|
840
716
|
// Cleanup
|
|
@@ -843,254 +719,18 @@ var CrowClient = class {
|
|
|
843
719
|
* Destroy the client and clean up resources
|
|
844
720
|
*/
|
|
845
721
|
destroy() {
|
|
846
|
-
this.stop();
|
|
847
|
-
this.messageListeners.clear();
|
|
848
|
-
this.loadingListeners.clear();
|
|
849
|
-
}
|
|
850
|
-
};
|
|
851
|
-
var PageControllerModule = null;
|
|
852
|
-
async function getPageController() {
|
|
853
|
-
if (!PageControllerModule) {
|
|
854
|
-
try {
|
|
855
|
-
PageControllerModule = await import('@page-agent/page-controller');
|
|
856
|
-
} catch (error) {
|
|
857
|
-
throw new Error(
|
|
858
|
-
'PageController not available. Either import from "@usecrow/client/browser" or install @page-agent/page-controller as a dependency.'
|
|
859
|
-
);
|
|
860
|
-
}
|
|
722
|
+
this.stop(), this.messageListeners.clear(), this.loadingListeners.clear();
|
|
861
723
|
}
|
|
862
|
-
return PageControllerModule.PageController;
|
|
863
724
|
}
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
if (this.pageController) {
|
|
876
|
-
return this.pageController;
|
|
877
|
-
}
|
|
878
|
-
try {
|
|
879
|
-
const PageController = await getPageController();
|
|
880
|
-
this.pageController = new PageController({
|
|
881
|
-
enableMask: true,
|
|
882
|
-
viewportExpansion: 500,
|
|
883
|
-
highlightLabelOpacity: 0,
|
|
884
|
-
// Hide numbered labels from users
|
|
885
|
-
highlightOpacity: 0
|
|
886
|
-
// Hide highlight boxes from users
|
|
887
|
-
});
|
|
888
|
-
await this.pageController.showMask();
|
|
889
|
-
const mask = this.pageController.mask;
|
|
890
|
-
if (mask?.wrapper) {
|
|
891
|
-
mask.wrapper.style.pointerEvents = "none";
|
|
892
|
-
}
|
|
893
|
-
console.log("[CrowBrowserUse] PageController initialized with non-blocking pointer");
|
|
894
|
-
return this.pageController;
|
|
895
|
-
} catch (error) {
|
|
896
|
-
console.error("[CrowBrowserUse] Failed to import @page-agent/page-controller:", error);
|
|
897
|
-
throw new Error(
|
|
898
|
-
"Failed to initialize browser automation. Make sure @page-agent/page-controller is installed."
|
|
899
|
-
);
|
|
900
|
-
}
|
|
901
|
-
}
|
|
902
|
-
/**
|
|
903
|
-
* Execute a browser automation task
|
|
904
|
-
*/
|
|
905
|
-
async execute(task) {
|
|
906
|
-
console.log("[CrowBrowserUse] Starting task:", task);
|
|
907
|
-
try {
|
|
908
|
-
const controller = await this.initPageController();
|
|
909
|
-
const startResponse = await this.startSession(task);
|
|
910
|
-
this.sessionId = startResponse.session_id;
|
|
911
|
-
this.maxSteps = startResponse.max_steps;
|
|
912
|
-
console.log("[CrowBrowserUse] Session started:", this.sessionId);
|
|
913
|
-
let stepCount = 0;
|
|
914
|
-
let lastActionResult;
|
|
915
|
-
while (stepCount < this.maxSteps) {
|
|
916
|
-
stepCount++;
|
|
917
|
-
const browserState = await controller.getBrowserState();
|
|
918
|
-
const stepResponse = await this.processStep(browserState, lastActionResult);
|
|
919
|
-
if (stepResponse.done) {
|
|
920
|
-
console.log("[CrowBrowserUse] Task completed:", stepResponse.message);
|
|
921
|
-
await this.cleanup();
|
|
922
|
-
return {
|
|
923
|
-
status: stepResponse.success ? "success" : "error",
|
|
924
|
-
data: {
|
|
925
|
-
message: stepResponse.message,
|
|
926
|
-
steps: stepCount
|
|
927
|
-
},
|
|
928
|
-
error: stepResponse.success ? void 0 : stepResponse.message
|
|
929
|
-
};
|
|
930
|
-
}
|
|
931
|
-
if (stepResponse.error) {
|
|
932
|
-
console.error("[CrowBrowserUse] Error:", stepResponse.error);
|
|
933
|
-
await this.cleanup();
|
|
934
|
-
return {
|
|
935
|
-
status: "error",
|
|
936
|
-
error: stepResponse.error
|
|
937
|
-
};
|
|
938
|
-
}
|
|
939
|
-
if (stepResponse.action) {
|
|
940
|
-
lastActionResult = await this.executeAction(controller, stepResponse.action);
|
|
941
|
-
console.log(`[CrowBrowserUse] Step ${stepCount}:`, lastActionResult);
|
|
942
|
-
}
|
|
943
|
-
if (stepResponse.reflection) {
|
|
944
|
-
console.log("[CrowBrowserUse] Reflection:", stepResponse.reflection.next_goal);
|
|
945
|
-
}
|
|
946
|
-
}
|
|
947
|
-
await this.cleanup();
|
|
948
|
-
return {
|
|
949
|
-
status: "error",
|
|
950
|
-
error: `Task incomplete after ${this.maxSteps} steps`
|
|
951
|
-
};
|
|
952
|
-
} catch (error) {
|
|
953
|
-
console.error("[CrowBrowserUse] Error:", error);
|
|
954
|
-
await this.cleanup();
|
|
955
|
-
return {
|
|
956
|
-
status: "error",
|
|
957
|
-
error: error instanceof Error ? error.message : String(error)
|
|
958
|
-
};
|
|
959
|
-
}
|
|
960
|
-
}
|
|
961
|
-
/**
|
|
962
|
-
* Start a browser-use session on the server
|
|
963
|
-
*/
|
|
964
|
-
async startSession(task) {
|
|
965
|
-
const response = await fetch(`${this.config.apiUrl}/api/browser-use/start`, {
|
|
966
|
-
method: "POST",
|
|
967
|
-
headers: { "Content-Type": "application/json" },
|
|
968
|
-
body: JSON.stringify({
|
|
969
|
-
product_id: this.config.productId,
|
|
970
|
-
task
|
|
971
|
-
})
|
|
972
|
-
});
|
|
973
|
-
if (!response.ok) {
|
|
974
|
-
const error = await response.json().catch(() => ({ detail: "Unknown error" }));
|
|
975
|
-
throw new Error(error.detail || `Failed to start session: ${response.status}`);
|
|
976
|
-
}
|
|
977
|
-
return response.json();
|
|
978
|
-
}
|
|
979
|
-
/**
|
|
980
|
-
* Process a step on the server
|
|
981
|
-
*/
|
|
982
|
-
async processStep(browserState, actionResult) {
|
|
983
|
-
const response = await fetch(`${this.config.apiUrl}/api/browser-use/step`, {
|
|
984
|
-
method: "POST",
|
|
985
|
-
headers: { "Content-Type": "application/json" },
|
|
986
|
-
body: JSON.stringify({
|
|
987
|
-
session_id: this.sessionId,
|
|
988
|
-
product_id: this.config.productId,
|
|
989
|
-
browser_state: browserState,
|
|
990
|
-
action_result: actionResult
|
|
991
|
-
})
|
|
992
|
-
});
|
|
993
|
-
if (!response.ok) {
|
|
994
|
-
const error = await response.json().catch(() => ({ detail: "Unknown error" }));
|
|
995
|
-
throw new Error(error.detail || `Failed to process step: ${response.status}`);
|
|
996
|
-
}
|
|
997
|
-
return response.json();
|
|
998
|
-
}
|
|
999
|
-
/**
|
|
1000
|
-
* Execute an action using PageController
|
|
1001
|
-
*/
|
|
1002
|
-
async executeAction(controller, action) {
|
|
1003
|
-
const actionName = Object.keys(action)[0];
|
|
1004
|
-
const actionParams = action[actionName];
|
|
1005
|
-
try {
|
|
1006
|
-
switch (actionName) {
|
|
1007
|
-
case "click_element_by_index": {
|
|
1008
|
-
const result = await controller.clickElement(actionParams.index);
|
|
1009
|
-
return result.message;
|
|
1010
|
-
}
|
|
1011
|
-
case "input_text": {
|
|
1012
|
-
const result = await controller.inputText(
|
|
1013
|
-
actionParams.index,
|
|
1014
|
-
actionParams.text
|
|
1015
|
-
);
|
|
1016
|
-
return result.message;
|
|
1017
|
-
}
|
|
1018
|
-
case "select_dropdown_option": {
|
|
1019
|
-
const result = await controller.selectOption(
|
|
1020
|
-
actionParams.index,
|
|
1021
|
-
actionParams.text
|
|
1022
|
-
);
|
|
1023
|
-
return result.message;
|
|
1024
|
-
}
|
|
1025
|
-
case "scroll": {
|
|
1026
|
-
const result = await controller.scroll({
|
|
1027
|
-
down: actionParams.down,
|
|
1028
|
-
numPages: actionParams.num_pages,
|
|
1029
|
-
pixels: actionParams.pixels,
|
|
1030
|
-
index: actionParams.index
|
|
1031
|
-
});
|
|
1032
|
-
return result.message;
|
|
1033
|
-
}
|
|
1034
|
-
case "scroll_horizontally": {
|
|
1035
|
-
const result = await controller.scrollHorizontally({
|
|
1036
|
-
right: actionParams.right,
|
|
1037
|
-
pixels: actionParams.pixels,
|
|
1038
|
-
index: actionParams.index
|
|
1039
|
-
});
|
|
1040
|
-
return result.message;
|
|
1041
|
-
}
|
|
1042
|
-
case "wait": {
|
|
1043
|
-
const seconds = actionParams.seconds || 1;
|
|
1044
|
-
await new Promise((resolve) => setTimeout(resolve, seconds * 1e3));
|
|
1045
|
-
return `Waited ${seconds} seconds`;
|
|
1046
|
-
}
|
|
1047
|
-
case "done": {
|
|
1048
|
-
return "Task completed";
|
|
1049
|
-
}
|
|
1050
|
-
default:
|
|
1051
|
-
return `Unknown action: ${actionName}`;
|
|
1052
|
-
}
|
|
1053
|
-
} catch (error) {
|
|
1054
|
-
return `Action failed: ${error instanceof Error ? error.message : String(error)}`;
|
|
1055
|
-
}
|
|
1056
|
-
}
|
|
1057
|
-
/**
|
|
1058
|
-
* Cleanup resources
|
|
1059
|
-
*/
|
|
1060
|
-
async cleanup() {
|
|
1061
|
-
if (this.pageController) {
|
|
1062
|
-
try {
|
|
1063
|
-
await this.pageController.hideMask();
|
|
1064
|
-
await this.pageController.cleanUpHighlights();
|
|
1065
|
-
this.pageController.dispose();
|
|
1066
|
-
} catch (error) {
|
|
1067
|
-
console.warn("[CrowBrowserUse] Cleanup error:", error);
|
|
1068
|
-
}
|
|
1069
|
-
this.pageController = null;
|
|
1070
|
-
}
|
|
1071
|
-
if (this.sessionId) {
|
|
1072
|
-
try {
|
|
1073
|
-
await fetch(`${this.config.apiUrl}/api/browser-use/end`, {
|
|
1074
|
-
method: "POST",
|
|
1075
|
-
headers: { "Content-Type": "application/json" },
|
|
1076
|
-
body: JSON.stringify({
|
|
1077
|
-
session_id: this.sessionId,
|
|
1078
|
-
product_id: this.config.productId
|
|
1079
|
-
})
|
|
1080
|
-
});
|
|
1081
|
-
} catch (error) {
|
|
1082
|
-
}
|
|
1083
|
-
this.sessionId = null;
|
|
1084
|
-
}
|
|
1085
|
-
}
|
|
1086
|
-
/**
|
|
1087
|
-
* Stop the current task
|
|
1088
|
-
*/
|
|
1089
|
-
async stop() {
|
|
1090
|
-
await this.cleanup();
|
|
1091
|
-
}
|
|
725
|
+
export {
|
|
726
|
+
b as ConversationManager,
|
|
727
|
+
x as CrowBrowserUse,
|
|
728
|
+
E as CrowClient,
|
|
729
|
+
w as DEFAULT_TOOLS,
|
|
730
|
+
S as DEFAULT_TOOL_NAMES,
|
|
731
|
+
_ as IdentityManager,
|
|
732
|
+
k as ToolManager,
|
|
733
|
+
I as parseSSEChunk,
|
|
734
|
+
v as parseSSEData,
|
|
735
|
+
M as streamResponse
|
|
1092
736
|
};
|
|
1093
|
-
|
|
1094
|
-
export { ConversationManager, CrowBrowserUse, CrowClient, DEFAULT_TOOLS, DEFAULT_TOOL_NAMES, IdentityManager, ToolManager, parseSSEChunk, parseSSEData, streamResponse };
|
|
1095
|
-
//# sourceMappingURL=index.js.map
|
|
1096
|
-
//# sourceMappingURL=index.js.map
|