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.
Files changed (91) hide show
  1. package/dist/agent/index.d.ts +3 -3
  2. package/dist/agent/index.js +141 -13
  3. package/dist/agent/index.js.map +1 -1
  4. package/dist/cli.js +206 -48
  5. package/dist/cli.js.map +1 -1
  6. package/dist/db/index.d.ts +2 -2
  7. package/dist/{index-Db23cukG.d.ts → index-Dm6wGcYv.d.ts} +26 -25
  8. package/dist/index.d.ts +5 -5
  9. package/dist/index.js +206 -48
  10. package/dist/index.js.map +1 -1
  11. package/dist/{schema-C7Mm4Ykn.d.ts → schema-XcP0dedO.d.ts} +3 -3
  12. package/dist/{search-CVVfuBPZ.d.ts → search-CCffrVJE.d.ts} +4 -4
  13. package/dist/server/index.js +206 -48
  14. package/dist/server/index.js.map +1 -1
  15. package/dist/tools/index.d.ts +3 -3
  16. package/package.json +1 -1
  17. package/web/.next/BUILD_ID +1 -1
  18. package/web/.next/standalone/web/.next/BUILD_ID +1 -1
  19. package/web/.next/standalone/web/.next/build-manifest.json +2 -2
  20. package/web/.next/standalone/web/.next/prerender-manifest.json +3 -3
  21. package/web/.next/standalone/web/.next/server/app/_global-error.html +2 -2
  22. package/web/.next/standalone/web/.next/server/app/_global-error.rsc +1 -1
  23. package/web/.next/standalone/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  24. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  25. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  26. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  27. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  28. package/web/.next/standalone/web/.next/server/app/_not-found.html +1 -1
  29. package/web/.next/standalone/web/.next/server/app/_not-found.rsc +1 -1
  30. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  31. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  32. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  33. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  34. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  35. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  36. package/web/.next/standalone/web/.next/server/app/docs/installation.html +2 -2
  37. package/web/.next/standalone/web/.next/server/app/docs/installation.rsc +1 -1
  38. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_full.segment.rsc +1 -1
  39. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_head.segment.rsc +1 -1
  40. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_index.segment.rsc +1 -1
  41. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_tree.segment.rsc +1 -1
  42. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation/__PAGE__.segment.rsc +1 -1
  43. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation.segment.rsc +1 -1
  44. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs.segment.rsc +1 -1
  45. package/web/.next/standalone/web/.next/server/app/docs/skills.html +2 -2
  46. package/web/.next/standalone/web/.next/server/app/docs/skills.rsc +1 -1
  47. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_full.segment.rsc +1 -1
  48. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_head.segment.rsc +1 -1
  49. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_index.segment.rsc +1 -1
  50. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_tree.segment.rsc +1 -1
  51. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills/__PAGE__.segment.rsc +1 -1
  52. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills.segment.rsc +1 -1
  53. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs.segment.rsc +1 -1
  54. package/web/.next/standalone/web/.next/server/app/docs/tools.html +2 -2
  55. package/web/.next/standalone/web/.next/server/app/docs/tools.rsc +1 -1
  56. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_full.segment.rsc +1 -1
  57. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_head.segment.rsc +1 -1
  58. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_index.segment.rsc +1 -1
  59. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_tree.segment.rsc +1 -1
  60. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools/__PAGE__.segment.rsc +1 -1
  61. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools.segment.rsc +1 -1
  62. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs.segment.rsc +1 -1
  63. package/web/.next/standalone/web/.next/server/app/docs.html +2 -2
  64. package/web/.next/standalone/web/.next/server/app/docs.rsc +1 -1
  65. package/web/.next/standalone/web/.next/server/app/docs.segments/_full.segment.rsc +1 -1
  66. package/web/.next/standalone/web/.next/server/app/docs.segments/_head.segment.rsc +1 -1
  67. package/web/.next/standalone/web/.next/server/app/docs.segments/_index.segment.rsc +1 -1
  68. package/web/.next/standalone/web/.next/server/app/docs.segments/_tree.segment.rsc +1 -1
  69. package/web/.next/standalone/web/.next/server/app/docs.segments/docs/__PAGE__.segment.rsc +1 -1
  70. package/web/.next/standalone/web/.next/server/app/docs.segments/docs.segment.rsc +1 -1
  71. package/web/.next/standalone/web/.next/server/app/index.html +1 -1
  72. package/web/.next/standalone/web/.next/server/app/index.rsc +1 -1
  73. package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p/__PAGE__.segment.rsc +1 -1
  74. package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p.segment.rsc +1 -1
  75. package/web/.next/standalone/web/.next/server/app/index.segments/_full.segment.rsc +1 -1
  76. package/web/.next/standalone/web/.next/server/app/index.segments/_head.segment.rsc +1 -1
  77. package/web/.next/standalone/web/.next/server/app/index.segments/_index.segment.rsc +1 -1
  78. package/web/.next/standalone/web/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  79. package/web/.next/standalone/web/.next/server/pages/404.html +1 -1
  80. package/web/.next/standalone/web/.next/server/pages/500.html +2 -2
  81. package/web/.next/standalone/web/.next/server/server-reference-manifest.js +1 -1
  82. package/web/.next/standalone/web/.next/server/server-reference-manifest.json +1 -1
  83. /package/web/.next/standalone/web/.next/static/{UMGGmtMDTCI6fL-AIFkiM → 6Dlxqhgk8Mki7q7L-gDbl}/_buildManifest.js +0 -0
  84. /package/web/.next/standalone/web/.next/static/{UMGGmtMDTCI6fL-AIFkiM → 6Dlxqhgk8Mki7q7L-gDbl}/_clientMiddlewareManifest.json +0 -0
  85. /package/web/.next/standalone/web/.next/static/{UMGGmtMDTCI6fL-AIFkiM → 6Dlxqhgk8Mki7q7L-gDbl}/_ssgManifest.js +0 -0
  86. /package/web/.next/standalone/web/.next/static/static/{UMGGmtMDTCI6fL-AIFkiM → 6Dlxqhgk8Mki7q7L-gDbl}/_buildManifest.js +0 -0
  87. /package/web/.next/standalone/web/.next/static/static/{UMGGmtMDTCI6fL-AIFkiM → 6Dlxqhgk8Mki7q7L-gDbl}/_clientMiddlewareManifest.json +0 -0
  88. /package/web/.next/standalone/web/.next/static/static/{UMGGmtMDTCI6fL-AIFkiM → 6Dlxqhgk8Mki7q7L-gDbl}/_ssgManifest.js +0 -0
  89. /package/web/.next/static/{UMGGmtMDTCI6fL-AIFkiM → 6Dlxqhgk8Mki7q7L-gDbl}/_buildManifest.js +0 -0
  90. /package/web/.next/static/{UMGGmtMDTCI6fL-AIFkiM → 6Dlxqhgk8Mki7q7L-gDbl}/_clientMiddlewareManifest.json +0 -0
  91. /package/web/.next/static/{UMGGmtMDTCI6fL-AIFkiM → 6Dlxqhgk8Mki7q7L-gDbl}/_ssgManifest.js +0 -0
