sparkecoder 0.1.66 → 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 +3 -3
- package/dist/agent/index.js +141 -13
- package/dist/agent/index.js.map +1 -1
- package/dist/cli.js +206 -48
- package/dist/cli.js.map +1 -1
- package/dist/db/index.d.ts +2 -2
- package/dist/{index-Db23cukG.d.ts → index-Dm6wGcYv.d.ts} +26 -25
- package/dist/index.d.ts +5 -5
- package/dist/index.js +206 -48
- package/dist/index.js.map +1 -1
- package/dist/{schema-C7Mm4Ykn.d.ts → schema-XcP0dedO.d.ts} +3 -3
- package/dist/{search-CVVfuBPZ.d.ts → search-CCffrVJE.d.ts} +4 -4
- package/dist/server/index.js +206 -48
- package/dist/server/index.js.map +1 -1
- package/dist/tools/index.d.ts +3 -3
- 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/{UMGGmtMDTCI6fL-AIFkiM → 6Dlxqhgk8Mki7q7L-gDbl}/_buildManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/{UMGGmtMDTCI6fL-AIFkiM → 6Dlxqhgk8Mki7q7L-gDbl}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/standalone/web/.next/static/{UMGGmtMDTCI6fL-AIFkiM → 6Dlxqhgk8Mki7q7L-gDbl}/_ssgManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/static/{UMGGmtMDTCI6fL-AIFkiM → 6Dlxqhgk8Mki7q7L-gDbl}/_buildManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/static/{UMGGmtMDTCI6fL-AIFkiM → 6Dlxqhgk8Mki7q7L-gDbl}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/standalone/web/.next/static/static/{UMGGmtMDTCI6fL-AIFkiM → 6Dlxqhgk8Mki7q7L-gDbl}/_ssgManifest.js +0 -0
- /package/web/.next/static/{UMGGmtMDTCI6fL-AIFkiM → 6Dlxqhgk8Mki7q7L-gDbl}/_buildManifest.js +0 -0
- /package/web/.next/static/{UMGGmtMDTCI6fL-AIFkiM → 6Dlxqhgk8Mki7q7L-gDbl}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{UMGGmtMDTCI6fL-AIFkiM → 6Dlxqhgk8Mki7q7L-gDbl}/_ssgManifest.js +0 -0
package/dist/cli.js
CHANGED
|
@@ -6969,12 +6969,18 @@ Before calling \`complete_task\`, you MUST verify your work completely. Do not j
|
|
|
6969
6969
|
- If the task asked for multiple things, verify EACH one individually.
|
|
6970
6970
|
- If something doesn't look right, fix it \u2014 don't complete with known issues.
|
|
6971
6971
|
|
|
6972
|
+
**Screenshot your completed work:**
|
|
6973
|
+
- After completing a task, take a screenshot of the result when it makes sense (UI changes browser pages, etc.). You can use the browser skill to do this.
|
|
6974
|
+
- Use \`upload_file\` to upload the screenshot and include the download URL in your task result so the user can see proof of what was done.
|
|
6975
|
+
- This is especially valuable for UI/visual changes, successful test runs, and browser verification \u2014 show, don't just tell.
|
|
6976
|
+
|
|
6972
6977
|
### Use All Available Tools
|
|
6973
6978
|
- **load_skill**: Load specialized skills/knowledge relevant to the task. Check what skills are available and use them.
|
|
6974
6979
|
- **explore_agent**: Use for codebase exploration and understanding before making changes.
|
|
6975
6980
|
- **code_graph**: Use to understand type hierarchies, references, and impact before refactoring.
|
|
6976
6981
|
- **todo**: Track your progress on multi-step tasks so you don't miss steps.
|
|
6977
6982
|
- **bash**: Full shell access \u2014 run builds, tests, dev servers, open browsers, curl endpoints, anything.
|
|
6983
|
+
- **upload_file**: Upload files (screenshots, reports, exports) to cloud storage. Use this to include screenshots of completed work in your task result \u2014 visual proof is very helpful.
|
|
6978
6984
|
|
|
6979
6985
|
### Output Schema
|
|
6980
6986
|
The \`complete_task\` tool expects a \`result\` object matching this JSON Schema:
|
|
@@ -7250,6 +7256,21 @@ ${this.summary}`
|
|
|
7250
7256
|
|
|
7251
7257
|
// src/agent/index.ts
|
|
7252
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
|
+
}
|
|
7253
7274
|
var approvalResolvers = /* @__PURE__ */ new Map();
|
|
7254
7275
|
var Agent = class _Agent {
|
|
7255
7276
|
session;
|
|
@@ -7493,8 +7514,11 @@ ${prompt}` });
|
|
|
7493
7514
|
};
|
|
7494
7515
|
let taskRecorder = null;
|
|
7495
7516
|
const sessionId = this.session.id;
|
|
7517
|
+
const emit = options.writeSSE;
|
|
7496
7518
|
const bashProgressHandler = (progress) => {
|
|
7497
7519
|
options.onToolProgress?.({ toolName: "bash", data: progress });
|
|
7520
|
+
if (emit) emit(JSON.stringify({ type: "tool-progress", toolName: "bash", data: progress })).catch(() => {
|
|
7521
|
+
});
|
|
7498
7522
|
const port = progress.browserStreamPort;
|
|
7499
7523
|
if (port && progress.status === "started") {
|
|
7500
7524
|
Promise.resolve().then(() => (init_stream_proxy(), stream_proxy_exports)).then(({ getOrCreateProxy: getOrCreateProxy2 }) => {
|
|
@@ -7503,7 +7527,17 @@ ${prompt}` });
|
|
|
7503
7527
|
Promise.resolve().then(() => (init_recorder(), recorder_exports)).then(({ FrameRecorder: FrameRecorder2 }) => {
|
|
7504
7528
|
taskRecorder = new FrameRecorder2(sessionId);
|
|
7505
7529
|
taskRecorder.start();
|
|
7506
|
-
|
|
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
|
+
});
|
|
7507
7541
|
});
|
|
7508
7542
|
}
|
|
7509
7543
|
});
|
|
@@ -7514,8 +7548,16 @@ ${prompt}` });
|
|
|
7514
7548
|
workingDirectory: this.session.workingDirectory,
|
|
7515
7549
|
skillsDirectories: config.resolvedSkillsDirectories,
|
|
7516
7550
|
onBashProgress: bashProgressHandler,
|
|
7517
|
-
onWriteFileProgress:
|
|
7518
|
-
|
|
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
|
+
},
|
|
7519
7561
|
taskTools: {
|
|
7520
7562
|
outputSchema: options.taskConfig.outputSchema,
|
|
7521
7563
|
onComplete
|
|
@@ -7533,6 +7575,9 @@ ${prompt}` });
|
|
|
7533
7575
|
|
|
7534
7576
|
${taskAddendum}`;
|
|
7535
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
|
+
}
|
|
7536
7581
|
await this.context.addUserMessage(options.prompt);
|
|
7537
7582
|
let iteration = 0;
|
|
7538
7583
|
while (iteration < maxIterations) {
|
|
@@ -7544,7 +7589,15 @@ ${taskAddendum}`;
|
|
|
7544
7589
|
}
|
|
7545
7590
|
const messages = await this.context.getMessages();
|
|
7546
7591
|
const useAnthropic = isAnthropicModel(this.session.model);
|
|
7547
|
-
|
|
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({
|
|
7548
7601
|
model: resolveModel(this.session.model),
|
|
7549
7602
|
system: systemPrompt,
|
|
7550
7603
|
messages,
|
|
@@ -7553,21 +7606,94 @@ ${taskAddendum}`;
|
|
|
7553
7606
|
abortSignal: options.abortSignal,
|
|
7554
7607
|
providerOptions: useAnthropic ? {
|
|
7555
7608
|
anthropic: {
|
|
7609
|
+
toolStreaming: true,
|
|
7556
7610
|
thinking: { type: "enabled", budgetTokens: 1e4 }
|
|
7557
7611
|
}
|
|
7558
7612
|
} : void 0,
|
|
7559
|
-
onStepFinish: (step) => {
|
|
7613
|
+
onStepFinish: async (step) => {
|
|
7560
7614
|
options.onStepFinish?.(step);
|
|
7561
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
|
+
}
|
|
7562
7624
|
}
|
|
7563
7625
|
});
|
|
7564
|
-
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;
|
|
7565
7689
|
await this.context.addResponseMessages(responseMessages);
|
|
7566
|
-
|
|
7567
|
-
|
|
7568
|
-
|
|
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 });
|
|
7569
7695
|
}
|
|
7570
|
-
for (const step of
|
|
7696
|
+
for (const step of resultSteps) {
|
|
7571
7697
|
if (step.toolCalls) {
|
|
7572
7698
|
for (const tc of step.toolCalls) {
|
|
7573
7699
|
options.onToolCall?.({ toolCallId: tc.toolCallId, toolName: tc.toolName, input: tc.args });
|
|
@@ -7620,9 +7746,11 @@ ${taskAddendum}`;
|
|
|
7620
7746
|
iterations: iteration
|
|
7621
7747
|
};
|
|
7622
7748
|
}
|
|
7623
|
-
|
|
7624
|
-
|
|
7625
|
-
|
|
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);
|
|
7626
7754
|
}
|
|
7627
7755
|
const timeoutError = `Task did not complete within ${maxIterations} iterations`;
|
|
7628
7756
|
const timeoutRecordingUrls = await this.finishTaskRecording(taskRecorder);
|
|
@@ -10254,6 +10382,7 @@ init_db();
|
|
|
10254
10382
|
import { Hono as Hono5 } from "hono";
|
|
10255
10383
|
import { zValidator as zValidator5 } from "@hono/zod-validator";
|
|
10256
10384
|
import { z as z19 } from "zod";
|
|
10385
|
+
import { nanoid as nanoid7 } from "nanoid";
|
|
10257
10386
|
init_config();
|
|
10258
10387
|
var tasks = new Hono5();
|
|
10259
10388
|
var taskAbortControllers = /* @__PURE__ */ new Map();
|
|
@@ -10291,45 +10420,74 @@ tasks.post(
|
|
|
10291
10420
|
const taskId = agent.sessionId;
|
|
10292
10421
|
const abortController = new AbortController();
|
|
10293
10422
|
taskAbortControllers.set(taskId, abortController);
|
|
10294
|
-
|
|
10295
|
-
|
|
10296
|
-
|
|
10297
|
-
|
|
10298
|
-
|
|
10299
|
-
|
|
10300
|
-
|
|
10301
|
-
|
|
10302
|
-
|
|
10303
|
-
|
|
10304
|
-
|
|
10305
|
-
|
|
10306
|
-
|
|
10307
|
-
|
|
10308
|
-
|
|
10309
|
-
|
|
10310
|
-
|
|
10311
|
-
|
|
10312
|
-
|
|
10313
|
-
|
|
10314
|
-
|
|
10315
|
-
|
|
10316
|
-
|
|
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
|
|
10317
10447
|
});
|
|
10318
|
-
|
|
10319
|
-
|
|
10320
|
-
|
|
10321
|
-
|
|
10322
|
-
|
|
10323
|
-
|
|
10324
|
-
|
|
10325
|
-
|
|
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
|
+
}
|
|
10326
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
|
+
}
|
|
10327
10478
|
}
|
|
10479
|
+
} finally {
|
|
10480
|
+
await writeSSE("[DONE]");
|
|
10481
|
+
writer.close().catch(() => {
|
|
10482
|
+
});
|
|
10483
|
+
await activeStreamQueries.finish(streamId).catch(() => {
|
|
10484
|
+
});
|
|
10485
|
+
taskAbortControllers.delete(taskId);
|
|
10328
10486
|
}
|
|
10329
|
-
}
|
|
10330
|
-
|
|
10331
|
-
|
|
10332
|
-
|
|
10487
|
+
})();
|
|
10488
|
+
return readable;
|
|
10489
|
+
};
|
|
10490
|
+
await streamContext.resumableStream(streamId, taskStreamProducer);
|
|
10333
10491
|
return c.json({ taskId, status: "running" }, 201);
|
|
10334
10492
|
}
|
|
10335
10493
|
);
|