sparkecoder 0.1.67 → 0.1.68
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 +1 -1
- package/dist/agent/index.js +135 -13
- package/dist/agent/index.js.map +1 -1
- package/dist/cli.js +200 -48
- package/dist/cli.js.map +1 -1
- package/dist/{index-DHyVVhJY.d.ts → index-Dm6wGcYv.d.ts} +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +200 -48
- package/dist/index.js.map +1 -1
- package/dist/server/index.js +200 -48
- package/dist/server/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/_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/index.html +1 -1
- package/web/.next/standalone/web/.next/server/app/index.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/_full.segment.rsc +1 -1
- 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/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/{static/tZkod5afiOX7T9AkN1yPO → 6Dlxqhgk8Mki7q7L-gDbl}/_buildManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/{static/tZkod5afiOX7T9AkN1yPO → 6Dlxqhgk8Mki7q7L-gDbl}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/standalone/web/.next/static/{static/tZkod5afiOX7T9AkN1yPO → 6Dlxqhgk8Mki7q7L-gDbl}/_ssgManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/{tZkod5afiOX7T9AkN1yPO → static/6Dlxqhgk8Mki7q7L-gDbl}/_buildManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/{tZkod5afiOX7T9AkN1yPO → static/6Dlxqhgk8Mki7q7L-gDbl}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/standalone/web/.next/static/{tZkod5afiOX7T9AkN1yPO → static/6Dlxqhgk8Mki7q7L-gDbl}/_ssgManifest.js +0 -0
- /package/web/.next/static/{tZkod5afiOX7T9AkN1yPO → 6Dlxqhgk8Mki7q7L-gDbl}/_buildManifest.js +0 -0
- /package/web/.next/static/{tZkod5afiOX7T9AkN1yPO → 6Dlxqhgk8Mki7q7L-gDbl}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{tZkod5afiOX7T9AkN1yPO → 6Dlxqhgk8Mki7q7L-gDbl}/_ssgManifest.js +0 -0
package/dist/cli.js
CHANGED
|
@@ -7256,6 +7256,21 @@ ${this.summary}`
|
|
|
7256
7256
|
|
|
7257
7257
|
// src/agent/index.ts
|
|
7258
7258
|
init_webhook();
|
|
7259
|
+
var MAX_SSE_FIELD_LENGTH = 8 * 1024;
|
|
7260
|
+
var SSE_PREVIEW_LENGTH = 2 * 1024;
|
|
7261
|
+
function truncateWriteFileInput(input) {
|
|
7262
|
+
const out = { ...input };
|
|
7263
|
+
for (const key of ["content", "old_string", "new_string"]) {
|
|
7264
|
+
const val = out[key];
|
|
7265
|
+
if (typeof val === "string" && val.length > MAX_SSE_FIELD_LENGTH) {
|
|
7266
|
+
out[key] = `${val.slice(0, SSE_PREVIEW_LENGTH)}
|
|
7267
|
+
... (truncated)`;
|
|
7268
|
+
out[`${key}Truncated`] = true;
|
|
7269
|
+
out[`${key}Length`] = val.length;
|
|
7270
|
+
}
|
|
7271
|
+
}
|
|
7272
|
+
return out;
|
|
7273
|
+
}
|
|
7259
7274
|
var approvalResolvers = /* @__PURE__ */ new Map();
|
|
7260
7275
|
var Agent = class _Agent {
|
|
7261
7276
|
session;
|
|
@@ -7499,8 +7514,11 @@ ${prompt}` });
|
|
|
7499
7514
|
};
|
|
7500
7515
|
let taskRecorder = null;
|
|
7501
7516
|
const sessionId = this.session.id;
|
|
7517
|
+
const emit = options.writeSSE;
|
|
7502
7518
|
const bashProgressHandler = (progress) => {
|
|
7503
7519
|
options.onToolProgress?.({ toolName: "bash", data: progress });
|
|
7520
|
+
if (emit) emit(JSON.stringify({ type: "tool-progress", toolName: "bash", data: progress })).catch(() => {
|
|
7521
|
+
});
|
|
7504
7522
|
const port = progress.browserStreamPort;
|
|
7505
7523
|
if (port && progress.status === "started") {
|
|
7506
7524
|
Promise.resolve().then(() => (init_stream_proxy(), stream_proxy_exports)).then(({ getOrCreateProxy: getOrCreateProxy2 }) => {
|
|
@@ -7509,7 +7527,17 @@ ${prompt}` });
|
|
|
7509
7527
|
Promise.resolve().then(() => (init_recorder(), recorder_exports)).then(({ FrameRecorder: FrameRecorder2 }) => {
|
|
7510
7528
|
taskRecorder = new FrameRecorder2(sessionId);
|
|
7511
7529
|
taskRecorder.start();
|
|
7512
|
-
|
|
7530
|
+
});
|
|
7531
|
+
}
|
|
7532
|
+
if (proxy.listenerCount("frame") === 0) {
|
|
7533
|
+
proxy.on("frame", (frame) => {
|
|
7534
|
+
taskRecorder?.addFrame(frame);
|
|
7535
|
+
if (emit) emit(JSON.stringify({ type: "browser-frame", data: frame.data, metadata: frame.metadata })).catch(() => {
|
|
7536
|
+
});
|
|
7537
|
+
});
|
|
7538
|
+
proxy.on("status", (s) => {
|
|
7539
|
+
if (emit) emit(JSON.stringify({ type: "browser-status", ...s })).catch(() => {
|
|
7540
|
+
});
|
|
7513
7541
|
});
|
|
7514
7542
|
}
|
|
7515
7543
|
});
|
|
@@ -7520,8 +7548,16 @@ ${prompt}` });
|
|
|
7520
7548
|
workingDirectory: this.session.workingDirectory,
|
|
7521
7549
|
skillsDirectories: config.resolvedSkillsDirectories,
|
|
7522
7550
|
onBashProgress: bashProgressHandler,
|
|
7523
|
-
onWriteFileProgress:
|
|
7524
|
-
|
|
7551
|
+
onWriteFileProgress: (progress) => {
|
|
7552
|
+
options.onToolProgress?.({ toolName: "write_file", data: progress });
|
|
7553
|
+
if (emit) emit(JSON.stringify({ type: "tool-progress", toolName: "write_file", data: progress })).catch(() => {
|
|
7554
|
+
});
|
|
7555
|
+
},
|
|
7556
|
+
onSearchProgress: (progress) => {
|
|
7557
|
+
options.onToolProgress?.({ toolName: "explore_agent", data: progress });
|
|
7558
|
+
if (emit) emit(JSON.stringify({ type: "tool-progress", toolName: "explore_agent", data: progress })).catch(() => {
|
|
7559
|
+
});
|
|
7560
|
+
},
|
|
7525
7561
|
taskTools: {
|
|
7526
7562
|
outputSchema: options.taskConfig.outputSchema,
|
|
7527
7563
|
onComplete
|
|
@@ -7539,6 +7575,9 @@ ${prompt}` });
|
|
|
7539
7575
|
|
|
7540
7576
|
${taskAddendum}`;
|
|
7541
7577
|
fireWebhook("task.started", { prompt: options.prompt });
|
|
7578
|
+
if (emit) {
|
|
7579
|
+
await emit(JSON.stringify({ type: "data-user-message", data: { id: `user_${Date.now()}`, content: options.prompt } }));
|
|
7580
|
+
}
|
|
7542
7581
|
await this.context.addUserMessage(options.prompt);
|
|
7543
7582
|
let iteration = 0;
|
|
7544
7583
|
while (iteration < maxIterations) {
|
|
@@ -7550,7 +7589,15 @@ ${taskAddendum}`;
|
|
|
7550
7589
|
}
|
|
7551
7590
|
const messages = await this.context.getMessages();
|
|
7552
7591
|
const useAnthropic = isAnthropicModel(this.session.model);
|
|
7553
|
-
|
|
7592
|
+
if (emit) {
|
|
7593
|
+
await emit(JSON.stringify({ type: "start", messageId: `msg_${Date.now()}` }));
|
|
7594
|
+
}
|
|
7595
|
+
let textStarted = false;
|
|
7596
|
+
let textId = `text_${Date.now()}`;
|
|
7597
|
+
let reasoningId = `reasoning_${Date.now()}`;
|
|
7598
|
+
let reasoningStarted = false;
|
|
7599
|
+
const toolCallStarts = /* @__PURE__ */ new Set();
|
|
7600
|
+
const iterStream = streamText2({
|
|
7554
7601
|
model: resolveModel(this.session.model),
|
|
7555
7602
|
system: systemPrompt,
|
|
7556
7603
|
messages,
|
|
@@ -7559,21 +7606,94 @@ ${taskAddendum}`;
|
|
|
7559
7606
|
abortSignal: options.abortSignal,
|
|
7560
7607
|
providerOptions: useAnthropic ? {
|
|
7561
7608
|
anthropic: {
|
|
7609
|
+
toolStreaming: true,
|
|
7562
7610
|
thinking: { type: "enabled", budgetTokens: 1e4 }
|
|
7563
7611
|
}
|
|
7564
7612
|
} : void 0,
|
|
7565
|
-
onStepFinish: (step) => {
|
|
7613
|
+
onStepFinish: async (step) => {
|
|
7566
7614
|
options.onStepFinish?.(step);
|
|
7567
7615
|
fireWebhook("task.step_finished", { iteration, text: step.text });
|
|
7616
|
+
if (emit) {
|
|
7617
|
+
if (textStarted) {
|
|
7618
|
+
await emit(JSON.stringify({ type: "text-end", id: textId }));
|
|
7619
|
+
textStarted = false;
|
|
7620
|
+
textId = `text_${Date.now()}`;
|
|
7621
|
+
}
|
|
7622
|
+
await emit(JSON.stringify({ type: "finish-step" }));
|
|
7623
|
+
}
|
|
7568
7624
|
}
|
|
7569
7625
|
});
|
|
7570
|
-
const
|
|
7626
|
+
for await (const part of iterStream.fullStream) {
|
|
7627
|
+
if (part.type === "text-delta") {
|
|
7628
|
+
if (emit) {
|
|
7629
|
+
if (!textStarted) {
|
|
7630
|
+
await emit(JSON.stringify({ type: "text-start", id: textId }));
|
|
7631
|
+
textStarted = true;
|
|
7632
|
+
}
|
|
7633
|
+
await emit(JSON.stringify({ type: "text-delta", id: textId, delta: part.text }));
|
|
7634
|
+
}
|
|
7635
|
+
} else if (part.type === "reasoning-start") {
|
|
7636
|
+
if (emit) {
|
|
7637
|
+
await emit(JSON.stringify({ type: "reasoning-start", id: reasoningId }));
|
|
7638
|
+
reasoningStarted = true;
|
|
7639
|
+
}
|
|
7640
|
+
} else if (part.type === "reasoning-delta") {
|
|
7641
|
+
if (emit) {
|
|
7642
|
+
await emit(JSON.stringify({ type: "reasoning-delta", id: reasoningId, delta: part.text }));
|
|
7643
|
+
}
|
|
7644
|
+
} else if (part.type === "reasoning-end") {
|
|
7645
|
+
if (emit && reasoningStarted) {
|
|
7646
|
+
await emit(JSON.stringify({ type: "reasoning-end", id: reasoningId }));
|
|
7647
|
+
reasoningStarted = false;
|
|
7648
|
+
reasoningId = `reasoning_${Date.now()}`;
|
|
7649
|
+
}
|
|
7650
|
+
} else if (part.type === "tool-call-streaming-start") {
|
|
7651
|
+
if (emit) {
|
|
7652
|
+
const p = part;
|
|
7653
|
+
await emit(JSON.stringify({ type: "tool-input-start", toolCallId: p.toolCallId, toolName: p.toolName }));
|
|
7654
|
+
toolCallStarts.add(p.toolCallId);
|
|
7655
|
+
}
|
|
7656
|
+
} else if (part.type === "tool-call-delta") {
|
|
7657
|
+
if (emit) {
|
|
7658
|
+
const p = part;
|
|
7659
|
+
await emit(JSON.stringify({ type: "tool-input-delta", toolCallId: p.toolCallId, argsTextDelta: p.argsTextDelta }));
|
|
7660
|
+
}
|
|
7661
|
+
} else if (part.type === "tool-call") {
|
|
7662
|
+
if (emit) {
|
|
7663
|
+
if (!toolCallStarts.has(part.toolCallId)) {
|
|
7664
|
+
await emit(JSON.stringify({ type: "tool-input-start", toolCallId: part.toolCallId, toolName: part.toolName }));
|
|
7665
|
+
toolCallStarts.add(part.toolCallId);
|
|
7666
|
+
}
|
|
7667
|
+
const safeInput = part.toolName === "write_file" && part.input && typeof part.input === "object" ? truncateWriteFileInput(part.input) : part.input;
|
|
7668
|
+
await emit(JSON.stringify({ type: "tool-input-available", toolCallId: part.toolCallId, toolName: part.toolName, input: safeInput }));
|
|
7669
|
+
}
|
|
7670
|
+
} else if (part.type === "tool-result") {
|
|
7671
|
+
if (emit) {
|
|
7672
|
+
await emit(JSON.stringify({ type: "tool-output-available", toolCallId: part.toolCallId, output: part.output }));
|
|
7673
|
+
}
|
|
7674
|
+
} else if (part.type === "error") {
|
|
7675
|
+
console.error("Task stream error:", part.error);
|
|
7676
|
+
if (emit) {
|
|
7677
|
+
await emit(JSON.stringify({ type: "error", errorText: String(part.error) }));
|
|
7678
|
+
}
|
|
7679
|
+
}
|
|
7680
|
+
}
|
|
7681
|
+
if (emit && textStarted) {
|
|
7682
|
+
await emit(JSON.stringify({ type: "text-end", id: textId }));
|
|
7683
|
+
}
|
|
7684
|
+
if (emit && reasoningStarted) {
|
|
7685
|
+
await emit(JSON.stringify({ type: "reasoning-end", id: reasoningId }));
|
|
7686
|
+
}
|
|
7687
|
+
const iterResponse = await iterStream.response;
|
|
7688
|
+
const responseMessages = iterResponse.messages;
|
|
7571
7689
|
await this.context.addResponseMessages(responseMessages);
|
|
7572
|
-
|
|
7573
|
-
|
|
7574
|
-
|
|
7690
|
+
const resultText = await iterStream.text;
|
|
7691
|
+
const resultSteps = await iterStream.steps;
|
|
7692
|
+
if (resultText) {
|
|
7693
|
+
options.onText?.(resultText);
|
|
7694
|
+
fireWebhook("task.message", { iteration, text: resultText });
|
|
7575
7695
|
}
|
|
7576
|
-
for (const step of
|
|
7696
|
+
for (const step of resultSteps) {
|
|
7577
7697
|
if (step.toolCalls) {
|
|
7578
7698
|
for (const tc of step.toolCalls) {
|
|
7579
7699
|
options.onToolCall?.({ toolCallId: tc.toolCallId, toolName: tc.toolName, input: tc.args });
|
|
@@ -7626,9 +7746,11 @@ ${taskAddendum}`;
|
|
|
7626
7746
|
iterations: iteration
|
|
7627
7747
|
};
|
|
7628
7748
|
}
|
|
7629
|
-
|
|
7630
|
-
|
|
7631
|
-
|
|
7749
|
+
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.";
|
|
7750
|
+
if (emit) {
|
|
7751
|
+
await emit(JSON.stringify({ type: "data-user-message", data: { id: `user_${Date.now()}`, content: continuationPrompt } }));
|
|
7752
|
+
}
|
|
7753
|
+
await this.context.addUserMessage(continuationPrompt);
|
|
7632
7754
|
}
|
|
7633
7755
|
const timeoutError = `Task did not complete within ${maxIterations} iterations`;
|
|
7634
7756
|
const timeoutRecordingUrls = await this.finishTaskRecording(taskRecorder);
|
|
@@ -10260,6 +10382,7 @@ init_db();
|
|
|
10260
10382
|
import { Hono as Hono5 } from "hono";
|
|
10261
10383
|
import { zValidator as zValidator5 } from "@hono/zod-validator";
|
|
10262
10384
|
import { z as z19 } from "zod";
|
|
10385
|
+
import { nanoid as nanoid7 } from "nanoid";
|
|
10263
10386
|
init_config();
|
|
10264
10387
|
var tasks = new Hono5();
|
|
10265
10388
|
var taskAbortControllers = /* @__PURE__ */ new Map();
|
|
@@ -10297,45 +10420,74 @@ tasks.post(
|
|
|
10297
10420
|
const taskId = agent.sessionId;
|
|
10298
10421
|
const abortController = new AbortController();
|
|
10299
10422
|
taskAbortControllers.set(taskId, abortController);
|
|
10300
|
-
|
|
10301
|
-
|
|
10302
|
-
|
|
10303
|
-
|
|
10304
|
-
|
|
10305
|
-
|
|
10306
|
-
|
|
10307
|
-
|
|
10308
|
-
|
|
10309
|
-
|
|
10310
|
-
|
|
10311
|
-
|
|
10312
|
-
|
|
10313
|
-
|
|
10314
|
-
|
|
10315
|
-
|
|
10316
|
-
|
|
10317
|
-
|
|
10318
|
-
|
|
10319
|
-
|
|
10320
|
-
|
|
10321
|
-
|
|
10322
|
-
|
|
10423
|
+
const streamId = `stream_${taskId}_${nanoid7(10)}`;
|
|
10424
|
+
await activeStreamQueries.create(taskId, streamId);
|
|
10425
|
+
const taskStreamProducer = () => {
|
|
10426
|
+
const { readable, writable } = new TransformStream();
|
|
10427
|
+
const writer = writable.getWriter();
|
|
10428
|
+
let writerClosed = false;
|
|
10429
|
+
const writeSSE = async (data) => {
|
|
10430
|
+
if (writerClosed) return;
|
|
10431
|
+
try {
|
|
10432
|
+
await writer.write(`data: ${data}
|
|
10433
|
+
|
|
10434
|
+
`);
|
|
10435
|
+
} catch {
|
|
10436
|
+
writerClosed = true;
|
|
10437
|
+
}
|
|
10438
|
+
};
|
|
10439
|
+
(async () => {
|
|
10440
|
+
await writeSSE(JSON.stringify({ type: "data-stream-id", streamId }));
|
|
10441
|
+
try {
|
|
10442
|
+
await agent.runTask({
|
|
10443
|
+
prompt: body.prompt,
|
|
10444
|
+
taskConfig,
|
|
10445
|
+
abortSignal: abortController.signal,
|
|
10446
|
+
writeSSE
|
|
10323
10447
|
});
|
|
10324
|
-
|
|
10325
|
-
|
|
10326
|
-
|
|
10327
|
-
|
|
10328
|
-
|
|
10329
|
-
|
|
10330
|
-
|
|
10331
|
-
|
|
10448
|
+
await writeSSE(JSON.stringify({ type: "finish" }));
|
|
10449
|
+
} catch (err) {
|
|
10450
|
+
if (err.name === "AbortError" || abortController.signal.aborted) {
|
|
10451
|
+
console.log(`[TASK] Task ${taskId} was cancelled`);
|
|
10452
|
+
await writeSSE(JSON.stringify({ type: "abort" }));
|
|
10453
|
+
} else {
|
|
10454
|
+
console.error(`[TASK] Error in task ${taskId}:`, err.message);
|
|
10455
|
+
const errorMsg = err.message || "Unknown error";
|
|
10456
|
+
await writeSSE(JSON.stringify({ type: "error", errorText: errorMsg }));
|
|
10457
|
+
const failedTask = {
|
|
10458
|
+
...taskConfig,
|
|
10459
|
+
status: "failed",
|
|
10460
|
+
error: errorMsg
|
|
10461
|
+
};
|
|
10462
|
+
await sessionQueries.update(taskId, {
|
|
10463
|
+
config: {
|
|
10464
|
+
toolApprovals: { bash: false, write_file: false, read_file: false },
|
|
10465
|
+
task: failedTask
|
|
10466
|
+
}
|
|
10332
10467
|
});
|
|
10468
|
+
if (taskConfig.webhookUrl) {
|
|
10469
|
+
const { sendWebhook: sendWebhook2 } = await Promise.resolve().then(() => (init_webhook(), webhook_exports));
|
|
10470
|
+
sendWebhook2(taskConfig.webhookUrl, {
|
|
10471
|
+
type: "task.failed",
|
|
10472
|
+
taskId,
|
|
10473
|
+
sessionId: taskId,
|
|
10474
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10475
|
+
data: { status: "failed", error: errorMsg }
|
|
10476
|
+
});
|
|
10477
|
+
}
|
|
10333
10478
|
}
|
|
10479
|
+
} finally {
|
|
10480
|
+
await writeSSE("[DONE]");
|
|
10481
|
+
writer.close().catch(() => {
|
|
10482
|
+
});
|
|
10483
|
+
await activeStreamQueries.finish(streamId).catch(() => {
|
|
10484
|
+
});
|
|
10485
|
+
taskAbortControllers.delete(taskId);
|
|
10334
10486
|
}
|
|
10335
|
-
}
|
|
10336
|
-
|
|
10337
|
-
|
|
10338
|
-
|
|
10487
|
+
})();
|
|
10488
|
+
return readable;
|
|
10489
|
+
};
|
|
10490
|
+
await streamContext.resumableStream(streamId, taskStreamProducer);
|
|
10339
10491
|
return c.json({ taskId, status: "running" }, 201);
|
|
10340
10492
|
}
|
|
10341
10493
|
);
|