@@ -1,5 +1,5 @@
1
- import { C as Checkpoint, F as FileBackup, M as ModelMessage, a as Message, S as Session, L as LoadedSkill, T as TodoItem, b as ToolExecution, A as ActiveStream, I as IndexStatusRecord, c as IndexedChunk, d as SubagentExecution, e as SubagentStep, f as Terminal } from '../schema-C7Mm4Ykn.js';
2
- export { N as NewActiveStream, g as NewCheckpoint, h as NewFileBackup, i as NewIndexStatusRecord, j as NewIndexedChunk, k as NewMessage, l as NewSession, m as NewSubagentExecution, n as NewTerminal, o as NewTodoItem, p as NewToolExecution, q as SessionConfig, r as TaskConfig, U as UserContentPart, s as UserFilePart, t as UserImagePart, u as UserModelMessage, v as UserTextPart } from '../schema-C7Mm4Ykn.js';
1
+ import { C as Checkpoint, F as FileBackup, M as ModelMessage, a as Message, S as Session, L as LoadedSkill, T as TodoItem, b as ToolExecution, A as ActiveStream, I as IndexStatusRecord, c as IndexedChunk, d as SubagentExecution, e as SubagentStep, f as Terminal } from '../schema-XcP0dedO.js';
2
+ export { N as NewActiveStream, g as NewCheckpoint, h as NewFileBackup, i as NewIndexStatusRecord, j as NewIndexedChunk, k as NewMessage, l as NewSession, m as NewSubagentExecution, n as NewTerminal, o as NewTodoItem, p as NewToolExecution, q as SessionConfig, r as TaskConfig, U as UserContentPart, s as UserFilePart, t as UserImagePart, u as UserModelMessage, v as UserTextPart } from '../schema-XcP0dedO.js';
3
3
  import 'drizzle-orm/sqlite-core';
