sparkecoder 0.1.67 → 0.1.69
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/agent/index.d.ts +3 -3
- package/dist/agent/index.js +173 -19
- package/dist/agent/index.js.map +1 -1
- package/dist/cli.js +307 -64
- package/dist/cli.js.map +1 -1
- package/dist/db/index.d.ts +2 -2
- package/dist/{index-DHyVVhJY.d.ts → index-DqaHLgSC.d.ts} +20 -19
- package/dist/index.d.ts +5 -5
- package/dist/index.js +307 -64
- package/dist/index.js.map +1 -1
- package/dist/{schema-XcP0dedO.d.ts → schema-Bq4tID-f.d.ts} +3 -3
- package/dist/{search-CCffrVJE.d.ts → search-BRnGaIl-.d.ts} +7 -7
- package/dist/server/index.js +307 -64
- package/dist/server/index.js.map +1 -1
- package/dist/tools/index.d.ts +2 -2
- package/package.json +1 -1
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/standalone/web/.next/BUILD_ID +1 -1
- package/web/.next/standalone/web/.next/build-manifest.json +2 -2
- package/web/.next/standalone/web/.next/prerender-manifest.json +3 -3
- package/web/.next/standalone/web/.next/server/app/(main)/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/app/(main)/session/[id]/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.html +2 -2
- package/web/.next/standalone/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.html +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.html +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/installation.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.html +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/skills.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.html +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/tools.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.html +2 -2
- package/web/.next/standalone/web/.next/server/app/docs.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/docs/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/docs.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/embed/[id]/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/app/index.html +1 -1
- package/web/.next/standalone/web/.next/server/app/index.rsc +3 -3
- package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p/__PAGE__.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/index.segments/_full.segment.rsc +3 -3
- package/web/.next/standalone/web/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/chunks/ssr/[root-of-the-server]__c71f29f9._.js +3 -3
- package/web/.next/standalone/web/.next/server/chunks/ssr/web_2b3a5919._.js +1 -1
- package/web/.next/standalone/web/.next/server/chunks/ssr/web_38156da8._.js +1 -1
- package/web/.next/standalone/web/.next/server/pages/404.html +1 -1
- package/web/.next/standalone/web/.next/server/pages/500.html +2 -2
- package/web/.next/standalone/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/server-reference-manifest.json +1 -1
- package/web/.next/standalone/web/.next/static/chunks/{4e673433173ad456.js → 2cafc7cb79454d33.js} +3 -3
- package/web/.next/standalone/web/.next/static/chunks/{515f0c0bd6087843.js → b6ec74cad9ffd3ee.js} +3 -3
- package/web/.next/{static/chunks/31208ade542a0fcb.js → standalone/web/.next/static/chunks/fc39a194539da104.js} +3 -3
- package/web/.next/{static/chunks/4e673433173ad456.js → standalone/web/.next/static/static/chunks/2cafc7cb79454d33.js} +3 -3
- package/web/.next/standalone/web/.next/static/static/chunks/{515f0c0bd6087843.js → b6ec74cad9ffd3ee.js} +3 -3
- package/web/.next/standalone/web/.next/static/static/chunks/{31208ade542a0fcb.js → fc39a194539da104.js} +3 -3
- package/web/.next/standalone/web/src/components/chat-interface.tsx +14 -0
- package/web/.next/standalone/web/src/lib/api.ts +89 -16
- package/web/.next/{standalone/web/.next/static/static/chunks/4e673433173ad456.js → static/chunks/2cafc7cb79454d33.js} +3 -3
- package/web/.next/static/chunks/{515f0c0bd6087843.js → b6ec74cad9ffd3ee.js} +3 -3
- package/web/.next/{standalone/web/.next/static/chunks/31208ade542a0fcb.js → static/chunks/fc39a194539da104.js} +3 -3
- /package/web/.next/standalone/web/.next/static/{static/tZkod5afiOX7T9AkN1yPO → XB638PEDChQhwk6wSMrSh}/_buildManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/{static/tZkod5afiOX7T9AkN1yPO → XB638PEDChQhwk6wSMrSh}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/standalone/web/.next/static/{static/tZkod5afiOX7T9AkN1yPO → XB638PEDChQhwk6wSMrSh}/_ssgManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/{tZkod5afiOX7T9AkN1yPO → static/XB638PEDChQhwk6wSMrSh}/_buildManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/{tZkod5afiOX7T9AkN1yPO → static/XB638PEDChQhwk6wSMrSh}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/standalone/web/.next/static/{tZkod5afiOX7T9AkN1yPO → static/XB638PEDChQhwk6wSMrSh}/_ssgManifest.js +0 -0
- /package/web/.next/static/{tZkod5afiOX7T9AkN1yPO → XB638PEDChQhwk6wSMrSh}/_buildManifest.js +0 -0
- /package/web/.next/static/{tZkod5afiOX7T9AkN1yPO → XB638PEDChQhwk6wSMrSh}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{tZkod5afiOX7T9AkN1yPO → XB638PEDChQhwk6wSMrSh}/_ssgManifest.js +0 -0
package/dist/agent/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import 'ai';
|
|
2
|
-
import '../schema-
|
|
3
|
-
export { A as Agent, a as AgentOptions, b as AgentRunOptions, c as AgentStreamResult, C as ContextManager, M as MessageAttachment, d as buildSystemPrompt, e as buildTaskPromptAddendum } from '../index-
|
|
4
|
-
import '../search-
|
|
2
|
+
import '../schema-Bq4tID-f.js';
|
|
3
|
+
export { A as Agent, a as AgentOptions, b as AgentRunOptions, c as AgentStreamResult, C as ContextManager, M as MessageAttachment, d as buildSystemPrompt, e as buildTaskPromptAddendum } from '../index-DqaHLgSC.js';
|
|
4
|
+
import '../search-BRnGaIl-.js';
|
|
5
5
|
import 'drizzle-orm/sqlite-core';
|
|
6
6
|
import 'zod';
|
package/dist/agent/index.js
CHANGED
|
@@ -1417,10 +1417,15 @@ import WebSocket from "ws";
|
|
|
1417
1417
|
import { EventEmitter } from "events";
|
|
1418
1418
|
function getOrCreateProxy(sessionId, port) {
|
|
1419
1419
|
const existing = activeProxies.get(sessionId);
|
|
1420
|
-
if (existing)
|
|
1420
|
+
if (existing) {
|
|
1421
|
+
console.log(`[BROWSER-WS] Reusing existing proxy for session ${sessionId} (connected=${existing.connected})`);
|
|
1422
|
+
return existing;
|
|
1423
|
+
}
|
|
1424
|
+
console.log(`[BROWSER-WS] Creating new proxy for session ${sessionId} on port ${port} (active proxies: ${activeProxies.size})`);
|
|
1421
1425
|
const proxy = new BrowserStreamProxy(port);
|
|
1422
1426
|
activeProxies.set(sessionId, proxy);
|
|
1423
1427
|
proxy.on("close", () => {
|
|
1428
|
+
console.log(`[BROWSER-WS] Proxy closed for session ${sessionId}, removing from registry`);
|
|
1424
1429
|
activeProxies.delete(sessionId);
|
|
1425
1430
|
});
|
|
1426
1431
|
proxy.connect();
|
|
@@ -1432,8 +1437,11 @@ function getProxy(sessionId) {
|
|
|
1432
1437
|
function destroyProxy(sessionId) {
|
|
1433
1438
|
const proxy = activeProxies.get(sessionId);
|
|
1434
1439
|
if (proxy) {
|
|
1440
|
+
console.log(`[BROWSER-WS] destroyProxy() called for session ${sessionId}`);
|
|
1435
1441
|
proxy.destroy();
|
|
1436
1442
|
activeProxies.delete(sessionId);
|
|
1443
|
+
} else {
|
|
1444
|
+
console.log(`[BROWSER-WS] destroyProxy() called but no proxy exists for session ${sessionId}`);
|
|
1437
1445
|
}
|
|
1438
1446
|
}
|
|
1439
1447
|
var RECONNECT_DELAY_MS, MAX_RECONNECT_ATTEMPTS, FRAME_THROTTLE_MS, BrowserStreamProxy, activeProxies;
|
|
@@ -1464,18 +1472,22 @@ var init_stream_proxy = __esm({
|
|
|
1464
1472
|
}
|
|
1465
1473
|
connect() {
|
|
1466
1474
|
if (this.destroyed) return;
|
|
1475
|
+
console.log(`[BROWSER-WS] connect() called for port ${this.port}`);
|
|
1467
1476
|
this.doConnect();
|
|
1468
1477
|
}
|
|
1469
1478
|
doConnect() {
|
|
1470
1479
|
if (this.destroyed) return;
|
|
1471
1480
|
const url = `ws://localhost:${this.port}`;
|
|
1481
|
+
console.log(`[BROWSER-WS] Attempting WebSocket connection to ${url} (attempt ${this.reconnectAttempts + 1}/${MAX_RECONNECT_ATTEMPTS})`);
|
|
1472
1482
|
try {
|
|
1473
1483
|
this.ws = new WebSocket(url);
|
|
1474
|
-
} catch {
|
|
1484
|
+
} catch (err) {
|
|
1485
|
+
console.warn(`[BROWSER-WS] WebSocket constructor threw for ${url}:`, err);
|
|
1475
1486
|
this.scheduleReconnect();
|
|
1476
1487
|
return;
|
|
1477
1488
|
}
|
|
1478
1489
|
this.ws.on("open", () => {
|
|
1490
|
+
console.log(`[BROWSER-WS] Connected to ${url} (after ${this.reconnectAttempts} retries)`);
|
|
1479
1491
|
this.reconnectAttempts = 0;
|
|
1480
1492
|
this._connected = true;
|
|
1481
1493
|
this.emit("status", {
|
|
@@ -1487,12 +1499,14 @@ var init_stream_proxy = __esm({
|
|
|
1487
1499
|
try {
|
|
1488
1500
|
const msg = JSON.parse(typeof raw === "string" ? raw : raw.toString("utf8"));
|
|
1489
1501
|
this.handleMessage(msg);
|
|
1490
|
-
} catch {
|
|
1502
|
+
} catch (err) {
|
|
1503
|
+
console.warn(`[BROWSER-WS] Malformed message from ${url}:`, err);
|
|
1491
1504
|
}
|
|
1492
1505
|
});
|
|
1493
|
-
this.ws.on("close", () => {
|
|
1506
|
+
this.ws.on("close", (code, reason) => {
|
|
1494
1507
|
const wasConnected = this._connected;
|
|
1495
1508
|
this._connected = false;
|
|
1509
|
+
console.log(`[BROWSER-WS] Connection closed: code=${code} reason="${reason?.toString() || ""}" wasConnected=${wasConnected} destroyed=${this.destroyed}`);
|
|
1496
1510
|
if (wasConnected) {
|
|
1497
1511
|
this.emit("status", { connected: false, screencasting: false });
|
|
1498
1512
|
}
|
|
@@ -1500,14 +1514,26 @@ var init_stream_proxy = __esm({
|
|
|
1500
1514
|
this.scheduleReconnect();
|
|
1501
1515
|
}
|
|
1502
1516
|
});
|
|
1503
|
-
this.ws.on("error", () => {
|
|
1517
|
+
this.ws.on("error", (err) => {
|
|
1518
|
+
console.warn(`[BROWSER-WS] WebSocket error on port ${this.port}:`, err.message);
|
|
1504
1519
|
});
|
|
1505
1520
|
}
|
|
1521
|
+
frameCount = 0;
|
|
1522
|
+
throttledCount = 0;
|
|
1523
|
+
lastFrameLogTime = 0;
|
|
1506
1524
|
handleMessage(msg) {
|
|
1507
1525
|
if (msg.type === "frame") {
|
|
1508
1526
|
const now = Date.now();
|
|
1509
|
-
if (now - this.lastFrameTime < FRAME_THROTTLE_MS)
|
|
1527
|
+
if (now - this.lastFrameTime < FRAME_THROTTLE_MS) {
|
|
1528
|
+
this.throttledCount++;
|
|
1529
|
+
return;
|
|
1530
|
+
}
|
|
1510
1531
|
this.lastFrameTime = now;
|
|
1532
|
+
this.frameCount++;
|
|
1533
|
+
if (now - this.lastFrameLogTime > 5e3) {
|
|
1534
|
+
console.log(`[BROWSER-WS] Frame stats: emitted=${this.frameCount} throttled=${this.throttledCount} listeners=${this.listenerCount("frame")} dataSize=${msg.data?.length ?? 0}`);
|
|
1535
|
+
this.lastFrameLogTime = now;
|
|
1536
|
+
}
|
|
1511
1537
|
const frame = {
|
|
1512
1538
|
data: msg.data,
|
|
1513
1539
|
metadata: msg.metadata ?? {
|
|
@@ -1523,21 +1549,26 @@ var init_stream_proxy = __esm({
|
|
|
1523
1549
|
this._latestFrame = frame;
|
|
1524
1550
|
this.emit("frame", frame);
|
|
1525
1551
|
} else if (msg.type === "status") {
|
|
1552
|
+
console.log(`[BROWSER-WS] Status message received:`, JSON.stringify(msg));
|
|
1526
1553
|
this.emit("status", {
|
|
1527
1554
|
connected: msg.connected ?? true,
|
|
1528
1555
|
screencasting: msg.screencasting ?? true,
|
|
1529
1556
|
viewportWidth: msg.viewportWidth,
|
|
1530
1557
|
viewportHeight: msg.viewportHeight
|
|
1531
1558
|
});
|
|
1559
|
+
} else {
|
|
1560
|
+
console.log(`[BROWSER-WS] Unknown message type: ${msg.type}`);
|
|
1532
1561
|
}
|
|
1533
1562
|
}
|
|
1534
1563
|
scheduleReconnect() {
|
|
1535
1564
|
if (this.destroyed || this.reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {
|
|
1565
|
+
console.log(`[BROWSER-WS] Giving up reconnection: destroyed=${this.destroyed} attempts=${this.reconnectAttempts}/${MAX_RECONNECT_ATTEMPTS}`);
|
|
1536
1566
|
this.emit("close");
|
|
1537
1567
|
return;
|
|
1538
1568
|
}
|
|
1539
1569
|
this.reconnectAttempts++;
|
|
1540
1570
|
const delay = this.reconnectAttempts <= 5 ? RECONNECT_DELAY_MS : RECONNECT_DELAY_MS * (this.reconnectAttempts - 4);
|
|
1571
|
+
console.log(`[BROWSER-WS] Scheduling reconnect in ${delay}ms (attempt ${this.reconnectAttempts}/${MAX_RECONNECT_ATTEMPTS})`);
|
|
1541
1572
|
this.reconnectTimer = setTimeout(() => this.doConnect(), delay);
|
|
1542
1573
|
}
|
|
1543
1574
|
/**
|
|
@@ -1549,6 +1580,7 @@ var init_stream_proxy = __esm({
|
|
|
1549
1580
|
}
|
|
1550
1581
|
}
|
|
1551
1582
|
destroy() {
|
|
1583
|
+
console.log(`[BROWSER-WS] Destroying proxy for port ${this.port} (emitted ${this.frameCount} frames, throttled ${this.throttledCount})`);
|
|
1552
1584
|
this.destroyed = true;
|
|
1553
1585
|
if (this.reconnectTimer) {
|
|
1554
1586
|
clearTimeout(this.reconnectTimer);
|
|
@@ -5922,6 +5954,21 @@ async function sendWebhook(url, event) {
|
|
|
5922
5954
|
}
|
|
5923
5955
|
|
|
5924
5956
|
// src/agent/index.ts
|
|
5957
|
+
var MAX_SSE_FIELD_LENGTH = 8 * 1024;
|
|
5958
|
+
var SSE_PREVIEW_LENGTH = 2 * 1024;
|
|
5959
|
+
function truncateWriteFileInput(input) {
|
|
5960
|
+
const out = { ...input };
|
|
5961
|
+
for (const key of ["content", "old_string", "new_string"]) {
|
|
5962
|
+
const val = out[key];
|
|
5963
|
+
if (typeof val === "string" && val.length > MAX_SSE_FIELD_LENGTH) {
|
|
5964
|
+
out[key] = `${val.slice(0, SSE_PREVIEW_LENGTH)}
|
|
5965
|
+
... (truncated)`;
|
|
5966
|
+
out[`${key}Truncated`] = true;
|
|
5967
|
+
out[`${key}Length`] = val.length;
|
|
5968
|
+
}
|
|
5969
|
+
}
|
|
5970
|
+
return out;
|
|
5971
|
+
}
|
|
5925
5972
|
var approvalResolvers = /* @__PURE__ */ new Map();
|
|
5926
5973
|
var Agent = class _Agent {
|
|
5927
5974
|
session;
|
|
@@ -6165,8 +6212,11 @@ ${prompt}` });
|
|
|
6165
6212
|
};
|
|
6166
6213
|
let taskRecorder = null;
|
|
6167
6214
|
const sessionId = this.session.id;
|
|
6215
|
+
const emit = options.writeSSE;
|
|
6168
6216
|
const bashProgressHandler = (progress) => {
|
|
6169
6217
|
options.onToolProgress?.({ toolName: "bash", data: progress });
|
|
6218
|
+
if (emit) emit(JSON.stringify({ type: "tool-progress", toolName: "bash", data: progress })).catch(() => {
|
|
6219
|
+
});
|
|
6170
6220
|
const port = progress.browserStreamPort;
|
|
6171
6221
|
if (port && progress.status === "started") {
|
|
6172
6222
|
Promise.resolve().then(() => (init_stream_proxy(), stream_proxy_exports)).then(({ getOrCreateProxy: getOrCreateProxy2 }) => {
|
|
@@ -6175,7 +6225,17 @@ ${prompt}` });
|
|
|
6175
6225
|
Promise.resolve().then(() => (init_recorder(), recorder_exports)).then(({ FrameRecorder: FrameRecorder2 }) => {
|
|
6176
6226
|
taskRecorder = new FrameRecorder2(sessionId);
|
|
6177
6227
|
taskRecorder.start();
|
|
6178
|
-
|
|
6228
|
+
});
|
|
6229
|
+
}
|
|
6230
|
+
if (proxy.listenerCount("frame") === 0) {
|
|
6231
|
+
proxy.on("frame", (frame) => {
|
|
6232
|
+
taskRecorder?.addFrame(frame);
|
|
6233
|
+
if (emit) emit(JSON.stringify({ type: "browser-frame", data: frame.data, metadata: frame.metadata })).catch(() => {
|
|
6234
|
+
});
|
|
6235
|
+
});
|
|
6236
|
+
proxy.on("status", (s) => {
|
|
6237
|
+
if (emit) emit(JSON.stringify({ type: "browser-status", ...s })).catch(() => {
|
|
6238
|
+
});
|
|
6179
6239
|
});
|
|
6180
6240
|
}
|
|
6181
6241
|
});
|
|
@@ -6186,8 +6246,16 @@ ${prompt}` });
|
|
|
6186
6246
|
workingDirectory: this.session.workingDirectory,
|
|
6187
6247
|
skillsDirectories: config.resolvedSkillsDirectories,
|
|
6188
6248
|
onBashProgress: bashProgressHandler,
|
|
6189
|
-
onWriteFileProgress:
|
|
6190
|
-
|
|
6249
|
+
onWriteFileProgress: (progress) => {
|
|
6250
|
+
options.onToolProgress?.({ toolName: "write_file", data: progress });
|
|
6251
|
+
if (emit) emit(JSON.stringify({ type: "tool-progress", toolName: "write_file", data: progress })).catch(() => {
|
|
6252
|
+
});
|
|
6253
|
+
},
|
|
6254
|
+
onSearchProgress: (progress) => {
|
|
6255
|
+
options.onToolProgress?.({ toolName: "explore_agent", data: progress });
|
|
6256
|
+
if (emit) emit(JSON.stringify({ type: "tool-progress", toolName: "explore_agent", data: progress })).catch(() => {
|
|
6257
|
+
});
|
|
6258
|
+
},
|
|
6191
6259
|
taskTools: {
|
|
6192
6260
|
outputSchema: options.taskConfig.outputSchema,
|
|
6193
6261
|
onComplete
|
|
@@ -6205,6 +6273,9 @@ ${prompt}` });
|
|
|
6205
6273
|
|
|
6206
6274
|
${taskAddendum}`;
|
|
6207
6275
|
fireWebhook("task.started", { prompt: options.prompt });
|
|
6276
|
+
if (emit) {
|
|
6277
|
+
await emit(JSON.stringify({ type: "data-user-message", data: { id: `user_${Date.now()}`, content: options.prompt } }));
|
|
6278
|
+
}
|
|
6208
6279
|
await this.context.addUserMessage(options.prompt);
|
|
6209
6280
|
let iteration = 0;
|
|
6210
6281
|
while (iteration < maxIterations) {
|
|
@@ -6216,7 +6287,15 @@ ${taskAddendum}`;
|
|
|
6216
6287
|
}
|
|
6217
6288
|
const messages = await this.context.getMessages();
|
|
6218
6289
|
const useAnthropic = isAnthropicModel(this.session.model);
|
|
6219
|
-
|
|
6290
|
+
if (emit) {
|
|
6291
|
+
await emit(JSON.stringify({ type: "start", messageId: `msg_${Date.now()}` }));
|
|
6292
|
+
}
|
|
6293
|
+
let textStarted = false;
|
|
6294
|
+
let textId = `text_${Date.now()}`;
|
|
6295
|
+
let reasoningId = `reasoning_${Date.now()}`;
|
|
6296
|
+
let reasoningStarted = false;
|
|
6297
|
+
const toolCallStarts = /* @__PURE__ */ new Set();
|
|
6298
|
+
const iterStream = streamText2({
|
|
6220
6299
|
model: resolveModel(this.session.model),
|
|
6221
6300
|
system: systemPrompt,
|
|
6222
6301
|
messages,
|
|
@@ -6225,21 +6304,94 @@ ${taskAddendum}`;
|
|
|
6225
6304
|
abortSignal: options.abortSignal,
|
|
6226
6305
|
providerOptions: useAnthropic ? {
|
|
6227
6306
|
anthropic: {
|
|
6307
|
+
toolStreaming: true,
|
|
6228
6308
|
thinking: { type: "enabled", budgetTokens: 1e4 }
|
|
6229
6309
|
}
|
|
6230
6310
|
} : void 0,
|
|
6231
|
-
onStepFinish: (step) => {
|
|
6311
|
+
onStepFinish: async (step) => {
|
|
6232
6312
|
options.onStepFinish?.(step);
|
|
6233
6313
|
fireWebhook("task.step_finished", { iteration, text: step.text });
|
|
6314
|
+
if (emit) {
|
|
6315
|
+
if (textStarted) {
|
|
6316
|
+
await emit(JSON.stringify({ type: "text-end", id: textId }));
|
|
6317
|
+
textStarted = false;
|
|
6318
|
+
textId = `text_${Date.now()}`;
|
|
6319
|
+
}
|
|
6320
|
+
await emit(JSON.stringify({ type: "finish-step" }));
|
|
6321
|
+
}
|
|
6234
6322
|
}
|
|
6235
6323
|
});
|
|
6236
|
-
const
|
|
6324
|
+
for await (const part of iterStream.fullStream) {
|
|
6325
|
+
if (part.type === "text-delta") {
|
|
6326
|
+
if (emit) {
|
|
6327
|
+
if (!textStarted) {
|
|
6328
|
+
await emit(JSON.stringify({ type: "text-start", id: textId }));
|
|
6329
|
+
textStarted = true;
|
|
6330
|
+
}
|
|
6331
|
+
await emit(JSON.stringify({ type: "text-delta", id: textId, delta: part.text }));
|
|
6332
|
+
}
|
|
6333
|
+
} else if (part.type === "reasoning-start") {
|
|
6334
|
+
if (emit) {
|
|
6335
|
+
await emit(JSON.stringify({ type: "reasoning-start", id: reasoningId }));
|
|
6336
|
+
reasoningStarted = true;
|
|
6337
|
+
}
|
|
6338
|
+
} else if (part.type === "reasoning-delta") {
|
|
6339
|
+
if (emit) {
|
|
6340
|
+
await emit(JSON.stringify({ type: "reasoning-delta", id: reasoningId, delta: part.text }));
|
|
6341
|
+
}
|
|
6342
|
+
} else if (part.type === "reasoning-end") {
|
|
6343
|
+
if (emit && reasoningStarted) {
|
|
6344
|
+
await emit(JSON.stringify({ type: "reasoning-end", id: reasoningId }));
|
|
6345
|
+
reasoningStarted = false;
|
|
6346
|
+
reasoningId = `reasoning_${Date.now()}`;
|
|
6347
|
+
}
|
|
6348
|
+
} else if (part.type === "tool-call-streaming-start") {
|
|
6349
|
+
if (emit) {
|
|
6350
|
+
const p = part;
|
|
6351
|
+
await emit(JSON.stringify({ type: "tool-input-start", toolCallId: p.toolCallId, toolName: p.toolName }));
|
|
6352
|
+
toolCallStarts.add(p.toolCallId);
|
|
6353
|
+
}
|
|
6354
|
+
} else if (part.type === "tool-call-delta") {
|
|
6355
|
+
if (emit) {
|
|
6356
|
+
const p = part;
|
|
6357
|
+
await emit(JSON.stringify({ type: "tool-input-delta", toolCallId: p.toolCallId, argsTextDelta: p.argsTextDelta }));
|
|
6358
|
+
}
|
|
6359
|
+
} else if (part.type === "tool-call") {
|
|
6360
|
+
if (emit) {
|
|
6361
|
+
if (!toolCallStarts.has(part.toolCallId)) {
|
|
6362
|
+
await emit(JSON.stringify({ type: "tool-input-start", toolCallId: part.toolCallId, toolName: part.toolName }));
|
|
6363
|
+
toolCallStarts.add(part.toolCallId);
|
|
6364
|
+
}
|
|
6365
|
+
const safeInput = part.toolName === "write_file" && part.input && typeof part.input === "object" ? truncateWriteFileInput(part.input) : part.input;
|
|
6366
|
+
await emit(JSON.stringify({ type: "tool-input-available", toolCallId: part.toolCallId, toolName: part.toolName, input: safeInput }));
|
|
6367
|
+
}
|
|
6368
|
+
} else if (part.type === "tool-result") {
|
|
6369
|
+
if (emit) {
|
|
6370
|
+
await emit(JSON.stringify({ type: "tool-output-available", toolCallId: part.toolCallId, output: part.output }));
|
|
6371
|
+
}
|
|
6372
|
+
} else if (part.type === "error") {
|
|
6373
|
+
console.error("Task stream error:", part.error);
|
|
6374
|
+
if (emit) {
|
|
6375
|
+
await emit(JSON.stringify({ type: "error", errorText: String(part.error) }));
|
|
6376
|
+
}
|
|
6377
|
+
}
|
|
6378
|
+
}
|
|
6379
|
+
if (emit && textStarted) {
|
|
6380
|
+
await emit(JSON.stringify({ type: "text-end", id: textId }));
|
|
6381
|
+
}
|
|
6382
|
+
if (emit && reasoningStarted) {
|
|
6383
|
+
await emit(JSON.stringify({ type: "reasoning-end", id: reasoningId }));
|
|
6384
|
+
}
|
|
6385
|
+
const iterResponse = await iterStream.response;
|
|
6386
|
+
const responseMessages = iterResponse.messages;
|
|
6237
6387
|
await this.context.addResponseMessages(responseMessages);
|
|
6238
|
-
|
|
6239
|
-
|
|
6240
|
-
|
|
6388
|
+
const resultText = await iterStream.text;
|
|
6389
|
+
const resultSteps = await iterStream.steps;
|
|
6390
|
+
if (resultText) {
|
|
6391
|
+
options.onText?.(resultText);
|
|
6392
|
+
fireWebhook("task.message", { iteration, text: resultText });
|
|
6241
6393
|
}
|
|
6242
|
-
for (const step of
|
|
6394
|
+
for (const step of resultSteps) {
|
|
6243
6395
|
if (step.toolCalls) {
|
|
6244
6396
|
for (const tc of step.toolCalls) {
|
|
6245
6397
|
options.onToolCall?.({ toolCallId: tc.toolCallId, toolName: tc.toolName, input: tc.args });
|
|
@@ -6292,9 +6444,11 @@ ${taskAddendum}`;
|
|
|
6292
6444
|
iterations: iteration
|
|
6293
6445
|
};
|
|
6294
6446
|
}
|
|
6295
|
-
|
|
6296
|
-
|
|
6297
|
-
|
|
6447
|
+
const continuationPrompt = "Continue working on the task. Before calling `complete_task`, VERIFY your work is correct \u2014 re-read edited files, run the linter, run tests if applicable, and check the browser/server if you made UI or API changes. Make sure you searched the right directories and found everything relevant. When fully verified, call `complete_task` with the result. If you cannot complete it, call `task_failed` with a reason.";
|
|
6448
|
+
if (emit) {
|
|
6449
|
+
await emit(JSON.stringify({ type: "data-user-message", data: { id: `user_${Date.now()}`, content: continuationPrompt } }));
|
|
6450
|
+
}
|
|
6451
|
+
await this.context.addUserMessage(continuationPrompt);
|
|
6298
6452
|
}
|
|
6299
6453
|
const timeoutError = `Task did not complete within ${maxIterations} iterations`;
|
|
6300
6454
|
const timeoutRecordingUrls = await this.finishTaskRecording(taskRecorder);
|