sparkecoder 0.1.65 → 0.1.66
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 +31 -28
- package/dist/agent/index.js.map +1 -1
- package/dist/cli.js +96 -118
- package/dist/cli.js.map +1 -1
- package/dist/db/index.d.ts +2 -2
- package/dist/{index-BhKQYdOx.d.ts → index-Db23cukG.d.ts} +25 -25
- package/dist/index.d.ts +5 -5
- package/dist/index.js +96 -118
- package/dist/index.js.map +1 -1
- package/dist/{schema-XcP0dedO.d.ts → schema-C7Mm4Ykn.d.ts} +3 -3
- package/dist/{search-DkNNtC5A.d.ts → search-CVVfuBPZ.d.ts} +5 -4
- package/dist/server/index.js +96 -118
- package/dist/server/index.js.map +1 -1
- package/dist/tools/index.d.ts +3 -3
- package/dist/tools/index.js +16 -11
- package/dist/tools/index.js.map +1 -1
- 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.js.nft.json +1 -1
- 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.js.nft.json +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/page_client-reference-manifest.js +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 +2 -2
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- 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 +2 -2
- 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 +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/installation/page_client-reference-manifest.js +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 +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_full.segment.rsc +2 -2
- 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 +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_tree.segment.rsc +2 -2
- 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/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills/page_client-reference-manifest.js +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 +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_full.segment.rsc +2 -2
- 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 +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_tree.segment.rsc +2 -2
- 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/page_client-reference-manifest.js +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 +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_full.segment.rsc +2 -2
- 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 +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_tree.segment.rsc +2 -2
- 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 +2 -2
- package/web/.next/standalone/web/.next/server/app/docs.segments/_full.segment.rsc +2 -2
- 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 +2 -2
- package/web/.next/standalone/web/.next/server/app/docs.segments/_tree.segment.rsc +2 -2
- 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.js.nft.json +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 +4 -4
- 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 +4 -4
- 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 +2 -2
- package/web/.next/standalone/web/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_708e1a2e._.js → 2374f_02a118f9._.js} +1 -1
- package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_3db08933._.js → 2374f_0ed477f8._.js} +1 -1
- package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_7d957e38._.js → 2374f_12bad06e._.js} +1 -1
- package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_1225fb9d._.js → 2374f_2526ca80._.js} +1 -1
- package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_95e53328._.js → 2374f_3b51a934._.js} +1 -1
- package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_f1f229dd._.js → 2374f_3e519469._.js} +1 -1
- package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_a19628a3._.js → 2374f_5ebfcf1a._.js} +1 -1
- package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_a90b70ee._.js → 2374f_a0f483d1._.js} +1 -1
- package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_2775224f._.js → 2374f_acf3dfe4._.js} +1 -1
- package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_32fd5733._.js → 2374f_ad08e83a._.js} +1 -1
- package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_2eac907f._.js → 2374f_c1d54c16._.js} +1 -1
- package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_51500fd2._.js → 2374f_db3e363b._.js} +1 -1
- package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_8385a57b._.js → 2374f_f0d7e130._.js} +1 -1
- package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_6f1ea3a7._.js → 2374f_fc992d90._.js} +1 -1
- package/web/.next/standalone/web/.next/server/chunks/ssr/{[root-of-the-server]__5bde4c40._.js → [root-of-the-server]__06818a54._.js} +2 -2
- package/web/.next/standalone/web/.next/server/chunks/ssr/{[root-of-the-server]__4085bf35._.js → [root-of-the-server]__c71f29f9._.js} +4 -4
- 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/chunks/ssr/web_5cca707f._.js +7 -0
- package/web/.next/standalone/web/.next/server/chunks/ssr/web_935e81f5._.js +7 -0
- package/web/.next/standalone/web/.next/server/chunks/ssr/{web_14735895._.js → web_cc5f7515._.js} +2 -2
- 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/{static/chunks/4b6a9454bc6460c5.js → standalone/web/.next/static/chunks/31208ade542a0fcb.js} +3 -3
- package/web/.next/{static/chunks/4a490bc538aa0940.js → standalone/web/.next/static/chunks/4e673433173ad456.js} +3 -3
- package/web/.next/standalone/web/.next/static/chunks/{c2dccd8f56d8eb5a.js → 515f0c0bd6087843.js} +5 -5
- package/web/.next/standalone/web/.next/static/chunks/fd39dd62879495e1.css +1 -0
- package/web/.next/standalone/web/.next/static/static/chunks/{4b6a9454bc6460c5.js → 31208ade542a0fcb.js} +3 -3
- package/web/.next/standalone/web/.next/static/static/chunks/{4a490bc538aa0940.js → 4e673433173ad456.js} +3 -3
- package/web/.next/standalone/web/.next/static/static/chunks/{c2dccd8f56d8eb5a.js → 515f0c0bd6087843.js} +5 -5
- package/web/.next/standalone/web/.next/static/static/chunks/fd39dd62879495e1.css +1 -0
- package/web/.next/standalone/web/src/components/chat-interface.tsx +96 -1
- package/web/.next/standalone/web/src/lib/api.ts +24 -0
- package/web/.next/{standalone/web/.next/static/chunks/4b6a9454bc6460c5.js → static/chunks/31208ade542a0fcb.js} +3 -3
- package/web/.next/{standalone/web/.next/static/chunks/4a490bc538aa0940.js → static/chunks/4e673433173ad456.js} +3 -3
- package/web/.next/static/chunks/{c2dccd8f56d8eb5a.js → 515f0c0bd6087843.js} +5 -5
- package/web/.next/static/chunks/fd39dd62879495e1.css +1 -0
- package/web/.next/standalone/web/.next/server/chunks/ssr/web_08bbd8c8._.js +0 -7
- package/web/.next/standalone/web/.next/server/chunks/ssr/web_c729ad51._.js +0 -7
- package/web/.next/standalone/web/.next/static/chunks/8b53c110c5a6f9a0.css +0 -1
- package/web/.next/standalone/web/.next/static/static/chunks/8b53c110c5a6f9a0.css +0 -1
- package/web/.next/static/chunks/8b53c110c5a6f9a0.css +0 -1
- /package/web/.next/standalone/web/.next/static/{NuySHGSR0CchKU9zo42LK → UMGGmtMDTCI6fL-AIFkiM}/_buildManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/{NuySHGSR0CchKU9zo42LK → UMGGmtMDTCI6fL-AIFkiM}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/standalone/web/.next/static/{NuySHGSR0CchKU9zo42LK → UMGGmtMDTCI6fL-AIFkiM}/_ssgManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/static/{NuySHGSR0CchKU9zo42LK → UMGGmtMDTCI6fL-AIFkiM}/_buildManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/static/{NuySHGSR0CchKU9zo42LK → UMGGmtMDTCI6fL-AIFkiM}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/standalone/web/.next/static/static/{NuySHGSR0CchKU9zo42LK → UMGGmtMDTCI6fL-AIFkiM}/_ssgManifest.js +0 -0
- /package/web/.next/static/{NuySHGSR0CchKU9zo42LK → UMGGmtMDTCI6fL-AIFkiM}/_buildManifest.js +0 -0
- /package/web/.next/static/{NuySHGSR0CchKU9zo42LK → UMGGmtMDTCI6fL-AIFkiM}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{NuySHGSR0CchKU9zo42LK → UMGGmtMDTCI6fL-AIFkiM}/_ssgManifest.js +0 -0
package/dist/cli.js
CHANGED
|
@@ -2555,19 +2555,14 @@ __export(stream_proxy_exports, {
|
|
|
2555
2555
|
import WebSocket from "ws";
|
|
2556
2556
|
import { EventEmitter } from "events";
|
|
2557
2557
|
function getOrCreateProxy(sessionId, port) {
|
|
2558
|
-
|
|
2559
|
-
if (
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
proxy.on("close", () => {
|
|
2567
|
-
activeProxies.delete(sessionId);
|
|
2568
|
-
});
|
|
2569
|
-
proxy.connect();
|
|
2570
|
-
}
|
|
2558
|
+
const existing = activeProxies.get(sessionId);
|
|
2559
|
+
if (existing) return existing;
|
|
2560
|
+
const proxy = new BrowserStreamProxy(port);
|
|
2561
|
+
activeProxies.set(sessionId, proxy);
|
|
2562
|
+
proxy.on("close", () => {
|
|
2563
|
+
activeProxies.delete(sessionId);
|
|
2564
|
+
});
|
|
2565
|
+
proxy.connect();
|
|
2571
2566
|
return proxy;
|
|
2572
2567
|
}
|
|
2573
2568
|
function getProxy(sessionId) {
|
|
@@ -2584,8 +2579,8 @@ var RECONNECT_DELAY_MS, MAX_RECONNECT_ATTEMPTS, FRAME_THROTTLE_MS, BrowserStream
|
|
|
2584
2579
|
var init_stream_proxy = __esm({
|
|
2585
2580
|
"src/browser/stream-proxy.ts"() {
|
|
2586
2581
|
"use strict";
|
|
2587
|
-
RECONNECT_DELAY_MS =
|
|
2588
|
-
MAX_RECONNECT_ATTEMPTS =
|
|
2582
|
+
RECONNECT_DELAY_MS = 1e3;
|
|
2583
|
+
MAX_RECONNECT_ATTEMPTS = 20;
|
|
2589
2584
|
FRAME_THROTTLE_MS = 100;
|
|
2590
2585
|
BrowserStreamProxy = class extends EventEmitter {
|
|
2591
2586
|
ws = null;
|
|
@@ -2635,8 +2630,11 @@ var init_stream_proxy = __esm({
|
|
|
2635
2630
|
}
|
|
2636
2631
|
});
|
|
2637
2632
|
this.ws.on("close", () => {
|
|
2633
|
+
const wasConnected = this._connected;
|
|
2638
2634
|
this._connected = false;
|
|
2639
|
-
|
|
2635
|
+
if (wasConnected) {
|
|
2636
|
+
this.emit("status", { connected: false, screencasting: false });
|
|
2637
|
+
}
|
|
2640
2638
|
if (!this.destroyed) {
|
|
2641
2639
|
this.scheduleReconnect();
|
|
2642
2640
|
}
|
|
@@ -2678,7 +2676,7 @@ var init_stream_proxy = __esm({
|
|
|
2678
2676
|
return;
|
|
2679
2677
|
}
|
|
2680
2678
|
this.reconnectAttempts++;
|
|
2681
|
-
const delay = RECONNECT_DELAY_MS * this.reconnectAttempts;
|
|
2679
|
+
const delay = this.reconnectAttempts <= 5 ? RECONNECT_DELAY_MS : RECONNECT_DELAY_MS * (this.reconnectAttempts - 4);
|
|
2682
2680
|
this.reconnectTimer = setTimeout(() => this.doConnect(), delay);
|
|
2683
2681
|
}
|
|
2684
2682
|
/**
|
|
@@ -3395,15 +3393,15 @@ function getBrowserStreamPort(sessionId) {
|
|
|
3395
3393
|
}
|
|
3396
3394
|
return port;
|
|
3397
3395
|
}
|
|
3398
|
-
function
|
|
3399
|
-
return /\bagent-browser\
|
|
3396
|
+
function hasAgentBrowserCommand(command) {
|
|
3397
|
+
return /\bagent-browser\b/.test(command);
|
|
3400
3398
|
}
|
|
3401
3399
|
function isAgentBrowserCloseCommand(command) {
|
|
3402
|
-
return /\bagent-browser\s+close\b/.test(command);
|
|
3400
|
+
return /\bagent-browser\s+(close|close\s+--all)\b/.test(command);
|
|
3403
3401
|
}
|
|
3404
3402
|
function injectBrowserStreamPort(command, port) {
|
|
3405
3403
|
return command.replace(
|
|
3406
|
-
/\bagent-browser\b
|
|
3404
|
+
/\bagent-browser\b/g,
|
|
3407
3405
|
`AGENT_BROWSER_STREAM_PORT=${port} agent-browser`
|
|
3408
3406
|
);
|
|
3409
3407
|
}
|
|
@@ -3573,12 +3571,14 @@ Terminal output is stored in the global SparkECoder data directory. Use the \`ta
|
|
|
3573
3571
|
};
|
|
3574
3572
|
}
|
|
3575
3573
|
let actualCommand = command;
|
|
3576
|
-
const
|
|
3574
|
+
const hasAgentBrowser = hasAgentBrowserCommand(command);
|
|
3577
3575
|
const browserClose = isAgentBrowserCloseCommand(command);
|
|
3578
3576
|
let browserPort;
|
|
3579
|
-
if (
|
|
3577
|
+
if (hasAgentBrowser) {
|
|
3580
3578
|
browserPort = getBrowserStreamPort(options.sessionId);
|
|
3581
|
-
|
|
3579
|
+
if (!browserClose) {
|
|
3580
|
+
actualCommand = injectBrowserStreamPort(command, browserPort);
|
|
3581
|
+
}
|
|
3582
3582
|
}
|
|
3583
3583
|
const canUseTmux = await shouldUseTmux();
|
|
3584
3584
|
if (background) {
|
|
@@ -3594,9 +3594,6 @@ Terminal output is stored in the global SparkECoder data directory. Use the \`ta
|
|
|
3594
3594
|
sessionId: options.sessionId,
|
|
3595
3595
|
terminalId
|
|
3596
3596
|
});
|
|
3597
|
-
if (browserOpen && browserPort) {
|
|
3598
|
-
options.onProgress?.({ terminalId, status: "running", command, browserStreamPort: browserPort });
|
|
3599
|
-
}
|
|
3600
3597
|
return {
|
|
3601
3598
|
success: true,
|
|
3602
3599
|
id: result.id,
|
|
@@ -3615,7 +3612,13 @@ Terminal output is stored in the global SparkECoder data directory. Use the \`ta
|
|
|
3615
3612
|
});
|
|
3616
3613
|
const truncatedOutput = truncateOutput(result.output, MAX_OUTPUT_CHARS2);
|
|
3617
3614
|
options.onOutput?.(truncatedOutput);
|
|
3618
|
-
options.onProgress?.({
|
|
3615
|
+
options.onProgress?.({
|
|
3616
|
+
terminalId,
|
|
3617
|
+
status: "completed",
|
|
3618
|
+
command,
|
|
3619
|
+
browserStreamPort: browserPort,
|
|
3620
|
+
browserClosed: browserClose || void 0
|
|
3621
|
+
});
|
|
3619
3622
|
return {
|
|
3620
3623
|
success: result.exitCode === 0,
|
|
3621
3624
|
id: result.id,
|
|
@@ -8860,42 +8863,6 @@ function enrichPromptWithDevtoolsContext(sessionId, prompt) {
|
|
|
8860
8863
|
|
|
8861
8864
|
${prompt}`;
|
|
8862
8865
|
}
|
|
8863
|
-
async function encodAndUploadRecording(sessionId, recorder) {
|
|
8864
|
-
if (!isRemoteConfigured()) {
|
|
8865
|
-
console.log("[RECORDING] Remote server not configured, skipping upload");
|
|
8866
|
-
recorder.clear();
|
|
8867
|
-
return;
|
|
8868
|
-
}
|
|
8869
|
-
console.log(`[RECORDING] Encoding ${recorder.frameCount} frames for session ${sessionId}...`);
|
|
8870
|
-
const result = await recorder.encode();
|
|
8871
|
-
recorder.clear();
|
|
8872
|
-
if (!result) {
|
|
8873
|
-
console.log("[RECORDING] Encoding failed or produced no output");
|
|
8874
|
-
return;
|
|
8875
|
-
}
|
|
8876
|
-
try {
|
|
8877
|
-
const { storageQueries: storageQueries2 } = await Promise.resolve().then(() => (init_remote(), remote_exports));
|
|
8878
|
-
const { readFile: readFile11, unlink: unlink3 } = await import("fs/promises");
|
|
8879
|
-
const uploadInfo = await storageQueries2.getUploadUrl(
|
|
8880
|
-
sessionId,
|
|
8881
|
-
`browser-recording-${Date.now()}.mp4`,
|
|
8882
|
-
"video/mp4",
|
|
8883
|
-
"browser-recording"
|
|
8884
|
-
);
|
|
8885
|
-
const fileData = await readFile11(result.path);
|
|
8886
|
-
await fetch(uploadInfo.uploadUrl, {
|
|
8887
|
-
method: "PUT",
|
|
8888
|
-
headers: { "Content-Type": "video/mp4" },
|
|
8889
|
-
body: fileData
|
|
8890
|
-
});
|
|
8891
|
-
await storageQueries2.updateFile(uploadInfo.fileId, { sizeBytes: result.sizeBytes });
|
|
8892
|
-
console.log(`[RECORDING] Uploaded recording for session ${sessionId} (${result.sizeBytes} bytes)`);
|
|
8893
|
-
await unlink3(result.path).catch(() => {
|
|
8894
|
-
});
|
|
8895
|
-
} catch (err) {
|
|
8896
|
-
console.error("[RECORDING] Upload failed:", err.message);
|
|
8897
|
-
}
|
|
8898
|
-
}
|
|
8899
8866
|
var agents = new Hono2();
|
|
8900
8867
|
var attachmentSchema = z16.object({
|
|
8901
8868
|
type: z16.enum(["image", "file"]),
|
|
@@ -9110,30 +9077,38 @@ ${prompt}` });
|
|
|
9110
9077
|
await new Promise((resolve12) => setTimeout(resolve12, 0));
|
|
9111
9078
|
}
|
|
9112
9079
|
const browserPort = progress.data?.browserStreamPort;
|
|
9113
|
-
|
|
9080
|
+
const browserClosed = progress.data?.browserClosed;
|
|
9081
|
+
if (progress.toolName === "bash" && browserClosed) {
|
|
9082
|
+
console.log(`[BROWSER-STREAM] agent-browser close detected, destroying proxy`);
|
|
9083
|
+
destroyProxy(sessionId);
|
|
9084
|
+
} else if (progress.toolName === "bash" && browserPort) {
|
|
9085
|
+
console.log(`[BROWSER-STREAM] agent-browser command detected, ensuring proxy on port ${browserPort}`);
|
|
9114
9086
|
const proxy = getOrCreateProxy(sessionId, browserPort);
|
|
9115
|
-
|
|
9116
|
-
|
|
9117
|
-
recorder = new FrameRecorder(sessionId);
|
|
9087
|
+
if (!sessionRecorders.has(sessionId)) {
|
|
9088
|
+
const recorder = new FrameRecorder(sessionId);
|
|
9118
9089
|
recorder.start();
|
|
9119
9090
|
sessionRecorders.set(sessionId, recorder);
|
|
9120
9091
|
}
|
|
9121
|
-
proxy.
|
|
9122
|
-
|
|
9123
|
-
|
|
9124
|
-
|
|
9125
|
-
|
|
9126
|
-
|
|
9127
|
-
|
|
9092
|
+
if (proxy.listenerCount("frame") === 0) {
|
|
9093
|
+
proxy.on("frame", (frame) => {
|
|
9094
|
+
const rec = sessionRecorders.get(sessionId);
|
|
9095
|
+
rec?.addFrame(frame);
|
|
9096
|
+
writeSSE(JSON.stringify({
|
|
9097
|
+
type: "browser-frame",
|
|
9098
|
+
data: frame.data,
|
|
9099
|
+
metadata: frame.metadata
|
|
9100
|
+
})).catch(() => {
|
|
9101
|
+
});
|
|
9128
9102
|
});
|
|
9129
|
-
|
|
9130
|
-
|
|
9131
|
-
|
|
9132
|
-
|
|
9133
|
-
|
|
9134
|
-
|
|
9103
|
+
proxy.on("status", (s) => {
|
|
9104
|
+
console.log(`[BROWSER-STREAM] Status:`, s);
|
|
9105
|
+
writeSSE(JSON.stringify({
|
|
9106
|
+
type: "browser-status",
|
|
9107
|
+
...s
|
|
9108
|
+
})).catch(() => {
|
|
9109
|
+
});
|
|
9135
9110
|
});
|
|
9136
|
-
}
|
|
9111
|
+
}
|
|
9137
9112
|
}
|
|
9138
9113
|
},
|
|
9139
9114
|
onStepFinish: async () => {
|
|
@@ -9245,15 +9220,6 @@ ${prompt}` });
|
|
|
9245
9220
|
}
|
|
9246
9221
|
} finally {
|
|
9247
9222
|
cleanupAbortController();
|
|
9248
|
-
destroyProxy(sessionId);
|
|
9249
|
-
const recorder = sessionRecorders.get(sessionId);
|
|
9250
|
-
if (recorder && recorder.frameCount > 0) {
|
|
9251
|
-
sessionRecorders.delete(sessionId);
|
|
9252
|
-
recorder.stop();
|
|
9253
|
-
encodAndUploadRecording(sessionId, recorder).catch((err) => {
|
|
9254
|
-
console.error("[RECORDING] Failed to encode/upload:", err.message);
|
|
9255
|
-
});
|
|
9256
|
-
}
|
|
9257
9223
|
await writeSSE("[DONE]");
|
|
9258
9224
|
await safeClose();
|
|
9259
9225
|
}
|
|
@@ -9609,30 +9575,38 @@ agents.post(
|
|
|
9609
9575
|
await new Promise((resolve12) => setTimeout(resolve12, 0));
|
|
9610
9576
|
}
|
|
9611
9577
|
const browserPort = progress.data?.browserStreamPort;
|
|
9612
|
-
|
|
9578
|
+
const browserClosed = progress.data?.browserClosed;
|
|
9579
|
+
if (progress.toolName === "bash" && browserClosed) {
|
|
9580
|
+
console.log(`[BROWSER-STREAM] agent-browser close detected`);
|
|
9581
|
+
destroyProxy(session.id);
|
|
9582
|
+
} else if (progress.toolName === "bash" && browserPort) {
|
|
9583
|
+
console.log(`[BROWSER-STREAM] agent-browser command detected, port ${browserPort}`);
|
|
9613
9584
|
const proxy = getOrCreateProxy(session.id, browserPort);
|
|
9614
|
-
|
|
9615
|
-
|
|
9616
|
-
recorder = new FrameRecorder(session.id);
|
|
9585
|
+
if (!sessionRecorders.has(session.id)) {
|
|
9586
|
+
const recorder = new FrameRecorder(session.id);
|
|
9617
9587
|
recorder.start();
|
|
9618
9588
|
sessionRecorders.set(session.id, recorder);
|
|
9619
9589
|
}
|
|
9620
|
-
proxy.
|
|
9621
|
-
|
|
9622
|
-
|
|
9623
|
-
|
|
9624
|
-
|
|
9625
|
-
|
|
9626
|
-
|
|
9590
|
+
if (proxy.listenerCount("frame") === 0) {
|
|
9591
|
+
proxy.on("frame", (frame) => {
|
|
9592
|
+
const rec = sessionRecorders.get(session.id);
|
|
9593
|
+
rec?.addFrame(frame);
|
|
9594
|
+
writeSSE(JSON.stringify({
|
|
9595
|
+
type: "browser-frame",
|
|
9596
|
+
data: frame.data,
|
|
9597
|
+
metadata: frame.metadata
|
|
9598
|
+
})).catch(() => {
|
|
9599
|
+
});
|
|
9627
9600
|
});
|
|
9628
|
-
|
|
9629
|
-
|
|
9630
|
-
|
|
9631
|
-
|
|
9632
|
-
|
|
9633
|
-
|
|
9601
|
+
proxy.on("status", (s) => {
|
|
9602
|
+
console.log(`[BROWSER-STREAM] Status:`, s);
|
|
9603
|
+
writeSSE(JSON.stringify({
|
|
9604
|
+
type: "browser-status",
|
|
9605
|
+
...s
|
|
9606
|
+
})).catch(() => {
|
|
9607
|
+
});
|
|
9634
9608
|
});
|
|
9635
|
-
}
|
|
9609
|
+
}
|
|
9636
9610
|
}
|
|
9637
9611
|
},
|
|
9638
9612
|
onStepFinish: async () => {
|
|
@@ -9738,15 +9712,6 @@ agents.post(
|
|
|
9738
9712
|
}
|
|
9739
9713
|
} finally {
|
|
9740
9714
|
cleanupAbortController();
|
|
9741
|
-
destroyProxy(session.id);
|
|
9742
|
-
const recorder = sessionRecorders.get(session.id);
|
|
9743
|
-
if (recorder && recorder.frameCount > 0) {
|
|
9744
|
-
sessionRecorders.delete(session.id);
|
|
9745
|
-
recorder.stop();
|
|
9746
|
-
encodAndUploadRecording(session.id, recorder).catch((err) => {
|
|
9747
|
-
console.error("[RECORDING] Failed to encode/upload:", err.message);
|
|
9748
|
-
});
|
|
9749
|
-
}
|
|
9750
9715
|
await writeSSE("[DONE]");
|
|
9751
9716
|
await safeClose();
|
|
9752
9717
|
}
|
|
@@ -9806,6 +9771,19 @@ agents.post(
|
|
|
9806
9771
|
return c.json({ success: true });
|
|
9807
9772
|
}
|
|
9808
9773
|
);
|
|
9774
|
+
agents.get("/:id/browser-stream", async (c) => {
|
|
9775
|
+
const sessionId = c.req.param("id");
|
|
9776
|
+
const proxy = getProxy(sessionId);
|
|
9777
|
+
return c.json({
|
|
9778
|
+
sessionId,
|
|
9779
|
+
active: !!proxy?.connected,
|
|
9780
|
+
hasProxy: !!proxy,
|
|
9781
|
+
latestFrame: proxy?.latestFrame ? {
|
|
9782
|
+
metadata: proxy.latestFrame.metadata,
|
|
9783
|
+
timestamp: proxy.latestFrame.timestamp
|
|
9784
|
+
} : null
|
|
9785
|
+
});
|
|
9786
|
+
});
|
|
9809
9787
|
|
|
9810
9788
|
// src/server/routes/health.ts
|
|
9811
9789
|
init_config();
|