4
4
 
5
5
  /**
@@ -1,7 +1,7 @@
1
1
  import { ModelMessage, streamText } from 'ai';
2
- import { S as Session, b as ToolExecution, r as TaskConfig } from './schema-C7Mm4Ykn.js';
2
+ import { S as Session, b as ToolExecution, r as TaskConfig } from './schema-XcP0dedO.js';
3
3
  import { z } from 'zod';
4
- import { B as BashToolProgress, W as WriteFileProgress, S as SearchToolProgress } from './search-CVVfuBPZ.js';
4
+ import { B as BashToolProgress, W as WriteFileProgress, S as SearchToolProgress } from './search-CCffrVJE.js';
5
5
 
6
6
  declare const ToolApprovalConfigSchema: z.ZodObject<{
7
7
  bash: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
@@ -37,54 +37,54 @@ declare const SessionConfigSchema: z.ZodObject<{
37
37
  error: z.ZodOptional<z.ZodString>;
38
38
  iterations: z.ZodOptional<z.ZodNumber>;
39
39
  }, "strip", z.ZodTypeAny, {
40
- status: "running" | "completed" | "failed";
41
- enabled: boolean;
40
+ status: "completed" | "failed" | "running";
42
41
  outputSchema: Record<string, unknown>;
43
- webhookUrl?: string | undefined;
42
+ enabled: boolean;
43
+ error?: string | undefined;
44
44
  maxIterations?: number | undefined;
45
+ webhookUrl?: string | undefined;
45
46
  result?: unknown;
46
- error?: string | undefined;
47
47
  iterations?: number | undefined;
48
48
  }, {
49
- status: "running" | "completed" | "failed";
50
- enabled: boolean;
49
+ status: "completed" | "failed" | "running";
51
50
  outputSchema: Record<string, unknown>;
52
- webhookUrl?: string | undefined;
51
+ enabled: boolean;
52
+ error?: string | undefined;
53
53
  maxIterations?: number | undefined;
54
+ webhookUrl?: string | undefined;
54
55
  result?: unknown;
55
- error?: string | undefined;
56
56
  iterations?: number | undefined;
57
57
  }>>;
58
58
  }, "strip", z.ZodTypeAny, {
59
59
  maxContextChars: number;
60
60
  toolApprovals?: Record<string, boolean> | undefined;
61
61
  approvalWebhook?: string | undefined;
62
- skillsDirectory?: string | undefined;
63
62
  task?: {
64
- status: "running" | "completed" | "failed";
65
- enabled: boolean;
63
+ status: "completed" | "failed" | "running";
66
64
  outputSchema: Record<string, unknown>;
67
- webhookUrl?: string | undefined;
65
+ enabled: boolean;
66
+ error?: string | undefined;
68
67
  maxIterations?: number | undefined;
68
+ webhookUrl?: string | undefined;
69
69
  result?: unknown;
70
- error?: string | undefined;
71
70
  iterations?: number | undefined;
72
71
  } | undefined;
72
+ skillsDirectory?: string | undefined;
73
73
  }, {
74
74
  toolApprovals?: Record<string, boolean> | undefined;
75
75
  approvalWebhook?: string | undefined;
76
- skillsDirectory?: string | undefined;
77
- maxContextChars?: number | undefined;
78
76
  task?: {
79
- status: "running" | "completed" | "failed";
80
- enabled: boolean;
77
+ status: "completed" | "failed" | "running";
81
78
  outputSchema: Record<string, unknown>;
82
- webhookUrl?: string | undefined;
79
+ enabled: boolean;
80
+ error?: string | undefined;
83
81
  maxIterations?: number | undefined;
82
+ webhookUrl?: string | undefined;
84
83
  result?: unknown;
85
- error?: string | undefined;
86
84
  iterations?: number | undefined;
87
85
  } | undefined;
86
+ skillsDirectory?: string | undefined;
87
+ maxContextChars?: number | undefined;
88
88
  }>;
89
89
  declare const SparkcoderConfigSchema: z.ZodObject<{
90
90
  defaultModel: z.ZodDefault<z.ZodString>;
@@ -179,6 +179,7 @@ declare const SparkcoderConfigSchema: z.ZodObject<{
179
179
  exclude?: string[] | undefined;
180
180
  }>>;
181
181
  }, "strip", z.ZodTypeAny, {
182
+ defaultModel: string;
182
183
  toolApprovals: {
183
184
  bash: boolean;
184
185
  write_file: boolean;
@@ -186,7 +187,6 @@ declare const SparkcoderConfigSchema: z.ZodObject<{
186
187
  load_skill: boolean;
187
188
  todo: boolean;
188
189
  };
189
- defaultModel: string;
190
190
  skills: {
191
191
  directory: string;
192
192
  additionalDirectories: string[];
@@ -202,8 +202,8 @@ declare const SparkcoderConfigSchema: z.ZodObject<{
202
202
  publicUrl?: string | undefined;
203
203
  };
204
204
  databasePath: string;
205
- approvalWebhook?: string | undefined;
206
205
  workingDirectory?: string | undefined;
206
+ approvalWebhook?: string | undefined;
207
207
  remoteServer?: {
208
208
  url?: string | undefined;
209
209
  authKey?: string | undefined;
@@ -217,6 +217,8 @@ declare const SparkcoderConfigSchema: z.ZodObject<{
217
217
  namespace?: string | undefined;
218
218
  } | undefined;
219
219
  }, {
220
+ defaultModel?: string | undefined;
221
+ workingDirectory?: string | undefined;
220
222
  toolApprovals?: {
221
223
  bash?: boolean | undefined;
222
224
  write_file?: boolean | undefined;
@@ -225,8 +227,6 @@ declare const SparkcoderConfigSchema: z.ZodObject<{
225
227
  todo?: boolean | undefined;
226
228
  } | undefined;
227
229
  approvalWebhook?: string | undefined;
228
- workingDirectory?: string | undefined;
229
- defaultModel?: string | undefined;
230
230
  skills?: {
231
231
  directory?: string | undefined;
232
232
  additionalDirectories?: string[] | undefined;
@@ -480,6 +480,7 @@ declare class Agent {
480
480
  prompt: string;
481
481
  taskConfig: TaskConfig;
482
482
  abortSignal?: AbortSignal;
483
+ writeSSE?: (data: string) => Promise<void>;
483
484
  onText?: (text: string) => void;
484
485
  onToolCall?: (toolCall: {
485
486
  toolCallId: string;
package/dist/index.d.ts CHANGED
@@ -1,11 +1,11 @@
1
- import { R as ResolvedConfig } from './index-Db23cukG.js';
2
- export { A as Agent, a as AgentOptions, b as AgentRunOptions, c as AgentStreamResult, S as SparkcoderConfig, T as ToolApprovalConfig } from './index-Db23cukG.js';
1
+ import { R as ResolvedConfig } from './index-Dm6wGcYv.js';
2
+ export { A as Agent, a as AgentOptions, b as AgentRunOptions, c as AgentStreamResult, S as SparkcoderConfig, T as ToolApprovalConfig } from './index-Dm6wGcYv.js';
3
3
  export { ServerOptions, createApp, startServer, stopServer } from './server/index.js';
4
4
  export { checkpointQueries, closeDatabase, fileBackupQueries, getDb, initDatabase, messageQueries, sessionQueries, skillQueries, todoQueries, toolExecutionQueries } from './db/index.js';
5
- import { F as FileBackup, C as Checkpoint } from './schema-C7Mm4Ykn.js';
6
- export { a as Message, M as ModelMessage, S as Session, q as SessionConfig, f as Terminal, T as TodoItem, b as ToolExecution } from './schema-C7Mm4Ykn.js';
5
+ import { F as FileBackup, C as Checkpoint } from './schema-XcP0dedO.js';
6
+ export { a as Message, M as ModelMessage, S as Session, q as SessionConfig, f as Terminal, T as TodoItem, b as ToolExecution } from './schema-XcP0dedO.js';
7
7
  export { createLoadSkillTool, createReadFileTool, createTodoTool, createTools } from './tools/index.js';
8
- export { c as createBashTool, a as createWriteFileTool } from './search-CVVfuBPZ.js';
8
+ export { c as createBashTool, a as createWriteFileTool } from './search-CCffrVJE.js';
9
9
  import 'ai';
10
10
  import 'zod';
11
11
  import 'hono/types';
package/dist/index.js CHANGED
@@ -6186,12 +6186,18 @@ Before calling \`complete_task\`, you MUST verify your work completely. Do not j
6186
6186
  - If the task asked for multiple things, verify EACH one individually.
6187
6187
  - If something doesn't look right, fix it \u2014 don't complete with known issues.
6188
6188
 
6189
+ **Screenshot your completed work:**
6190
+ - 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.
6191
+ - 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.
6192
+ - This is especially valuable for UI/visual changes, successful test runs, and browser verification \u2014 show, don't just tell.
6193
+
6189
6194
  ### Use All Available Tools
6190
6195
  - **load_skill**: Load specialized skills/knowledge relevant to the task. Check what skills are available and use them.
6191
6196
  - **explore_agent**: Use for codebase exploration and understanding before making changes.
6192
6197
  - **code_graph**: Use to understand type hierarchies, references, and impact before refactoring.
6193
6198
  - **todo**: Track your progress on multi-step tasks so you don't miss steps.
6194
6199
  - **bash**: Full shell access \u2014 run builds, tests, dev servers, open browsers, curl endpoints, anything.
6200
+ - **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.
6195
6201
 
6196
6202
  ### Output Schema
6197
6203
  The \`complete_task\` tool expects a \`result\` object matching this JSON Schema:
@@ -6467,6 +6473,21 @@ ${this.summary}`
6467
6473
 
6468
6474
  // src/agent/index.ts
6469
6475
  init_webhook();
6476
+ var MAX_SSE_FIELD_LENGTH = 8 * 1024;
6477
+ var SSE_PREVIEW_LENGTH = 2 * 1024;
6478
+ function truncateWriteFileInput(input) {
6479
+ const out = { ...input };
6480
+ for (const key of ["content", "old_string", "new_string"]) {
6481
+ const val = out[key];
6482
+ if (typeof val === "string" && val.length > MAX_SSE_FIELD_LENGTH) {
6483
+ out[key] = `${val.slice(0, SSE_PREVIEW_LENGTH)}
6484
+ ... (truncated)`;
6485
+ out[`${key}Truncated`] = true;
6486
+ out[`${key}Length`] = val.length;
6487
+ }
6488
+ }
6489
+ return out;
6490
+ }
6470
6491
  var approvalResolvers = /* @__PURE__ */ new Map();
