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
|
@@ -85,7 +85,7 @@ declare const sessions: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
|
|
|
85
85
|
tableName: "sessions";
|
|
86
86
|
dataType: "string";
|
|
87
87
|
columnType: "SQLiteText";
|
|
88
|
-
data: "
|
|
88
|
+
data: "error" | "completed" | "active" | "waiting";
|
|
89
89
|
driverParam: string;
|
|
90
90
|
notNull: true;
|
|
91
91
|
hasDefault: true;
|
|
@@ -391,7 +391,7 @@ declare const toolExecutions: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
|
|
|
391
391
|
tableName: "tool_executions";
|
|
392
392
|
dataType: "string";
|
|
393
393
|
columnType: "SQLiteText";
|
|
394
|
-
data: "
|
|
394
|
+
data: "error" | "completed" | "pending" | "approved" | "rejected";
|
|
395
395
|
driverParam: string;
|
|
396
396
|
notNull: true;
|
|
397
397
|
hasDefault: true;
|
|
@@ -814,7 +814,7 @@ declare const terminals: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
|
|
|
814
814
|
tableName: "terminals";
|
|
815
815
|
dataType: "string";
|
|
816
816
|
columnType: "SQLiteText";
|
|
817
|
-
data: "
|
|
817
|
+
data: "error" | "running" | "stopped";
|
|
818
818
|
driverParam: string;
|
|
819
819
|
notNull: true;
|
|
820
820
|
hasDefault: true;
|
|
@@ -15,12 +15,12 @@ interface BashToolOptions {
|
|
|
15
15
|
}
|
|
16
16
|
declare function createBashTool(options: BashToolOptions): ai.Tool<{
|
|
17
17
|
background: boolean;
|
|
18
|
-
id?: string | undefined;
|
|
19
18
|
input?: string | undefined;
|
|
19
|
+
id?: string | undefined;
|
|
20
20
|
command?: string | undefined;
|
|
21
21
|
kill?: boolean | undefined;
|
|
22
22
|
tail?: number | undefined;
|
|
23
|
-
key?: "Enter" | "Escape" | "Up" | "Down" | "Left" | "Right" | "Tab" | "C-c" | "C-d" | "
|
|
23
|
+
key?: "y" | "Enter" | "Escape" | "Up" | "Down" | "Left" | "Right" | "Tab" | "C-c" | "C-d" | "n" | undefined;
|
|
24
24
|
}, {
|
|
25
25
|
success: boolean;
|
|
26
26
|
id: string;
|
|
@@ -66,7 +66,7 @@ declare function createBashTool(options: BashToolOptions): ai.Tool<{
|
|
|
66
66
|
id: string;
|
|
67
67
|
output: string;
|
|
68
68
|
exitCode: number;
|
|
69
|
-
status: "
|
|
69
|
+
status: "error" | "completed" | "running" | "stopped";
|
|
70
70
|
message?: undefined;
|
|
71
71
|
error?: undefined;
|
|
72
72
|
} | {
|
|
@@ -218,8 +218,8 @@ interface SearchToolOptions {
|
|
|
218
218
|
* Progress is streamed back to the UI so users can see exploration happening.
|
|
219
219
|
*/
|
|
220
220
|
declare function createSearchTool(options: SearchToolOptions): ai.Tool<{
|
|
221
|
-
query: string;
|
|
222
221
|
context: string;
|
|
222
|
+
query: string;
|
|
223
223
|
}, {
|
|
224
224
|
success: boolean;
|
|
225
225
|
error: string;
|
package/dist/server/index.js
CHANGED
|
@@ -6191,12 +6191,18 @@ Before calling \`complete_task\`, you MUST verify your work completely. Do not j
|
|
|
6191
6191
|
- If the task asked for multiple things, verify EACH one individually.
|
|
6192
6192
|
- If something doesn't look right, fix it \u2014 don't complete with known issues.
|
|
6193
6193
|
|
|
6194
|
+
**Screenshot your completed work:**
|
|
6195
|
+
- 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.
|
|
6196
|
+
- 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.
|
|
6197
|
+
- This is especially valuable for UI/visual changes, successful test runs, and browser verification \u2014 show, don't just tell.
|
|
6198
|
+
|
|
6194
6199
|
### Use All Available Tools
|
|
6195
6200
|
- **load_skill**: Load specialized skills/knowledge relevant to the task. Check what skills are available and use them.
|
|
6196
6201
|
- **explore_agent**: Use for codebase exploration and understanding before making changes.
|
|
6197
6202
|
- **code_graph**: Use to understand type hierarchies, references, and impact before refactoring.
|
|
6198
6203
|
- **todo**: Track your progress on multi-step tasks so you don't miss steps.
|
|
6199
6204
|
- **bash**: Full shell access \u2014 run builds, tests, dev servers, open browsers, curl endpoints, anything.
|
|
6205
|
+
- **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.
|
|
6200
6206
|
|
|
6201
6207
|
### Output Schema
|
|
6202
6208
|
The \`complete_task\` tool expects a \`result\` object matching this JSON Schema:
|
|
@@ -6472,6 +6478,21 @@ ${this.summary}`
|
|
|
6472
6478
|
|
|
6473
6479
|
// src/agent/index.ts
|
|
6474
6480
|
init_webhook();
|
|
6481
|
+
var MAX_SSE_FIELD_LENGTH = 8 * 1024;
|
|
6482
|
+
var SSE_PREVIEW_LENGTH = 2 * 1024;
|
|
6483
|
+
function truncateWriteFileInput(input) {
|
|
6484
|
+
const out = { ...input };
|
|
6485
|
+
for (const key of ["content", "old_string", "new_string"]) {
|
|
6486
|
+
const val = out[key];
|
|
6487
|
+
if (typeof val === "string" && val.length > MAX_SSE_FIELD_LENGTH) {
|
|
6488
|
+
out[key] = `${val.slice(0, SSE_PREVIEW_LENGTH)}
|
|
6489
|
+
... (truncated)`;
|
|
6490
|
+
out[`${key}Truncated`] = true;
|
|
6491
|
+
out[`${key}Length`] = val.length;
|
|
6492
|
+
}
|
|
6493
|
+
}
|
|
6494
|
+
return out;
|
|
6495
|
+
}
|
|
6475
6496
|
var approvalResolvers = /* @__PURE__ */ new Map();
|
|
6476
6497
|
var Agent = class _Agent {
|
|
6477
6498
|
session;
|
|
@@ -6715,8 +6736,11 @@ ${prompt}` });
|
|
|
6715
6736
|
};
|
|
6716
6737
|
let taskRecorder = null;
|
|
6717
6738
|
const sessionId = this.session.id;
|
|
6739
|
+
const emit = options.writeSSE;
|
|
6718
6740
|
const bashProgressHandler = (progress) => {
|
|
6719
6741
|
options.onToolProgress?.({ toolName: "bash", data: progress });
|
|
6742
|
+
if (emit) emit(JSON.stringify({ type: "tool-progress", toolName: "bash", data: progress })).catch(() => {
|
|
6743
|
+
});
|
|
6720
6744
|
const port = progress.browserStreamPort;
|
|
6721
6745
|
if (port && progress.status === "started") {
|
|
6722
6746
|
Promise.resolve().then(() => (init_stream_proxy(), stream_proxy_exports)).then(({ getOrCreateProxy: getOrCreateProxy2 }) => {
|
|
@@ -6725,7 +6749,17 @@ ${prompt}` });
|
|
|
6725
6749
|
Promise.resolve().then(() => (init_recorder(), recorder_exports)).then(({ FrameRecorder: FrameRecorder2 }) => {
|
|
6726
6750
|
taskRecorder = new FrameRecorder2(sessionId);
|
|
6727
6751
|
taskRecorder.start();
|
|
6728
|
-
|
|
6752
|
+
});
|
|
6753
|
+
}
|
|
6754
|
+
if (proxy.listenerCount("frame") === 0) {
|
|
6755
|
+
proxy.on("frame", (frame) => {
|
|
6756
|
+
taskRecorder?.addFrame(frame);
|
|
6757
|
+
if (emit) emit(JSON.stringify({ type: "browser-frame", data: frame.data, metadata: frame.metadata })).catch(() => {
|
|
6758
|
+
});
|
|
6759
|
+
});
|
|
6760
|
+
proxy.on("status", (s) => {
|
|
6761
|
+
if (emit) emit(JSON.stringify({ type: "browser-status", ...s })).catch(() => {
|
|
6762
|
+
});
|
|
6729
6763
|
});
|
|
6730
6764
|
}
|
|
6731
6765
|
});
|
|
@@ -6736,8 +6770,16 @@ ${prompt}` });
|
|
|
6736
6770
|
workingDirectory: this.session.workingDirectory,
|
|
6737
6771
|
skillsDirectories: config.resolvedSkillsDirectories,
|
|
6738
6772
|
onBashProgress: bashProgressHandler,
|
|
6739
|
-
onWriteFileProgress:
|
|
6740
|
-
|
|
6773
|
+
onWriteFileProgress: (progress) => {
|
|
6774
|
+
options.onToolProgress?.({ toolName: "write_file", data: progress });
|
|
6775
|
+
if (emit) emit(JSON.stringify({ type: "tool-progress", toolName: "write_file", data: progress })).catch(() => {
|
|
6776
|
+
});
|
|
6777
|
+
},
|
|
6778
|
+
onSearchProgress: (progress) => {
|
|
6779
|
+
options.onToolProgress?.({ toolName: "explore_agent", data: progress });
|
|
6780
|
+
if (emit) emit(JSON.stringify({ type: "tool-progress", toolName: "explore_agent", data: progress })).catch(() => {
|
|
6781
|
+
});
|
|
6782
|
+
},
|
|
6741
6783
|
taskTools: {
|
|
6742
6784
|
outputSchema: options.taskConfig.outputSchema,
|
|
6743
6785
|
onComplete
|
|
@@ -6755,6 +6797,9 @@ ${prompt}` });
|
|
|
6755
6797
|
|
|
6756
6798
|
${taskAddendum}`;
|
|
6757
6799
|
fireWebhook("task.started", { prompt: options.prompt });
|
|
6800
|
+
if (emit) {
|
|
6801
|
+
await emit(JSON.stringify({ type: "data-user-message", data: { id: `user_${Date.now()}`, content: options.prompt } }));
|
|
6802
|
+
}
|
|
6758
6803
|
await this.context.addUserMessage(options.prompt);
|
|
6759
6804
|
let iteration = 0;
|
|
6760
6805
|
while (iteration < maxIterations) {
|
|
@@ -6766,7 +6811,15 @@ ${taskAddendum}`;
|
|
|
6766
6811
|
}
|
|
6767
6812
|
const messages = await this.context.getMessages();
|
|
6768
6813
|
const useAnthropic = isAnthropicModel(this.session.model);
|
|
6769
|
-
|
|
6814
|
+
if (emit) {
|
|
6815
|
+
await emit(JSON.stringify({ type: "start", messageId: `msg_${Date.now()}` }));
|
|
6816
|
+
}
|
|
6817
|
+
let textStarted = false;
|
|
6818
|
+
let textId = `text_${Date.now()}`;
|
|
6819
|
+
let reasoningId = `reasoning_${Date.now()}`;
|
|
6820
|
+
let reasoningStarted = false;
|
|
6821
|
+
const toolCallStarts = /* @__PURE__ */ new Set();
|
|
6822
|
+
const iterStream = streamText2({
|
|
6770
6823
|
model: resolveModel(this.session.model),
|
|
6771
6824
|
system: systemPrompt,
|
|
6772
6825
|
messages,
|
|
@@ -6775,21 +6828,94 @@ ${taskAddendum}`;
|
|
|
6775
6828
|
abortSignal: options.abortSignal,
|
|
6776
6829
|
providerOptions: useAnthropic ? {
|
|
6777
6830
|
anthropic: {
|
|
6831
|
+
toolStreaming: true,
|
|
6778
6832
|
thinking: { type: "enabled", budgetTokens: 1e4 }
|
|
6779
6833
|
}
|
|
6780
6834
|
} : void 0,
|
|
6781
|
-
onStepFinish: (step) => {
|
|
6835
|
+
onStepFinish: async (step) => {
|
|
6782
6836
|
options.onStepFinish?.(step);
|
|
6783
6837
|
fireWebhook("task.step_finished", { iteration, text: step.text });
|
|
6838
|
+
if (emit) {
|
|
6839
|
+
if (textStarted) {
|
|
6840
|
+
await emit(JSON.stringify({ type: "text-end", id: textId }));
|
|
6841
|
+
textStarted = false;
|
|
6842
|
+
textId = `text_${Date.now()}`;
|
|
6843
|
+
}
|
|
6844
|
+
await emit(JSON.stringify({ type: "finish-step" }));
|
|
6845
|
+
}
|
|
6784
6846
|
}
|
|
6785
6847
|
});
|
|
6786
|
-
const
|
|
6848
|
+
for await (const part of iterStream.fullStream) {
|
|
6849
|
+
if (part.type === "text-delta") {
|
|
6850
|
+
if (emit) {
|
|
6851
|
+
if (!textStarted) {
|
|
6852
|
+
await emit(JSON.stringify({ type: "text-start", id: textId }));
|
|
6853
|
+
textStarted = true;
|
|
6854
|
+
}
|
|
6855
|
+
await emit(JSON.stringify({ type: "text-delta", id: textId, delta: part.text }));
|
|
6856
|
+
}
|
|
6857
|
+
} else if (part.type === "reasoning-start") {
|
|
6858
|
+
if (emit) {
|
|
6859
|
+
await emit(JSON.stringify({ type: "reasoning-start", id: reasoningId }));
|
|
6860
|
+
reasoningStarted = true;
|
|
6861
|
+
}
|
|
6862
|
+
} else if (part.type === "reasoning-delta") {
|
|
6863
|
+
if (emit) {
|
|
6864
|
+
await emit(JSON.stringify({ type: "reasoning-delta", id: reasoningId, delta: part.text }));
|
|
6865
|
+
}
|
|
6866
|
+
} else if (part.type === "reasoning-end") {
|
|
6867
|
+
if (emit && reasoningStarted) {
|
|
6868
|
+
await emit(JSON.stringify({ type: "reasoning-end", id: reasoningId }));
|
|
6869
|
+
reasoningStarted = false;
|
|
6870
|
+
reasoningId = `reasoning_${Date.now()}`;
|
|
6871
|
+
}
|
|
6872
|
+
} else if (part.type === "tool-call-streaming-start") {
|
|
6873
|
+
if (emit) {
|
|
6874
|
+
const p = part;
|
|
6875
|
+
await emit(JSON.stringify({ type: "tool-input-start", toolCallId: p.toolCallId, toolName: p.toolName }));
|
|
6876
|
+
toolCallStarts.add(p.toolCallId);
|
|
6877
|
+
}
|
|
6878
|
+
} else if (part.type === "tool-call-delta") {
|
|
6879
|
+
if (emit) {
|
|
6880
|
+
const p = part;
|
|
6881
|
+
await emit(JSON.stringify({ type: "tool-input-delta", toolCallId: p.toolCallId, argsTextDelta: p.argsTextDelta }));
|
|
6882
|
+
}
|
|
6883
|
+
} else if (part.type === "tool-call") {
|
|
6884
|
+
if (emit) {
|
|
6885
|
+
if (!toolCallStarts.has(part.toolCallId)) {
|
|
6886
|
+
await emit(JSON.stringify({ type: "tool-input-start", toolCallId: part.toolCallId, toolName: part.toolName }));
|
|
6887
|
+
toolCallStarts.add(part.toolCallId);
|
|
6888
|
+
}
|
|
6889
|
+
const safeInput = part.toolName === "write_file" && part.input && typeof part.input === "object" ? truncateWriteFileInput(part.input) : part.input;
|
|
6890
|
+
await emit(JSON.stringify({ type: "tool-input-available", toolCallId: part.toolCallId, toolName: part.toolName, input: safeInput }));
|
|
6891
|
+
}
|
|
6892
|
+
} else if (part.type === "tool-result") {
|
|
6893
|
+
if (emit) {
|
|
6894
|
+
await emit(JSON.stringify({ type: "tool-output-available", toolCallId: part.toolCallId, output: part.output }));
|
|
6895
|
+
}
|
|
6896
|
+
} else if (part.type === "error") {
|
|
6897
|
+
console.error("Task stream error:", part.error);
|
|
6898
|
+
if (emit) {
|
|
6899
|
+
await emit(JSON.stringify({ type: "error", errorText: String(part.error) }));
|
|
6900
|
+
}
|
|
6901
|
+
}
|
|
6902
|
+
}
|
|
6903
|
+
if (emit && textStarted) {
|
|
6904
|
+
await emit(JSON.stringify({ type: "text-end", id: textId }));
|
|
6905
|
+
}
|
|
6906
|
+
if (emit && reasoningStarted) {
|
|
6907
|
+
await emit(JSON.stringify({ type: "reasoning-end", id: reasoningId }));
|
|
6908
|
+
}
|
|
6909
|
+
const iterResponse = await iterStream.response;
|
|
6910
|
+
const responseMessages = iterResponse.messages;
|
|
6787
6911
|
await this.context.addResponseMessages(responseMessages);
|
|
6788
|
-
|
|
6789
|
-
|
|
6790
|
-
|
|
6912
|
+
const resultText = await iterStream.text;
|
|
6913
|
+
const resultSteps = await iterStream.steps;
|
|
6914
|
+
if (resultText) {
|
|
6915
|
+
options.onText?.(resultText);
|
|
6916
|
+
fireWebhook("task.message", { iteration, text: resultText });
|
|
6791
6917
|
}
|
|
6792
|
-
for (const step of
|
|
6918
|
+
for (const step of resultSteps) {
|
|
6793
6919
|
if (step.toolCalls) {
|
|
6794
6920
|
for (const tc of step.toolCalls) {
|
|
6795
6921
|
options.onToolCall?.({ toolCallId: tc.toolCallId, toolName: tc.toolName, input: tc.args });
|
|
@@ -6842,9 +6968,11 @@ ${taskAddendum}`;
|
|
|
6842
6968
|
iterations: iteration
|
|
6843
6969
|
};
|
|
6844
6970
|
}
|
|
6845
|
-
|
|
6846
|
-
|
|
6847
|
-
|
|
6971
|
+
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.";
|
|
6972
|
+
if (emit) {
|
|
6973
|
+
await emit(JSON.stringify({ type: "data-user-message", data: { id: `user_${Date.now()}`, content: continuationPrompt } }));
|
|
6974
|
+
}
|
|
6975
|
+
await this.context.addUserMessage(continuationPrompt);
|
|
6848
6976
|
}
|
|
6849
6977
|
const timeoutError = `Task did not complete within ${maxIterations} iterations`;
|
|
6850
6978
|
const timeoutRecordingUrls = await this.finishTaskRecording(taskRecorder);
|
|
@@ -9476,6 +9604,7 @@ init_db();
|
|
|
9476
9604
|
import { Hono as Hono5 } from "hono";
|
|
9477
9605
|
import { zValidator as zValidator5 } from "@hono/zod-validator";
|
|
9478
9606
|
import { z as z19 } from "zod";
|
|
9607
|
+
import { nanoid as nanoid7 } from "nanoid";
|
|
9479
9608
|
init_config();
|
|
9480
9609
|
var tasks = new Hono5();
|
|
9481
9610
|
var taskAbortControllers = /* @__PURE__ */ new Map();
|
|
@@ -9513,45 +9642,74 @@ tasks.post(
|
|
|
9513
9642
|
const taskId = agent.sessionId;
|
|
9514
9643
|
const abortController = new AbortController();
|
|
9515
9644
|
taskAbortControllers.set(taskId, abortController);
|
|
9516
|
-
|
|
9517
|
-
|
|
9518
|
-
|
|
9519
|
-
|
|
9520
|
-
|
|
9521
|
-
|
|
9522
|
-
|
|
9523
|
-
|
|
9524
|
-
|
|
9525
|
-
|
|
9526
|
-
|
|
9527
|
-
|
|
9528
|
-
|
|
9529
|
-
|
|
9530
|
-
|
|
9531
|
-
|
|
9532
|
-
|
|
9533
|
-
|
|
9534
|
-
|
|
9535
|
-
|
|
9536
|
-
|
|
9537
|
-
|
|
9538
|
-
|
|
9645
|
+
const streamId = `stream_${taskId}_${nanoid7(10)}`;
|
|
9646
|
+
await activeStreamQueries.create(taskId, streamId);
|
|
9647
|
+
const taskStreamProducer = () => {
|
|
9648
|
+
const { readable, writable } = new TransformStream();
|
|
9649
|
+
const writer = writable.getWriter();
|
|
9650
|
+
let writerClosed = false;
|
|
9651
|
+
const writeSSE = async (data) => {
|
|
9652
|
+
if (writerClosed) return;
|
|
9653
|
+
try {
|
|
9654
|
+
await writer.write(`data: ${data}
|
|
9655
|
+
|
|
9656
|
+
`);
|
|
9657
|
+
} catch {
|
|
9658
|
+
writerClosed = true;
|
|
9659
|
+
}
|
|
9660
|
+
};
|
|
9661
|
+
(async () => {
|
|
9662
|
+
await writeSSE(JSON.stringify({ type: "data-stream-id", streamId }));
|
|
9663
|
+
try {
|
|
9664
|
+
await agent.runTask({
|
|
9665
|
+
prompt: body.prompt,
|
|
9666
|
+
taskConfig,
|
|
9667
|
+
abortSignal: abortController.signal,
|
|
9668
|
+
writeSSE
|
|
9539
9669
|
});
|
|
9540
|
-
|
|
9541
|
-
|
|
9542
|
-
|
|
9543
|
-
|
|
9544
|
-
|
|
9545
|
-
|
|
9546
|
-
|
|
9547
|
-
|
|
9670
|
+
await writeSSE(JSON.stringify({ type: "finish" }));
|
|
9671
|
+
} catch (err) {
|
|
9672
|
+
if (err.name === "AbortError" || abortController.signal.aborted) {
|
|
9673
|
+
console.log(`[TASK] Task ${taskId} was cancelled`);
|
|
9674
|
+
await writeSSE(JSON.stringify({ type: "abort" }));
|
|
9675
|
+
} else {
|
|
9676
|
+
console.error(`[TASK] Error in task ${taskId}:`, err.message);
|
|
9677
|
+
const errorMsg = err.message || "Unknown error";
|
|
9678
|
+
await writeSSE(JSON.stringify({ type: "error", errorText: errorMsg }));
|
|
9679
|
+
const failedTask = {
|
|
9680
|
+
...taskConfig,
|
|
9681
|
+
status: "failed",
|
|
9682
|
+
error: errorMsg
|
|
9683
|
+
};
|
|
9684
|
+
await sessionQueries.update(taskId, {
|
|
9685
|
+
config: {
|
|
9686
|
+
toolApprovals: { bash: false, write_file: false, read_file: false },
|
|
9687
|
+
task: failedTask
|
|
9688
|
+
}
|
|
9548
9689
|
});
|
|
9690
|
+
if (taskConfig.webhookUrl) {
|
|
9691
|
+
const { sendWebhook: sendWebhook2 } = await Promise.resolve().then(() => (init_webhook(), webhook_exports));
|
|
9692
|
+
sendWebhook2(taskConfig.webhookUrl, {
|
|
9693
|
+
type: "task.failed",
|
|
9694
|
+
taskId,
|
|
9695
|
+
sessionId: taskId,
|
|
9696
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
9697
|
+
data: { status: "failed", error: errorMsg }
|
|
9698
|
+
});
|
|
9699
|
+
}
|
|
9549
9700
|
}
|
|
9701
|
+
} finally {
|
|
9702
|
+
await writeSSE("[DONE]");
|
|
9703
|
+
writer.close().catch(() => {
|
|
9704
|
+
});
|
|
9705
|
+
await activeStreamQueries.finish(streamId).catch(() => {
|
|
9706
|
+
});
|
|
9707
|
+
taskAbortControllers.delete(taskId);
|
|
9550
9708
|
}
|
|
9551
|
-
}
|
|
9552
|
-
|
|
9553
|
-
|
|
9554
|
-
|
|
9709
|
+
})();
|
|
9710
|
+
return readable;
|
|
9711
|
+
};
|
|
9712
|
+
await streamContext.resumableStream(streamId, taskStreamProducer);
|
|
9555
9713
|
return c.json({ taskId, status: "running" }, 201);
|
|
9556
9714
|
}
|
|
9557
9715
|
);
|