6471
6492
  var Agent = class _Agent {
6472
6493
  session;
@@ -6710,8 +6731,11 @@ ${prompt}` });
6710
6731
  };
6711
6732
  let taskRecorder = null;
6712
6733
  const sessionId = this.session.id;
6734
+ const emit = options.writeSSE;
6713
6735
  const bashProgressHandler = (progress) => {
6714
6736
  options.onToolProgress?.({ toolName: "bash", data: progress });
6737
+ if (emit) emit(JSON.stringify({ type: "tool-progress", toolName: "bash", data: progress })).catch(() => {
6738
+ });
6715
6739
  const port = progress.browserStreamPort;
6716
6740
  if (port && progress.status === "started") {
6717
6741
  Promise.resolve().then(() => (init_stream_proxy(), stream_proxy_exports)).then(({ getOrCreateProxy: getOrCreateProxy2 }) => {
@@ -6720,7 +6744,17 @@ ${prompt}` });
6720
6744
  Promise.resolve().then(() => (init_recorder(), recorder_exports)).then(({ FrameRecorder: FrameRecorder2 }) => {
6721
6745
  taskRecorder = new FrameRecorder2(sessionId);
6722
6746
  taskRecorder.start();
6723
- proxy.on("frame", (frame) => taskRecorder?.addFrame(frame));
6747
+ });
6748
+ }
6749
+ if (proxy.listenerCount("frame") === 0) {
6750
+ proxy.on("frame", (frame) => {
6751
+ taskRecorder?.addFrame(frame);
6752
+ if (emit) emit(JSON.stringify({ type: "browser-frame", data: frame.data, metadata: frame.metadata })).catch(() => {
6753
+ });
6754
+ });
6755
+ proxy.on("status", (s) => {
6756
+ if (emit) emit(JSON.stringify({ type: "browser-status", ...s })).catch(() => {
6757
+ });
6724
6758
  });
6725
6759
  }
6726
6760
  });
@@ -6731,8 +6765,16 @@ ${prompt}` });
6731
6765
  workingDirectory: this.session.workingDirectory,
6732
6766
  skillsDirectories: config.resolvedSkillsDirectories,
6733
6767
  onBashProgress: bashProgressHandler,
6734
- onWriteFileProgress: options.onToolProgress ? (progress) => options.onToolProgress({ toolName: "write_file", data: progress }) : void 0,
6735
- onSearchProgress: options.onToolProgress ? (progress) => options.onToolProgress({ toolName: "explore_agent", data: progress }) : void 0,
6768
+ onWriteFileProgress: (progress) => {
6769
+ options.onToolProgress?.({ toolName: "write_file", data: progress });
6770
+ if (emit) emit(JSON.stringify({ type: "tool-progress", toolName: "write_file", data: progress })).catch(() => {
6771
+ });
6772
+ },
6773
+ onSearchProgress: (progress) => {
6774
+ options.onToolProgress?.({ toolName: "explore_agent", data: progress });
6775
+ if (emit) emit(JSON.stringify({ type: "tool-progress", toolName: "explore_agent", data: progress })).catch(() => {
6776
+ });
6777
+ },
6736
6778
  taskTools: {
6737
6779
  outputSchema: options.taskConfig.outputSchema,
6738
6780
  onComplete
@@ -6750,6 +6792,9 @@ ${prompt}` });
6750
6792
 
6751
6793
  ${taskAddendum}`;
6752
6794
  fireWebhook("task.started", { prompt: options.prompt });
6795
+ if (emit) {
6796
+ await emit(JSON.stringify({ type: "data-user-message", data: { id: `user_${Date.now()}`, content: options.prompt } }));
6797
+ }
6753
6798
  await this.context.addUserMessage(options.prompt);
6754
6799
  let iteration = 0;
6755
6800
  while (iteration < maxIterations) {
@@ -6761,7 +6806,15 @@ ${taskAddendum}`;
6761
6806
  }
6762
6807
  const messages = await this.context.getMessages();
6763
6808
  const useAnthropic = isAnthropicModel(this.session.model);
6764
- const result = await generateText3({
6809
+ if (emit) {
6810
+ await emit(JSON.stringify({ type: "start", messageId: `msg_${Date.now()}` }));
6811
+ }
6812
+ let textStarted = false;
6813
+ let textId = `text_${Date.now()}`;
6814
+ let reasoningId = `reasoning_${Date.now()}`;
6815
+ let reasoningStarted = false;
6816
+ const toolCallStarts = /* @__PURE__ */ new Set();
6817
+ const iterStream = streamText2({
6765
6818
  model: resolveModel(this.session.model),
6766
6819
  system: systemPrompt,
6767
6820
  messages,
@@ -6770,21 +6823,94 @@ ${taskAddendum}`;
6770
6823
  abortSignal: options.abortSignal,
6771
6824
  providerOptions: useAnthropic ? {
6772
6825
  anthropic: {
6826
+ toolStreaming: true,
6773
6827
  thinking: { type: "enabled", budgetTokens: 1e4 }
6774
6828
  }
6775
6829
  } : void 0,
6776
- onStepFinish: (step) => {
6830
+ onStepFinish: async (step) => {
6777
6831
  options.onStepFinish?.(step);
6778
6832
  fireWebhook("task.step_finished", { iteration, text: step.text });
6833
+ if (emit) {
6834
+ if (textStarted) {
6835
+ await emit(JSON.stringify({ type: "text-end", id: textId }));
6836
+ textStarted = false;
6837
+ textId = `text_${Date.now()}`;
6838
+ }
6839
+ await emit(JSON.stringify({ type: "finish-step" }));
6840
+ }
6779
6841
  }
6780
6842
  });
6781
- const responseMessages = result.response.messages;
6843
+ for await (const part of iterStream.fullStream) {
6844
+ if (part.type === "text-delta") {
6845
+ if (emit) {
6846
+ if (!textStarted) {
6847
+ await emit(JSON.stringify({ type: "text-start", id: textId }));
6848
+ textStarted = true;
6849
+ }
6850
+ await emit(JSON.stringify({ type: "text-delta", id: textId, delta: part.text }));
6851
+ }
6852
+ } else if (part.type === "reasoning-start") {
6853
+ if (emit) {
6854
+ await emit(JSON.stringify({ type: "reasoning-start", id: reasoningId }));
6855
+ reasoningStarted = true;
6856
+ }
6857
+ } else if (part.type === "reasoning-delta") {
6858
+ if (emit) {
6859
+ await emit(JSON.stringify({ type: "reasoning-delta", id: reasoningId, delta: part.text }));
6860
+ }
6861
+ } else if (part.type === "reasoning-end") {
6862
+ if (emit && reasoningStarted) {
6863
+ await emit(JSON.stringify({ type: "reasoning-end", id: reasoningId }));
6864
+ reasoningStarted = false;
6865
+ reasoningId = `reasoning_${Date.now()}`;
6866
+ }
6867
+ } else if (part.type === "tool-call-streaming-start") {
6868
+ if (emit) {
6869
+ const p = part;
6870
+ await emit(JSON.stringify({ type: "tool-input-start", toolCallId: p.toolCallId, toolName: p.toolName }));
6871
+ toolCallStarts.add(p.toolCallId);
6872
+ }
6873
+ } else if (part.type === "tool-call-delta") {
6874
+ if (emit) {
6875
+ const p = part;
6876
+ await emit(JSON.stringify({ type: "tool-input-delta", toolCallId: p.toolCallId, argsTextDelta: p.argsTextDelta }));
6877
+ }
6878
+ } else if (part.type === "tool-call") {
6879
+ if (emit) {
6880
+ if (!toolCallStarts.has(part.toolCallId)) {
6881
+ await emit(JSON.stringify({ type: "tool-input-start", toolCallId: part.toolCallId, toolName: part.toolName }));
6882
+ toolCallStarts.add(part.toolCallId);
6883
+ }
6884
+ const safeInput = part.toolName === "write_file" && part.input && typeof part.input === "object" ? truncateWriteFileInput(part.input) : part.input;
6885
+ await emit(JSON.stringify({ type: "tool-input-available", toolCallId: part.toolCallId, toolName: part.toolName, input: safeInput }));
6886
+ }
6887
+ } else if (part.type === "tool-result") {
6888
+ if (emit) {
6889
+ await emit(JSON.stringify({ type: "tool-output-available", toolCallId: part.toolCallId, output: part.output }));
6890
+ }
6891
+ } else if (part.type === "error") {
6892
+ console.error("Task stream error:", part.error);
6893
+ if (emit) {
6894
+ await emit(JSON.stringify({ type: "error", errorText: String(part.error) }));
6895
+ }
6896
+ }
6897
+ }
6898
+ if (emit && textStarted) {
6899
+ await emit(JSON.stringify({ type: "text-end", id: textId }));
6900
+ }
6901
+ if (emit && reasoningStarted) {
6902
+ await emit(JSON.stringify({ type: "reasoning-end", id: reasoningId }));
6903
+ }
6904
+ const iterResponse = await iterStream.response;
6905
+ const responseMessages = iterResponse.messages;
6782
6906
  await this.context.addResponseMessages(responseMessages);
6783
- if (result.text) {
6784
- options.onText?.(result.text);
6785
- fireWebhook("task.message", { iteration, text: result.text });
6907
+ const resultText = await iterStream.text;
6908
+ const resultSteps = await iterStream.steps;
6909
+ if (resultText) {
6910
+ options.onText?.(resultText);
6911
+ fireWebhook("task.message", { iteration, text: resultText });
6786
6912
  }
6787
- for (const step of result.steps) {
6913
+ for (const step of resultSteps) {
6788
6914
  if (step.toolCalls) {
6789
6915
  for (const tc of step.toolCalls) {
6790
6916
  options.onToolCall?.({ toolCallId: tc.toolCallId, toolName: tc.toolName, input: tc.args });
@@ -6837,9 +6963,11 @@ ${taskAddendum}`;
6837
6963
  iterations: iteration
6838
6964
  };
6839
6965
  }
6840
- await this.context.addUserMessage(
6841
- "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."
6842
- );
6966
+ 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.";
6967
+ if (emit) {
6968
+ await emit(JSON.stringify({ type: "data-user-message", data: { id: `user_${Date.now()}`, content: continuationPrompt } }));
6969
+ }
6970
+ await this.context.addUserMessage(continuationPrompt);
6843
6971
  }
6844
6972
  const timeoutError = `Task did not complete within ${maxIterations} iterations`;
6845
6973
  const timeoutRecordingUrls = await this.finishTaskRecording(taskRecorder);
@@ -9491,6 +9619,7 @@ init_db();
9491
9619
  import { Hono as Hono5 } from "hono";
9492
9620
  import { zValidator as zValidator5 } from "@hono/zod-validator";
9493
9621
  import { z as z19 } from "zod";
9622
+ import { nanoid as nanoid7 } from "nanoid";
9494
9623
  init_config();
9495
9624
  var tasks = new Hono5();
9496
9625
  var taskAbortControllers = /* @__PURE__ */ new Map();
@@ -9528,45 +9657,74 @@ tasks.post(
9528
9657
  const taskId = agent.sessionId;
9529
9658
  const abortController = new AbortController();
9530
9659
  taskAbortControllers.set(taskId, abortController);
9531
- (async () => {
9532
- try {
9533
- await agent.runTask({
9534
- prompt: body.prompt,
9535
- taskConfig,
9536
- abortSignal: abortController.signal
9537
- });
9538
- } catch (err) {
9539
- if (err.name === "AbortError" || abortController.signal.aborted) {
9540
- console.log(`[TASK] Task ${taskId} was cancelled`);
9541
- } else {
9542
- console.error(`[TASK] Error in task ${taskId}:`, err.message);
9543
- const errorMsg = err.message || "Unknown error";
9544
- const failedTask = {
9545
- ...taskConfig,
9546
- status: "failed",
9547
- error: errorMsg
9548
- };
9549
- await sessionQueries.update(taskId, {
9550
- config: {
9551
- toolApprovals: { bash: false, write_file: false, read_file: false },
9552
- task: failedTask
9553
- }
9660
+ const streamId = `stream_${taskId}_${nanoid7(10)}`;
9661
+ await activeStreamQueries.create(taskId, streamId);
9662
+ const taskStreamProducer = () => {
9663
+ const { readable, writable } = new TransformStream();
9664
+ const writer = writable.getWriter();
9665
+ let writerClosed = false;
9666
+ const writeSSE = async (data) => {
9667
+ if (writerClosed) return;
9668
+ try {
9669
+ await writer.write(`data: ${data}
9670
+
9671
+ `);
9672
+ } catch {
9673
+ writerClosed = true;
9674
+ }
9675
+ };
9676
+ (async () => {
9677
+ await writeSSE(JSON.stringify({ type: "data-stream-id", streamId }));
9678
+ try {
9679
+ await agent.runTask({
9680
+ prompt: body.prompt,
9681
+ taskConfig,
9682
+ abortSignal: abortController.signal,
9683
+ writeSSE
9554
9684
  });
9555
- if (taskConfig.webhookUrl) {
9556
- const { sendWebhook: sendWebhook2 } = await Promise.resolve().then(() => (init_webhook(), webhook_exports));
9557
- sendWebhook2(taskConfig.webhookUrl, {
9558
- type: "task.failed",
9559
- taskId,
9560
- sessionId: taskId,
9561
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
9562
- data: { status: "failed", error: errorMsg }
9685
+ await writeSSE(JSON.stringify({ type: "finish" }));
9686
+ } catch (err) {
9687
+ if (err.name === "AbortError" || abortController.signal.aborted) {
9688
+ console.log(`[TASK] Task ${taskId} was cancelled`);
9689
+ await writeSSE(JSON.stringify({ type: "abort" }));
9690
+ } else {
9691
+ console.error(`[TASK] Error in task ${taskId}:`, err.message);
9692
+ const errorMsg = err.message || "Unknown error";
9693
+ await writeSSE(JSON.stringify({ type: "error", errorText: errorMsg }));
9694
+ const failedTask = {
9695
+ ...taskConfig,
9696
+ status: "failed",
9697
+ error: errorMsg
9698
+ };
9699
+ await sessionQueries.update(taskId, {
9700
+ config: {
9701
+ toolApprovals: { bash: false, write_file: false, read_file: false },
9702
+ task: failedTask
9703
+ }
9563
9704
  });
9705
+ if (taskConfig.webhookUrl) {
9706
+ const { sendWebhook: sendWebhook2 } = await Promise.resolve().then(() => (init_webhook(), webhook_exports));
9707
+ sendWebhook2(taskConfig.webhookUrl, {
9708
+ type: "task.failed",
9709
+ taskId,
9710
+ sessionId: taskId,
9711
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
9712
+ data: { status: "failed", error: errorMsg }
9713
+ });
9714
+ }
9564
9715
  }
9716
+ } finally {
9717
+ await writeSSE("[DONE]");
9718
+ writer.close().catch(() => {
9719
+ });
9720
+ await activeStreamQueries.finish(streamId).catch(() => {
9721
+ });
9722
+ taskAbortControllers.delete(taskId);
9565
9723
  }
9566
- } finally {
9567
- taskAbortControllers.delete(taskId);
9568
- }
9569
- })();
9724
+ })();
9725
+ return readable;
9726
+ };
9727
+ await streamContext.resumableStream(streamId, taskStreamProducer);
9570
9728
  return c.json({ taskId, status: "running" }, 201);
9571
9729
  }
9572
9730
  );