sparkecoder 0.1.60 → 0.1.61
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 +4 -3
- package/dist/agent/index.js +588 -176
- package/dist/agent/index.js.map +1 -1
- package/dist/cli.js +818 -95
- package/dist/cli.js.map +1 -1
- package/dist/db/index.d.ts +3 -2
- package/dist/db/index.js.map +1 -1
- package/dist/{index-Csad1Nx4.d.ts → index-DuGtMaAJ.d.ts} +85 -4
- package/dist/index.d.ts +6 -5
- package/dist/index.js +1202 -665
- package/dist/index.js.map +1 -1
- package/dist/schema-C7Mm4Ykn.d.ts +1410 -0
- package/dist/{search-BETuS1vh.d.ts → search-C_IFImt1.d.ts} +3 -3
- package/dist/server/index.js +605 -68
- package/dist/server/index.js.map +1 -1
- package/dist/tools/index.d.ts +38 -3
- package/dist/tools/index.js +230 -2
- package/dist/tools/index.js.map +1 -1
- package/package.json +5 -3
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/standalone/web/.next/BUILD_ID +1 -1
- package/web/.next/standalone/web/.next/build-manifest.json +2 -2
- package/web/.next/standalone/web/.next/prerender-manifest.json +3 -3
- package/web/.next/standalone/web/.next/server/app/(main)/page.js.nft.json +1 -1
- package/web/.next/standalone/web/.next/server/app/(main)/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/app/(main)/session/[id]/page.js.nft.json +1 -1
- package/web/.next/standalone/web/.next/server/app/(main)/session/[id]/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.html +2 -2
- package/web/.next/standalone/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.html +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/api/config/route.js.nft.json +1 -1
- package/web/.next/standalone/web/.next/server/app/api/health/route.js.nft.json +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.html +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/installation.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_full.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_index.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_tree.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.html +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/skills.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_full.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_index.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_tree.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.html +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/tools.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_full.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_index.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_tree.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.html +2 -2
- package/web/.next/standalone/web/.next/server/app/docs.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs.segments/_full.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/_index.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs.segments/_tree.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/docs.segments/docs/__PAGE__.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/docs.segments/docs.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/embed/[id]/page.js.nft.json +1 -1
- package/web/.next/standalone/web/.next/server/app/embed/[id]/page_client-reference-manifest.js +1 -1
- package/web/.next/standalone/web/.next/server/app/index.html +1 -1
- package/web/.next/standalone/web/.next/server/app/index.rsc +4 -4
- package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p/__PAGE__.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/index.segments/_full.segment.rsc +4 -4
- package/web/.next/standalone/web/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/web/.next/standalone/web/.next/server/app/index.segments/_index.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_19289e11._.js → 2374f_03d22c16._.js} +1 -1
- package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_b4b86c1f._.js → 2374f_0d0b1fb9._.js} +1 -1
- package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_4858a1ea._.js → 2374f_3f7d6d28._.js} +1 -1
- package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_51385fed._.js → 2374f_6166d14d._.js} +1 -1
- package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_40e35a02._.js → 2374f_67b9525f._.js} +1 -1
- package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_fb95e3c9._.js → 2374f_6b436efc._.js} +1 -1
- package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_2f0d9f6f._.js → 2374f_784d851c._.js} +1 -1
- package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_35475cbe._.js → 2374f_976b2ded._.js} +1 -1
- package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_7db22cde._.js → 2374f_98eba491._.js} +1 -1
- package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_90b8e4fb._.js → 2374f_99b7b533._.js} +1 -1
- package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_4666c827._.js → 2374f_a1a36483._.js} +1 -1
- package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_076f03ec._.js → 2374f_b98835eb._.js} +1 -1
- package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_b17fce11._.js → 2374f_e19eaecc._.js} +1 -1
- package/web/.next/standalone/web/.next/server/chunks/ssr/{2374f_d8b9ce38._.js → 2374f_e3aec189._.js} +1 -1
- package/web/.next/standalone/web/.next/server/chunks/ssr/{[root-of-the-server]__7775f784._.js → [root-of-the-server]__4f176a16._.js} +2 -2
- package/web/.next/standalone/web/.next/server/chunks/ssr/[root-of-the-server]__d59f831d._.js +15 -0
- package/web/.next/standalone/web/.next/server/chunks/ssr/{web_645f4b90._.js → web_693f514e._.js} +2 -2
- package/web/.next/standalone/web/.next/server/chunks/ssr/web_a42a2651._.js +7 -0
- package/web/.next/standalone/web/.next/server/chunks/ssr/web_dc6ce793._.js +7 -0
- package/web/.next/standalone/web/.next/server/chunks/ssr/web_src_components_sessions-sidebar_tsx_92510070._.js +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/chunks/0358a0e7a40cfb93.css +1 -0
- package/web/.next/standalone/web/.next/static/chunks/1ecde4c0d426a635.js +1 -0
- package/web/.next/standalone/web/.next/static/chunks/20e0fa99c7a1c1fc.js +13 -0
- package/web/.next/standalone/web/.next/static/chunks/36688a049d72e8ab.js +5 -0
- package/web/.next/standalone/web/.next/static/chunks/95436454a7559b0d.js +7 -0
- package/web/.next/standalone/web/.next/static/chunks/a751ca474cc46212.js +5 -0
- package/web/.next/standalone/web/.next/static/static/chunks/0358a0e7a40cfb93.css +1 -0
- package/web/.next/standalone/web/.next/static/static/chunks/1ecde4c0d426a635.js +1 -0
- package/web/.next/standalone/web/.next/static/static/chunks/20e0fa99c7a1c1fc.js +13 -0
- package/web/.next/standalone/web/.next/static/static/chunks/36688a049d72e8ab.js +5 -0
- package/web/.next/standalone/web/.next/static/static/chunks/95436454a7559b0d.js +7 -0
- package/web/.next/standalone/web/.next/static/static/chunks/a751ca474cc46212.js +5 -0
- package/web/.next/standalone/web/src/components/ai-elements/complete-task-tool.tsx +126 -0
- package/web/.next/standalone/web/src/components/chat-interface.tsx +68 -3
- package/web/.next/standalone/web/src/components/sessions-sidebar.tsx +18 -1
- package/web/.next/standalone/web/src/lib/api.ts +12 -0
- package/web/.next/static/chunks/0358a0e7a40cfb93.css +1 -0
- package/web/.next/static/chunks/1ecde4c0d426a635.js +1 -0
- package/web/.next/static/chunks/20e0fa99c7a1c1fc.js +13 -0
- package/web/.next/static/chunks/36688a049d72e8ab.js +5 -0
- package/web/.next/static/chunks/95436454a7559b0d.js +7 -0
- package/web/.next/static/chunks/a751ca474cc46212.js +5 -0
- package/dist/schema-NcQknWCg.d.ts +0 -295
- package/web/.next/standalone/web/.next/server/chunks/ssr/[root-of-the-server]__bd396152._.js +0 -15
- package/web/.next/standalone/web/.next/server/chunks/ssr/web_9c9f0e3b._.js +0 -7
- package/web/.next/standalone/web/.next/server/chunks/ssr/web_d08270f7._.js +0 -7
- package/web/.next/standalone/web/.next/static/chunks/2868b007ce5163fc.css +0 -1
- package/web/.next/standalone/web/.next/static/chunks/3f295b6960943c38.js +0 -1
- package/web/.next/standalone/web/.next/static/chunks/631b023d37a08635.js +0 -13
- package/web/.next/standalone/web/.next/static/chunks/a2b4737b190d1b54.js +0 -5
- package/web/.next/standalone/web/.next/static/chunks/e97212fcc8221479.js +0 -5
- package/web/.next/standalone/web/.next/static/chunks/f6e47c8a9766ce91.js +0 -7
- package/web/.next/standalone/web/.next/static/static/chunks/2868b007ce5163fc.css +0 -1
- package/web/.next/standalone/web/.next/static/static/chunks/3f295b6960943c38.js +0 -1
- package/web/.next/standalone/web/.next/static/static/chunks/631b023d37a08635.js +0 -13
- package/web/.next/standalone/web/.next/static/static/chunks/a2b4737b190d1b54.js +0 -5
- package/web/.next/standalone/web/.next/static/static/chunks/e97212fcc8221479.js +0 -5
- package/web/.next/standalone/web/.next/static/static/chunks/f6e47c8a9766ce91.js +0 -7
- package/web/.next/static/chunks/2868b007ce5163fc.css +0 -1
- package/web/.next/static/chunks/3f295b6960943c38.js +0 -1
- package/web/.next/static/chunks/631b023d37a08635.js +0 -13
- package/web/.next/static/chunks/a2b4737b190d1b54.js +0 -5
- package/web/.next/static/chunks/e97212fcc8221479.js +0 -5
- package/web/.next/static/chunks/f6e47c8a9766ce91.js +0 -7
- /package/web/.next/standalone/web/.next/static/{R5xiWSOp_Nqqe_js-LROo → 8zJH-RqrUQ3scBGbdaCmn}/_buildManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/{R5xiWSOp_Nqqe_js-LROo → 8zJH-RqrUQ3scBGbdaCmn}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/standalone/web/.next/static/{R5xiWSOp_Nqqe_js-LROo → 8zJH-RqrUQ3scBGbdaCmn}/_ssgManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/static/{R5xiWSOp_Nqqe_js-LROo → 8zJH-RqrUQ3scBGbdaCmn}/_buildManifest.js +0 -0
- /package/web/.next/standalone/web/.next/static/static/{R5xiWSOp_Nqqe_js-LROo → 8zJH-RqrUQ3scBGbdaCmn}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/standalone/web/.next/static/static/{R5xiWSOp_Nqqe_js-LROo → 8zJH-RqrUQ3scBGbdaCmn}/_ssgManifest.js +0 -0
- /package/web/.next/static/{R5xiWSOp_Nqqe_js-LROo → 8zJH-RqrUQ3scBGbdaCmn}/_buildManifest.js +0 -0
- /package/web/.next/static/{R5xiWSOp_Nqqe_js-LROo → 8zJH-RqrUQ3scBGbdaCmn}/_clientMiddlewareManifest.json +0 -0
- /package/web/.next/static/{R5xiWSOp_Nqqe_js-LROo → 8zJH-RqrUQ3scBGbdaCmn}/_ssgManifest.js +0 -0
package/dist/server/index.js
CHANGED
|
@@ -367,7 +367,7 @@ var init_db = __esm({
|
|
|
367
367
|
|
|
368
368
|
// src/config/types.ts
|
|
369
369
|
import { z } from "zod";
|
|
370
|
-
var ToolApprovalConfigSchema, SkillMetadataSchema, SessionConfigSchema, VectorGatewayConfigSchema, RemoteServerConfigSchema, SparkcoderConfigSchema;
|
|
370
|
+
var ToolApprovalConfigSchema, SkillMetadataSchema, TaskConfigSchema, SessionConfigSchema, VectorGatewayConfigSchema, RemoteServerConfigSchema, SparkcoderConfigSchema;
|
|
371
371
|
var init_types = __esm({
|
|
372
372
|
"src/config/types.ts"() {
|
|
373
373
|
"use strict";
|
|
@@ -386,11 +386,22 @@ var init_types = __esm({
|
|
|
386
386
|
// Glob patterns - auto-inject when working with matching files
|
|
387
387
|
globs: z.array(z.string()).optional().default([])
|
|
388
388
|
});
|
|
389
|
+
TaskConfigSchema = z.object({
|
|
390
|
+
enabled: z.boolean(),
|
|
391
|
+
outputSchema: z.record(z.string(), z.unknown()),
|
|
392
|
+
webhookUrl: z.string().url().optional(),
|
|
393
|
+
maxIterations: z.number().optional(),
|
|
394
|
+
status: z.enum(["running", "completed", "failed"]),
|
|
395
|
+
result: z.unknown().optional(),
|
|
396
|
+
error: z.string().optional(),
|
|
397
|
+
iterations: z.number().optional()
|
|
398
|
+
});
|
|
389
399
|
SessionConfigSchema = z.object({
|
|
390
400
|
toolApprovals: z.record(z.string(), z.boolean()).optional(),
|
|
391
401
|
approvalWebhook: z.string().url().optional(),
|
|
392
402
|
skillsDirectory: z.string().optional(),
|
|
393
|
-
maxContextChars: z.number().optional().default(2e5)
|
|
403
|
+
maxContextChars: z.number().optional().default(2e5),
|
|
404
|
+
task: TaskConfigSchema.optional()
|
|
394
405
|
});
|
|
395
406
|
VectorGatewayConfigSchema = z.object({
|
|
396
407
|
// Redis cluster nodes URL for Vector Gateway (or use REDIS_CLUSTER_NODES env var)
|
|
@@ -698,6 +709,9 @@ function getConfig() {
|
|
|
698
709
|
}
|
|
699
710
|
function requiresApproval(toolName, sessionConfig) {
|
|
700
711
|
const config = getConfig();
|
|
712
|
+
if (sessionConfig?.toolApprovals?.["*"] !== void 0) {
|
|
713
|
+
return sessionConfig.toolApprovals["*"];
|
|
714
|
+
}
|
|
701
715
|
if (sessionConfig?.toolApprovals?.[toolName] !== void 0) {
|
|
702
716
|
return sessionConfig.toolApprovals[toolName];
|
|
703
717
|
}
|
|
@@ -1605,7 +1619,7 @@ var init_semantic_search = __esm({
|
|
|
1605
1619
|
|
|
1606
1620
|
// src/server/index.ts
|
|
1607
1621
|
import "dotenv/config";
|
|
1608
|
-
import { Hono as
|
|
1622
|
+
import { Hono as Hono6 } from "hono";
|
|
1609
1623
|
import { serve } from "@hono/node-server";
|
|
1610
1624
|
import { cors } from "hono/cors";
|
|
1611
1625
|
import { logger } from "hono/logger";
|
|
@@ -1619,7 +1633,7 @@ import { fileURLToPath as fileURLToPath4 } from "url";
|
|
|
1619
1633
|
init_db();
|
|
1620
1634
|
import { Hono } from "hono";
|
|
1621
1635
|
import { zValidator } from "@hono/zod-validator";
|
|
1622
|
-
import { z as
|
|
1636
|
+
import { z as z14 } from "zod";
|
|
1623
1637
|
import { existsSync as existsSync13, mkdirSync as mkdirSync3, writeFileSync as writeFileSync2, readdirSync, statSync as statSync2, unlinkSync } from "fs";
|
|
1624
1638
|
import { readdir as readdir5 } from "fs/promises";
|
|
1625
1639
|
import { join as join5, basename as basename4, extname as extname7, relative as relative9 } from "path";
|
|
@@ -1629,18 +1643,176 @@ import { nanoid as nanoid4 } from "nanoid";
|
|
|
1629
1643
|
import {
|
|
1630
1644
|
streamText as streamText2,
|
|
1631
1645
|
generateText as generateText3,
|
|
1632
|
-
tool as
|
|
1646
|
+
tool as tool12,
|
|
1633
1647
|
stepCountIs as stepCountIs2
|
|
1634
1648
|
} from "ai";
|
|
1635
1649
|
|
|
1636
1650
|
// src/agent/model.ts
|
|
1637
1651
|
import { gateway } from "@ai-sdk/gateway";
|
|
1652
|
+
|
|
1653
|
+
// src/agent/remote-model.ts
|
|
1654
|
+
function serializePrompt(prompt) {
|
|
1655
|
+
return prompt.map((msg) => {
|
|
1656
|
+
if (!Array.isArray(msg.content)) return msg;
|
|
1657
|
+
return {
|
|
1658
|
+
...msg,
|
|
1659
|
+
content: msg.content.map((part) => {
|
|
1660
|
+
if (part.type === "file" && part.data instanceof Uint8Array) {
|
|
1661
|
+
return {
|
|
1662
|
+
...part,
|
|
1663
|
+
data: Buffer.from(part.data).toString("base64"),
|
|
1664
|
+
_base64: true
|
|
1665
|
+
};
|
|
1666
|
+
}
|
|
1667
|
+
return part;
|
|
1668
|
+
})
|
|
1669
|
+
};
|
|
1670
|
+
});
|
|
1671
|
+
}
|
|
1672
|
+
function deserializeValue(value) {
|
|
1673
|
+
if (value && typeof value === "object") {
|
|
1674
|
+
if (value.__uint8array && typeof value.data === "string") {
|
|
1675
|
+
return Buffer.from(value.data, "base64");
|
|
1676
|
+
}
|
|
1677
|
+
if (Array.isArray(value)) {
|
|
1678
|
+
return value.map(deserializeValue);
|
|
1679
|
+
}
|
|
1680
|
+
const result = {};
|
|
1681
|
+
for (const [k, v] of Object.entries(value)) {
|
|
1682
|
+
result[k] = deserializeValue(v);
|
|
1683
|
+
}
|
|
1684
|
+
return result;
|
|
1685
|
+
}
|
|
1686
|
+
return value;
|
|
1687
|
+
}
|
|
1688
|
+
function prepareOptions(options) {
|
|
1689
|
+
const { abortSignal, ...rest } = options;
|
|
1690
|
+
return {
|
|
1691
|
+
...rest,
|
|
1692
|
+
prompt: serializePrompt(options.prompt)
|
|
1693
|
+
};
|
|
1694
|
+
}
|
|
1695
|
+
function createRemoteModel(modelId, config) {
|
|
1696
|
+
const baseUrl = config.url.replace(/\/$/, "");
|
|
1697
|
+
const headers = {
|
|
1698
|
+
"Content-Type": "application/json",
|
|
1699
|
+
"Authorization": `Bearer ${config.authKey}`
|
|
1700
|
+
};
|
|
1701
|
+
return {
|
|
1702
|
+
specificationVersion: "v3",
|
|
1703
|
+
provider: "remote-proxy",
|
|
1704
|
+
modelId,
|
|
1705
|
+
supportedUrls: {},
|
|
1706
|
+
async doGenerate(options) {
|
|
1707
|
+
const res = await fetch(`${baseUrl}/inference/generate`, {
|
|
1708
|
+
method: "POST",
|
|
1709
|
+
headers,
|
|
1710
|
+
body: JSON.stringify({
|
|
1711
|
+
modelId,
|
|
1712
|
+
options: prepareOptions(options)
|
|
1713
|
+
}),
|
|
1714
|
+
signal: options.abortSignal
|
|
1715
|
+
});
|
|
1716
|
+
if (!res.ok) {
|
|
1717
|
+
const err = await res.json().catch(() => ({}));
|
|
1718
|
+
throw new Error(
|
|
1719
|
+
`Remote inference failed (${res.status}): ${err.error || res.statusText}`
|
|
1720
|
+
);
|
|
1721
|
+
}
|
|
1722
|
+
const result = await res.json();
|
|
1723
|
+
return deserializeValue(result);
|
|
1724
|
+
},
|
|
1725
|
+
async doStream(options) {
|
|
1726
|
+
const res = await fetch(`${baseUrl}/inference/stream`, {
|
|
1727
|
+
method: "POST",
|
|
1728
|
+
headers,
|
|
1729
|
+
body: JSON.stringify({
|
|
1730
|
+
modelId,
|
|
1731
|
+
options: prepareOptions(options)
|
|
1732
|
+
}),
|
|
1733
|
+
signal: options.abortSignal
|
|
1734
|
+
});
|
|
1735
|
+
if (!res.ok) {
|
|
1736
|
+
const err = await res.json().catch(() => ({}));
|
|
1737
|
+
throw new Error(
|
|
1738
|
+
`Remote inference failed (${res.status}): ${err.error || res.statusText}`
|
|
1739
|
+
);
|
|
1740
|
+
}
|
|
1741
|
+
const reader = res.body.getReader();
|
|
1742
|
+
const decoder = new TextDecoder();
|
|
1743
|
+
let buffer = "";
|
|
1744
|
+
const stream = new ReadableStream({
|
|
1745
|
+
async pull(controller) {
|
|
1746
|
+
while (true) {
|
|
1747
|
+
const { done, value } = await reader.read();
|
|
1748
|
+
if (done) {
|
|
1749
|
+
if (buffer.trim()) {
|
|
1750
|
+
try {
|
|
1751
|
+
const parsed = deserializeValue(JSON.parse(buffer.trim()));
|
|
1752
|
+
if (parsed.type === "error") {
|
|
1753
|
+
controller.error(new Error(parsed.error));
|
|
1754
|
+
} else {
|
|
1755
|
+
controller.enqueue(parsed);
|
|
1756
|
+
}
|
|
1757
|
+
} catch {
|
|
1758
|
+
}
|
|
1759
|
+
}
|
|
1760
|
+
controller.close();
|
|
1761
|
+
return;
|
|
1762
|
+
}
|
|
1763
|
+
buffer += decoder.decode(value, { stream: true });
|
|
1764
|
+
const lines = buffer.split("\n");
|
|
1765
|
+
buffer = lines.pop() || "";
|
|
1766
|
+
for (const line of lines) {
|
|
1767
|
+
if (!line.trim()) continue;
|
|
1768
|
+
try {
|
|
1769
|
+
const parsed = deserializeValue(JSON.parse(line));
|
|
1770
|
+
if (parsed.type === "error") {
|
|
1771
|
+
controller.error(new Error(parsed.error));
|
|
1772
|
+
return;
|
|
1773
|
+
}
|
|
1774
|
+
controller.enqueue(parsed);
|
|
1775
|
+
} catch {
|
|
1776
|
+
}
|
|
1777
|
+
}
|
|
1778
|
+
}
|
|
1779
|
+
},
|
|
1780
|
+
cancel() {
|
|
1781
|
+
reader.cancel();
|
|
1782
|
+
}
|
|
1783
|
+
});
|
|
1784
|
+
const responseHeaders = {};
|
|
1785
|
+
res.headers.forEach((v, k) => {
|
|
1786
|
+
if (k.startsWith("x-upstream-")) {
|
|
1787
|
+
responseHeaders[k.replace("x-upstream-", "")] = v;
|
|
1788
|
+
}
|
|
1789
|
+
});
|
|
1790
|
+
return {
|
|
1791
|
+
stream,
|
|
1792
|
+
response: Object.keys(responseHeaders).length > 0 ? { headers: responseHeaders } : void 0
|
|
1793
|
+
};
|
|
1794
|
+
}
|
|
1795
|
+
};
|
|
1796
|
+
}
|
|
1797
|
+
|
|
1798
|
+
// src/agent/model.ts
|
|
1799
|
+
init_config();
|
|
1638
1800
|
var ANTHROPIC_PREFIX = "anthropic/";
|
|
1639
1801
|
function isAnthropicModel(modelId) {
|
|
1640
1802
|
const normalized = modelId.trim().toLowerCase();
|
|
1641
1803
|
return normalized.startsWith(ANTHROPIC_PREFIX) || normalized.startsWith("claude-");
|
|
1642
1804
|
}
|
|
1643
1805
|
function resolveModel(modelId) {
|
|
1806
|
+
try {
|
|
1807
|
+
const config = getConfig();
|
|
1808
|
+
if (config.resolvedRemoteServer.isConfigured) {
|
|
1809
|
+
return createRemoteModel(modelId.trim(), {
|
|
1810
|
+
url: config.resolvedRemoteServer.url,
|
|
1811
|
+
authKey: config.resolvedRemoteServer.authKey
|
|
1812
|
+
});
|
|
1813
|
+
}
|
|
1814
|
+
} catch {
|
|
1815
|
+
}
|
|
1644
1816
|
return gateway(modelId.trim());
|
|
1645
1817
|
}
|
|
1646
1818
|
var SUBAGENT_MODELS = {
|
|
@@ -1652,7 +1824,7 @@ var SUBAGENT_MODELS = {
|
|
|
1652
1824
|
// src/agent/index.ts
|
|
1653
1825
|
init_db();
|
|
1654
1826
|
init_config();
|
|
1655
|
-
import { z as
|
|
1827
|
+
import { z as z13 } from "zod";
|
|
1656
1828
|
import { nanoid as nanoid3 } from "nanoid";
|
|
1657
1829
|
|
|
1658
1830
|
// src/tools/bash.ts
|
|
@@ -4962,6 +5134,59 @@ Context: ${context}` : query;
|
|
|
4962
5134
|
|
|
4963
5135
|
// src/tools/index.ts
|
|
4964
5136
|
init_semantic_search();
|
|
5137
|
+
|
|
5138
|
+
// src/tools/task.ts
|
|
5139
|
+
import { tool as tool11 } from "ai";
|
|
5140
|
+
import { z as z12 } from "zod";
|
|
5141
|
+
import Ajv from "ajv";
|
|
5142
|
+
var ajv = new Ajv({ allErrors: true });
|
|
5143
|
+
function createCompleteTaskTool(options) {
|
|
5144
|
+
const validate = ajv.compile(options.outputSchema);
|
|
5145
|
+
return tool11({
|
|
5146
|
+
description: "Call this tool when you have completed the task. Pass the result as a JSON object matching the required output schema. If the result does not match the schema, you will receive validation errors and should fix and retry.",
|
|
5147
|
+
inputSchema: z12.object({
|
|
5148
|
+
result: z12.record(z12.string(), z12.unknown()).describe("The task result as a JSON object matching the output schema")
|
|
5149
|
+
}),
|
|
5150
|
+
execute: async (input) => {
|
|
5151
|
+
const valid = validate(input.result);
|
|
5152
|
+
if (!valid) {
|
|
5153
|
+
const errors = validate.errors?.map((e) => ({
|
|
5154
|
+
path: e.instancePath || "/",
|
|
5155
|
+
message: e.message,
|
|
5156
|
+
params: e.params
|
|
5157
|
+
}));
|
|
5158
|
+
return {
|
|
5159
|
+
status: "validation_error",
|
|
5160
|
+
message: "The result does not match the required output schema. Fix the errors and call complete_task again.",
|
|
5161
|
+
errors,
|
|
5162
|
+
expectedSchema: options.outputSchema
|
|
5163
|
+
};
|
|
5164
|
+
}
|
|
5165
|
+
options.onComplete({ status: "completed", result: input.result });
|
|
5166
|
+
return {
|
|
5167
|
+
status: "completed",
|
|
5168
|
+
message: "Task completed successfully."
|
|
5169
|
+
};
|
|
5170
|
+
}
|
|
5171
|
+
});
|
|
5172
|
+
}
|
|
5173
|
+
function createTaskFailedTool(options) {
|
|
5174
|
+
return tool11({
|
|
5175
|
+
description: "Call this tool if you are unable to complete the task. Provide a clear reason explaining why the task cannot be completed.",
|
|
5176
|
+
inputSchema: z12.object({
|
|
5177
|
+
reason: z12.string().describe("Explanation of why the task cannot be completed")
|
|
5178
|
+
}),
|
|
5179
|
+
execute: async (input) => {
|
|
5180
|
+
options.onComplete({ status: "failed", error: input.reason });
|
|
5181
|
+
return {
|
|
5182
|
+
status: "failed",
|
|
5183
|
+
message: `Task marked as failed: ${input.reason}`
|
|
5184
|
+
};
|
|
5185
|
+
}
|
|
5186
|
+
});
|
|
5187
|
+
}
|
|
5188
|
+
|
|
5189
|
+
// src/tools/index.ts
|
|
4965
5190
|
init_semantic();
|
|
4966
5191
|
init_semantic_search();
|
|
4967
5192
|
async function createTools(options) {
|
|
@@ -5013,6 +5238,10 @@ async function createTools(options) {
|
|
|
5013
5238
|
} catch {
|
|
5014
5239
|
}
|
|
5015
5240
|
}
|
|
5241
|
+
if (options.taskTools) {
|
|
5242
|
+
tools.complete_task = createCompleteTaskTool(options.taskTools);
|
|
5243
|
+
tools.task_failed = createTaskFailedTool(options.taskTools);
|
|
5244
|
+
}
|
|
5016
5245
|
return tools;
|
|
5017
5246
|
}
|
|
5018
5247
|
|
|
@@ -5330,6 +5559,30 @@ function formatTodosForContext(todos) {
|
|
|
5330
5559
|
}
|
|
5331
5560
|
return lines.join("\n");
|
|
5332
5561
|
}
|
|
5562
|
+
function buildTaskPromptAddendum(outputSchema) {
|
|
5563
|
+
return `
|
|
5564
|
+
## Task Mode
|
|
5565
|
+
|
|
5566
|
+
You are running in **task mode**. You have been given a specific task to complete autonomously.
|
|
5567
|
+
|
|
5568
|
+
### Rules
|
|
5569
|
+
1. Work independently \u2014 no human will approve tool calls. All tools run without approval.
|
|
5570
|
+
2. Keep working until the task is fully complete.
|
|
5571
|
+
3. When done, call the \`complete_task\` tool with a JSON result matching the output schema below.
|
|
5572
|
+
4. If you determine the task is impossible or encounter an unrecoverable error, call the \`task_failed\` tool with a clear reason.
|
|
5573
|
+
5. Do NOT stop without calling one of these two tools.
|
|
5574
|
+
|
|
5575
|
+
### Output Schema
|
|
5576
|
+
The \`complete_task\` tool expects a \`result\` object matching this JSON Schema:
|
|
5577
|
+
\`\`\`json
|
|
5578
|
+
${JSON.stringify(outputSchema, null, 2)}
|
|
5579
|
+
\`\`\`
|
|
5580
|
+
|
|
5581
|
+
### Completion Tools
|
|
5582
|
+
- **\`complete_task({ result: ... })\`** \u2014 Call when the task is done. The result is validated against the schema above. If validation fails you will get errors back \u2014 fix and retry.
|
|
5583
|
+
- **\`task_failed({ reason: "..." })\`** \u2014 Call only if the task truly cannot be completed.
|
|
5584
|
+
`;
|
|
5585
|
+
}
|
|
5333
5586
|
function createSummaryPrompt(conversationHistory) {
|
|
5334
5587
|
return `Please provide a concise summary of the following conversation history. Focus on:
|
|
5335
5588
|
1. The main task or goal being worked on
|
|
@@ -5591,6 +5844,25 @@ ${this.summary}`
|
|
|
5591
5844
|
}
|
|
5592
5845
|
};
|
|
5593
5846
|
|
|
5847
|
+
// src/utils/webhook.ts
|
|
5848
|
+
async function sendWebhook(url, event) {
|
|
5849
|
+
try {
|
|
5850
|
+
const controller = new AbortController();
|
|
5851
|
+
const timeout = setTimeout(() => controller.abort(), 5e3);
|
|
5852
|
+
await fetch(url, {
|
|
5853
|
+
method: "POST",
|
|
5854
|
+
headers: {
|
|
5855
|
+
"Content-Type": "application/json",
|
|
5856
|
+
"X-SparkECoder-Event": event.type
|
|
5857
|
+
},
|
|
5858
|
+
body: JSON.stringify(event),
|
|
5859
|
+
signal: controller.signal
|
|
5860
|
+
});
|
|
5861
|
+
clearTimeout(timeout);
|
|
5862
|
+
} catch {
|
|
5863
|
+
}
|
|
5864
|
+
}
|
|
5865
|
+
|
|
5594
5866
|
// src/agent/index.ts
|
|
5595
5867
|
var approvalResolvers = /* @__PURE__ */ new Map();
|
|
5596
5868
|
var Agent = class _Agent {
|
|
@@ -5810,6 +6082,145 @@ ${prompt}` });
|
|
|
5810
6082
|
steps: result.steps
|
|
5811
6083
|
};
|
|
5812
6084
|
}
|
|
6085
|
+
/**
|
|
6086
|
+
* Run the agent in task mode — loops autonomously until the agent calls
|
|
6087
|
+
* complete_task or task_failed (or hits maxIterations).
|
|
6088
|
+
* All tools run without approval. Webhook events are fired throughout.
|
|
6089
|
+
*/
|
|
6090
|
+
async runTask(options) {
|
|
6091
|
+
const config = getConfig();
|
|
6092
|
+
const maxIterations = options.taskConfig.maxIterations ?? 50;
|
|
6093
|
+
const webhookUrl = options.taskConfig.webhookUrl;
|
|
6094
|
+
const fireWebhook = (type, data) => {
|
|
6095
|
+
if (!webhookUrl) return;
|
|
6096
|
+
sendWebhook(webhookUrl, {
|
|
6097
|
+
type,
|
|
6098
|
+
taskId: this.session.id,
|
|
6099
|
+
sessionId: this.session.id,
|
|
6100
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
6101
|
+
data
|
|
6102
|
+
});
|
|
6103
|
+
};
|
|
6104
|
+
const completion = { signal: null };
|
|
6105
|
+
const onComplete = (signal) => {
|
|
6106
|
+
completion.signal = signal;
|
|
6107
|
+
};
|
|
6108
|
+
const taskTools = await createTools({
|
|
6109
|
+
sessionId: this.session.id,
|
|
6110
|
+
workingDirectory: this.session.workingDirectory,
|
|
6111
|
+
skillsDirectories: config.resolvedSkillsDirectories,
|
|
6112
|
+
onBashProgress: options.onToolProgress ? (progress) => options.onToolProgress({ toolName: "bash", data: progress }) : void 0,
|
|
6113
|
+
onWriteFileProgress: options.onToolProgress ? (progress) => options.onToolProgress({ toolName: "write_file", data: progress }) : void 0,
|
|
6114
|
+
onSearchProgress: options.onToolProgress ? (progress) => options.onToolProgress({ toolName: "explore_agent", data: progress }) : void 0,
|
|
6115
|
+
taskTools: {
|
|
6116
|
+
outputSchema: options.taskConfig.outputSchema,
|
|
6117
|
+
onComplete
|
|
6118
|
+
}
|
|
6119
|
+
});
|
|
6120
|
+
const baseSystemPrompt = await buildSystemPrompt({
|
|
6121
|
+
workingDirectory: this.session.workingDirectory,
|
|
6122
|
+
skillsDirectories: config.resolvedSkillsDirectories,
|
|
6123
|
+
sessionId: this.session.id,
|
|
6124
|
+
discoveredSkills: config.discoveredSkills,
|
|
6125
|
+
activeFiles: []
|
|
6126
|
+
});
|
|
6127
|
+
const taskAddendum = buildTaskPromptAddendum(options.taskConfig.outputSchema);
|
|
6128
|
+
const systemPrompt = `${baseSystemPrompt}
|
|
6129
|
+
|
|
6130
|
+
${taskAddendum}`;
|
|
6131
|
+
fireWebhook("task.started", { prompt: options.prompt });
|
|
6132
|
+
this.context.addUserMessage(options.prompt);
|
|
6133
|
+
let iteration = 0;
|
|
6134
|
+
while (iteration < maxIterations) {
|
|
6135
|
+
iteration++;
|
|
6136
|
+
if (options.abortSignal?.aborted) {
|
|
6137
|
+
const cancelError = "Task was cancelled";
|
|
6138
|
+
fireWebhook("task.failed", { status: "failed", error: cancelError, iterations: iteration });
|
|
6139
|
+
return { status: "failed", error: cancelError, iterations: iteration };
|
|
6140
|
+
}
|
|
6141
|
+
const messages = await this.context.getMessages();
|
|
6142
|
+
const useAnthropic = isAnthropicModel(this.session.model);
|
|
6143
|
+
const result = await generateText3({
|
|
6144
|
+
model: resolveModel(this.session.model),
|
|
6145
|
+
system: systemPrompt,
|
|
6146
|
+
messages,
|
|
6147
|
+
tools: taskTools,
|
|
6148
|
+
stopWhen: stepCountIs2(500),
|
|
6149
|
+
abortSignal: options.abortSignal,
|
|
6150
|
+
providerOptions: useAnthropic ? {
|
|
6151
|
+
anthropic: {
|
|
6152
|
+
thinking: { type: "enabled", budgetTokens: 1e4 }
|
|
6153
|
+
}
|
|
6154
|
+
} : void 0,
|
|
6155
|
+
onStepFinish: (step) => {
|
|
6156
|
+
options.onStepFinish?.(step);
|
|
6157
|
+
fireWebhook("task.step_finished", { iteration, text: step.text });
|
|
6158
|
+
}
|
|
6159
|
+
});
|
|
6160
|
+
const responseMessages = result.response.messages;
|
|
6161
|
+
this.context.addResponseMessages(responseMessages);
|
|
6162
|
+
if (result.text) {
|
|
6163
|
+
options.onText?.(result.text);
|
|
6164
|
+
fireWebhook("task.message", { iteration, text: result.text });
|
|
6165
|
+
}
|
|
6166
|
+
for (const step of result.steps) {
|
|
6167
|
+
if (step.toolCalls) {
|
|
6168
|
+
for (const tc of step.toolCalls) {
|
|
6169
|
+
options.onToolCall?.({ toolCallId: tc.toolCallId, toolName: tc.toolName, input: tc.args });
|
|
6170
|
+
fireWebhook("task.tool_call", { iteration, toolName: tc.toolName, toolCallId: tc.toolCallId, input: tc.args });
|
|
6171
|
+
}
|
|
6172
|
+
}
|
|
6173
|
+
if (step.toolResults) {
|
|
6174
|
+
for (const tr of step.toolResults) {
|
|
6175
|
+
options.onToolResult?.({ toolCallId: tr.toolCallId, toolName: tr.toolName, output: tr.result });
|
|
6176
|
+
fireWebhook("task.tool_result", { iteration, toolName: tr.toolName, toolCallId: tr.toolCallId, output: tr.result });
|
|
6177
|
+
}
|
|
6178
|
+
}
|
|
6179
|
+
}
|
|
6180
|
+
if (completion.signal) {
|
|
6181
|
+
const sig = completion.signal;
|
|
6182
|
+
const finalStatus = sig.status;
|
|
6183
|
+
const eventType = finalStatus === "completed" ? "task.completed" : "task.failed";
|
|
6184
|
+
fireWebhook(eventType, {
|
|
6185
|
+
status: finalStatus,
|
|
6186
|
+
result: sig.result,
|
|
6187
|
+
error: sig.error,
|
|
6188
|
+
iterations: iteration
|
|
6189
|
+
});
|
|
6190
|
+
const updatedTask2 = {
|
|
6191
|
+
...options.taskConfig,
|
|
6192
|
+
status: finalStatus,
|
|
6193
|
+
result: sig.result,
|
|
6194
|
+
error: sig.error,
|
|
6195
|
+
iterations: iteration
|
|
6196
|
+
};
|
|
6197
|
+
await sessionQueries.update(this.session.id, {
|
|
6198
|
+
config: { ...this.session.config, task: updatedTask2 }
|
|
6199
|
+
});
|
|
6200
|
+
return {
|
|
6201
|
+
status: finalStatus,
|
|
6202
|
+
result: sig.result,
|
|
6203
|
+
error: sig.error,
|
|
6204
|
+
iterations: iteration
|
|
6205
|
+
};
|
|
6206
|
+
}
|
|
6207
|
+
this.context.addUserMessage(
|
|
6208
|
+
"Continue working on the task. When done, call `complete_task` with the result. If you cannot complete it, call `task_failed` with a reason."
|
|
6209
|
+
);
|
|
6210
|
+
}
|
|
6211
|
+
const timeoutError = `Task did not complete within ${maxIterations} iterations`;
|
|
6212
|
+
fireWebhook("task.failed", { status: "failed", error: timeoutError, iterations: iteration });
|
|
6213
|
+
const updatedTask = {
|
|
6214
|
+
...options.taskConfig,
|
|
6215
|
+
status: "failed",
|
|
6216
|
+
error: timeoutError,
|
|
6217
|
+
iterations: iteration
|
|
6218
|
+
};
|
|
6219
|
+
await sessionQueries.update(this.session.id, {
|
|
6220
|
+
config: { ...this.session.config, task: updatedTask }
|
|
6221
|
+
});
|
|
6222
|
+
return { status: "failed", error: timeoutError, iterations: iteration };
|
|
6223
|
+
}
|
|
5813
6224
|
/**
|
|
5814
6225
|
* Wrap tools to add approval checking
|
|
5815
6226
|
*/
|
|
@@ -5823,9 +6234,9 @@ ${prompt}` });
|
|
|
5823
6234
|
wrappedTools[name] = originalTool;
|
|
5824
6235
|
continue;
|
|
5825
6236
|
}
|
|
5826
|
-
wrappedTools[name] =
|
|
6237
|
+
wrappedTools[name] = tool12({
|
|
5827
6238
|
description: originalTool.description || "",
|
|
5828
|
-
inputSchema: originalTool.inputSchema ||
|
|
6239
|
+
inputSchema: originalTool.inputSchema || z13.object({}),
|
|
5829
6240
|
execute: async (input, toolOptions) => {
|
|
5830
6241
|
const toolCallId = toolOptions.toolCallId || nanoid3();
|
|
5831
6242
|
const execution = toolExecutionQueries.create({
|
|
@@ -5966,18 +6377,18 @@ function cleanupPendingInputs() {
|
|
|
5966
6377
|
}
|
|
5967
6378
|
}
|
|
5968
6379
|
}
|
|
5969
|
-
var createSessionSchema =
|
|
5970
|
-
name:
|
|
5971
|
-
workingDirectory:
|
|
5972
|
-
model:
|
|
5973
|
-
toolApprovals:
|
|
6380
|
+
var createSessionSchema = z14.object({
|
|
6381
|
+
name: z14.string().optional(),
|
|
6382
|
+
workingDirectory: z14.string().optional(),
|
|
6383
|
+
model: z14.string().optional(),
|
|
6384
|
+
toolApprovals: z14.record(z14.string(), z14.boolean()).optional()
|
|
5974
6385
|
});
|
|
5975
|
-
var paginationQuerySchema =
|
|
5976
|
-
limit:
|
|
5977
|
-
offset:
|
|
6386
|
+
var paginationQuerySchema = z14.object({
|
|
6387
|
+
limit: z14.string().optional(),
|
|
6388
|
+
offset: z14.string().optional()
|
|
5978
6389
|
});
|
|
5979
|
-
var messagesQuerySchema =
|
|
5980
|
-
limit:
|
|
6390
|
+
var messagesQuerySchema = z14.object({
|
|
6391
|
+
limit: z14.string().optional()
|
|
5981
6392
|
});
|
|
5982
6393
|
sessions.get(
|
|
5983
6394
|
"/",
|
|
@@ -6116,10 +6527,10 @@ sessions.get("/:id/tools", async (c) => {
|
|
|
6116
6527
|
count: executions.length
|
|
6117
6528
|
});
|
|
6118
6529
|
});
|
|
6119
|
-
var updateSessionSchema =
|
|
6120
|
-
model:
|
|
6121
|
-
name:
|
|
6122
|
-
toolApprovals:
|
|
6530
|
+
var updateSessionSchema = z14.object({
|
|
6531
|
+
model: z14.string().optional(),
|
|
6532
|
+
name: z14.string().optional(),
|
|
6533
|
+
toolApprovals: z14.record(z14.string(), z14.boolean()).optional()
|
|
6123
6534
|
});
|
|
6124
6535
|
sessions.patch(
|
|
6125
6536
|
"/:id",
|
|
@@ -6189,8 +6600,8 @@ sessions.post("/:id/clear", async (c) => {
|
|
|
6189
6600
|
await agent.clearContext();
|
|
6190
6601
|
return c.json({ success: true, sessionId: id });
|
|
6191
6602
|
});
|
|
6192
|
-
var pendingInputSchema =
|
|
6193
|
-
text:
|
|
6603
|
+
var pendingInputSchema = z14.object({
|
|
6604
|
+
text: z14.string()
|
|
6194
6605
|
});
|
|
6195
6606
|
sessions.post(
|
|
6196
6607
|
"/:id/pending-input",
|
|
@@ -6221,13 +6632,13 @@ sessions.get("/:id/pending-input", async (c) => {
|
|
|
6221
6632
|
createdAt: pending.createdAt.toISOString()
|
|
6222
6633
|
});
|
|
6223
6634
|
});
|
|
6224
|
-
var devtoolsContextSchema =
|
|
6225
|
-
url:
|
|
6226
|
-
path:
|
|
6227
|
-
pageName:
|
|
6228
|
-
screenWidth:
|
|
6229
|
-
screenHeight:
|
|
6230
|
-
devicePixelRatio:
|
|
6635
|
+
var devtoolsContextSchema = z14.object({
|
|
6636
|
+
url: z14.string(),
|
|
6637
|
+
path: z14.string(),
|
|
6638
|
+
pageName: z14.string().optional(),
|
|
6639
|
+
screenWidth: z14.number().optional(),
|
|
6640
|
+
screenHeight: z14.number().optional(),
|
|
6641
|
+
devicePixelRatio: z14.number().optional()
|
|
6231
6642
|
});
|
|
6232
6643
|
sessions.post(
|
|
6233
6644
|
"/:id/devtools-context",
|
|
@@ -6518,10 +6929,10 @@ sessions.delete("/:id/attachments/:attachmentId", async (c) => {
|
|
|
6518
6929
|
unlinkSync(filePath);
|
|
6519
6930
|
return c.json({ success: true, id: attachmentId });
|
|
6520
6931
|
});
|
|
6521
|
-
var filesQuerySchema =
|
|
6522
|
-
query:
|
|
6932
|
+
var filesQuerySchema = z14.object({
|
|
6933
|
+
query: z14.string().optional(),
|
|
6523
6934
|
// Filter query (e.g., "src/com" to match "src/components")
|
|
6524
|
-
limit:
|
|
6935
|
+
limit: z14.string().optional()
|
|
6525
6936
|
// Max results (default 50)
|
|
6526
6937
|
});
|
|
6527
6938
|
var IGNORED_DIRECTORIES = /* @__PURE__ */ new Set([
|
|
@@ -6699,7 +7110,7 @@ sessions.get(
|
|
|
6699
7110
|
init_db();
|
|
6700
7111
|
import { Hono as Hono2 } from "hono";
|
|
6701
7112
|
import { zValidator as zValidator2 } from "@hono/zod-validator";
|
|
6702
|
-
import { z as
|
|
7113
|
+
import { z as z15 } from "zod";
|
|
6703
7114
|
import { existsSync as existsSync14, mkdirSync as mkdirSync4, writeFileSync as writeFileSync3 } from "fs";
|
|
6704
7115
|
import { join as join6 } from "path";
|
|
6705
7116
|
init_config();
|
|
@@ -6864,30 +7275,30 @@ function enrichPromptWithDevtoolsContext(sessionId, prompt) {
|
|
|
6864
7275
|
${prompt}`;
|
|
6865
7276
|
}
|
|
6866
7277
|
var agents = new Hono2();
|
|
6867
|
-
var attachmentSchema =
|
|
6868
|
-
type:
|
|
6869
|
-
data:
|
|
7278
|
+
var attachmentSchema = z15.object({
|
|
7279
|
+
type: z15.enum(["image", "file"]),
|
|
7280
|
+
data: z15.string(),
|
|
6870
7281
|
// base64 data URL or raw base64
|
|
6871
|
-
mediaType:
|
|
6872
|
-
filename:
|
|
7282
|
+
mediaType: z15.string().optional(),
|
|
7283
|
+
filename: z15.string().optional()
|
|
6873
7284
|
});
|
|
6874
|
-
var runPromptSchema =
|
|
6875
|
-
prompt:
|
|
7285
|
+
var runPromptSchema = z15.object({
|
|
7286
|
+
prompt: z15.string(),
|
|
6876
7287
|
// Can be empty if attachments are provided
|
|
6877
|
-
attachments:
|
|
7288
|
+
attachments: z15.array(attachmentSchema).optional()
|
|
6878
7289
|
}).refine(
|
|
6879
7290
|
(data) => data.prompt.trim().length > 0 || data.attachments && data.attachments.length > 0,
|
|
6880
7291
|
{ message: "Either prompt or attachments must be provided" }
|
|
6881
7292
|
);
|
|
6882
|
-
var quickStartSchema =
|
|
6883
|
-
prompt:
|
|
6884
|
-
name:
|
|
6885
|
-
workingDirectory:
|
|
6886
|
-
model:
|
|
6887
|
-
toolApprovals:
|
|
7293
|
+
var quickStartSchema = z15.object({
|
|
7294
|
+
prompt: z15.string().min(1),
|
|
7295
|
+
name: z15.string().optional(),
|
|
7296
|
+
workingDirectory: z15.string().optional(),
|
|
7297
|
+
model: z15.string().optional(),
|
|
7298
|
+
toolApprovals: z15.record(z15.string(), z15.boolean()).optional()
|
|
6888
7299
|
});
|
|
6889
|
-
var rejectSchema =
|
|
6890
|
-
reason:
|
|
7300
|
+
var rejectSchema = z15.object({
|
|
7301
|
+
reason: z15.string().optional()
|
|
6891
7302
|
}).optional();
|
|
6892
7303
|
var streamAbortControllers = /* @__PURE__ */ new Map();
|
|
6893
7304
|
function getAttachmentsDirectory(sessionId) {
|
|
@@ -7317,7 +7728,7 @@ agents.get("/:id/watch", async (c) => {
|
|
|
7317
7728
|
"Cache-Control": "no-cache",
|
|
7318
7729
|
"Connection": "keep-alive",
|
|
7319
7730
|
"x-vercel-ai-ui-message-stream": "v1",
|
|
7320
|
-
"x-stream-id": streamId
|
|
7731
|
+
"x-stream-id": streamId ?? ""
|
|
7321
7732
|
}
|
|
7322
7733
|
});
|
|
7323
7734
|
});
|
|
@@ -7675,7 +8086,7 @@ agents.post(
|
|
|
7675
8086
|
init_config();
|
|
7676
8087
|
import { Hono as Hono3 } from "hono";
|
|
7677
8088
|
import { zValidator as zValidator3 } from "@hono/zod-validator";
|
|
7678
|
-
import { z as
|
|
8089
|
+
import { z as z16 } from "zod";
|
|
7679
8090
|
import { readFileSync as readFileSync5 } from "fs";
|
|
7680
8091
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
7681
8092
|
import { dirname as dirname6, join as join7 } from "path";
|
|
@@ -7785,9 +8196,9 @@ health.get("/api-keys", async (c) => {
|
|
|
7785
8196
|
supportedProviders: SUPPORTED_PROVIDERS
|
|
7786
8197
|
});
|
|
7787
8198
|
});
|
|
7788
|
-
var setApiKeySchema =
|
|
7789
|
-
provider:
|
|
7790
|
-
apiKey:
|
|
8199
|
+
var setApiKeySchema = z16.object({
|
|
8200
|
+
provider: z16.string(),
|
|
8201
|
+
apiKey: z16.string().min(1)
|
|
7791
8202
|
});
|
|
7792
8203
|
health.post(
|
|
7793
8204
|
"/api-keys",
|
|
@@ -7826,13 +8237,13 @@ health.delete("/api-keys/:provider", async (c) => {
|
|
|
7826
8237
|
// src/server/routes/terminals.ts
|
|
7827
8238
|
import { Hono as Hono4 } from "hono";
|
|
7828
8239
|
import { zValidator as zValidator4 } from "@hono/zod-validator";
|
|
7829
|
-
import { z as
|
|
8240
|
+
import { z as z17 } from "zod";
|
|
7830
8241
|
init_db();
|
|
7831
8242
|
var terminals = new Hono4();
|
|
7832
|
-
var spawnSchema =
|
|
7833
|
-
command:
|
|
7834
|
-
cwd:
|
|
7835
|
-
name:
|
|
8243
|
+
var spawnSchema = z17.object({
|
|
8244
|
+
command: z17.string(),
|
|
8245
|
+
cwd: z17.string().optional(),
|
|
8246
|
+
name: z17.string().optional()
|
|
7836
8247
|
});
|
|
7837
8248
|
terminals.post(
|
|
7838
8249
|
"/:sessionId/terminals",
|
|
@@ -7913,8 +8324,8 @@ terminals.get("/:sessionId/terminals/:terminalId", async (c) => {
|
|
|
7913
8324
|
// We don't track exit codes in tmux mode
|
|
7914
8325
|
});
|
|
7915
8326
|
});
|
|
7916
|
-
var logsQuerySchema =
|
|
7917
|
-
tail:
|
|
8327
|
+
var logsQuerySchema = z17.object({
|
|
8328
|
+
tail: z17.string().optional().transform((v) => v ? parseInt(v, 10) : void 0)
|
|
7918
8329
|
});
|
|
7919
8330
|
terminals.get(
|
|
7920
8331
|
"/:sessionId/terminals/:terminalId/logs",
|
|
@@ -7938,8 +8349,8 @@ terminals.get(
|
|
|
7938
8349
|
});
|
|
7939
8350
|
}
|
|
7940
8351
|
);
|
|
7941
|
-
var killSchema =
|
|
7942
|
-
signal:
|
|
8352
|
+
var killSchema = z17.object({
|
|
8353
|
+
signal: z17.enum(["SIGTERM", "SIGKILL"]).optional()
|
|
7943
8354
|
});
|
|
7944
8355
|
terminals.post(
|
|
7945
8356
|
"/:sessionId/terminals/:terminalId/kill",
|
|
@@ -7953,8 +8364,8 @@ terminals.post(
|
|
|
7953
8364
|
return c.json({ success: true, message: "Terminal killed" });
|
|
7954
8365
|
}
|
|
7955
8366
|
);
|
|
7956
|
-
var writeSchema =
|
|
7957
|
-
input:
|
|
8367
|
+
var writeSchema = z17.object({
|
|
8368
|
+
input: z17.string()
|
|
7958
8369
|
});
|
|
7959
8370
|
terminals.post(
|
|
7960
8371
|
"/:sessionId/terminals/:terminalId/write",
|
|
@@ -8135,6 +8546,131 @@ data: ${JSON.stringify({ status: "stopped" })}
|
|
|
8135
8546
|
);
|
|
8136
8547
|
});
|
|
8137
8548
|
|
|
8549
|
+
// src/server/routes/tasks.ts
|
|
8550
|
+
init_db();
|
|
8551
|
+
import { Hono as Hono5 } from "hono";
|
|
8552
|
+
import { zValidator as zValidator5 } from "@hono/zod-validator";
|
|
8553
|
+
import { z as z18 } from "zod";
|
|
8554
|
+
init_config();
|
|
8555
|
+
var tasks = new Hono5();
|
|
8556
|
+
var taskAbortControllers = /* @__PURE__ */ new Map();
|
|
8557
|
+
var createTaskSchema = z18.object({
|
|
8558
|
+
prompt: z18.string().min(1),
|
|
8559
|
+
outputSchema: z18.record(z18.string(), z18.unknown()),
|
|
8560
|
+
webhookUrl: z18.string().url().optional(),
|
|
8561
|
+
model: z18.string().optional(),
|
|
8562
|
+
workingDirectory: z18.string().optional(),
|
|
8563
|
+
name: z18.string().optional(),
|
|
8564
|
+
maxIterations: z18.number().int().min(1).max(500).optional()
|
|
8565
|
+
});
|
|
8566
|
+
tasks.post(
|
|
8567
|
+
"/",
|
|
8568
|
+
zValidator5("json", createTaskSchema),
|
|
8569
|
+
async (c) => {
|
|
8570
|
+
const body = c.req.valid("json");
|
|
8571
|
+
const config = getConfig();
|
|
8572
|
+
const taskConfig = {
|
|
8573
|
+
enabled: true,
|
|
8574
|
+
outputSchema: body.outputSchema,
|
|
8575
|
+
webhookUrl: body.webhookUrl,
|
|
8576
|
+
maxIterations: body.maxIterations ?? 50,
|
|
8577
|
+
status: "running"
|
|
8578
|
+
};
|
|
8579
|
+
const agent = await Agent.create({
|
|
8580
|
+
name: body.name || "Task",
|
|
8581
|
+
workingDirectory: body.workingDirectory || config.resolvedWorkingDirectory,
|
|
8582
|
+
model: body.model || config.defaultModel,
|
|
8583
|
+
sessionConfig: {
|
|
8584
|
+
toolApprovals: { bash: false, write_file: false, read_file: false },
|
|
8585
|
+
task: taskConfig
|
|
8586
|
+
}
|
|
8587
|
+
});
|
|
8588
|
+
const taskId = agent.sessionId;
|
|
8589
|
+
const abortController = new AbortController();
|
|
8590
|
+
taskAbortControllers.set(taskId, abortController);
|
|
8591
|
+
(async () => {
|
|
8592
|
+
try {
|
|
8593
|
+
await agent.runTask({
|
|
8594
|
+
prompt: body.prompt,
|
|
8595
|
+
taskConfig,
|
|
8596
|
+
abortSignal: abortController.signal
|
|
8597
|
+
});
|
|
8598
|
+
} catch (err) {
|
|
8599
|
+
if (err.name === "AbortError" || abortController.signal.aborted) {
|
|
8600
|
+
console.log(`[TASK] Task ${taskId} was cancelled`);
|
|
8601
|
+
} else {
|
|
8602
|
+
console.error(`[TASK] Error in task ${taskId}:`, err.message);
|
|
8603
|
+
const failedTask = {
|
|
8604
|
+
...taskConfig,
|
|
8605
|
+
status: "failed",
|
|
8606
|
+
error: err.message || "Unknown error"
|
|
8607
|
+
};
|
|
8608
|
+
await sessionQueries.update(taskId, {
|
|
8609
|
+
config: {
|
|
8610
|
+
toolApprovals: { bash: false, write_file: false, read_file: false },
|
|
8611
|
+
task: failedTask
|
|
8612
|
+
}
|
|
8613
|
+
});
|
|
8614
|
+
}
|
|
8615
|
+
} finally {
|
|
8616
|
+
taskAbortControllers.delete(taskId);
|
|
8617
|
+
}
|
|
8618
|
+
})();
|
|
8619
|
+
return c.json({ taskId, status: "running" }, 201);
|
|
8620
|
+
}
|
|
8621
|
+
);
|
|
8622
|
+
tasks.get("/:id", async (c) => {
|
|
8623
|
+
const id = c.req.param("id");
|
|
8624
|
+
const session = await sessionQueries.getById(id);
|
|
8625
|
+
if (!session) {
|
|
8626
|
+
return c.json({ error: "Task not found" }, 404);
|
|
8627
|
+
}
|
|
8628
|
+
const task = session.config?.task;
|
|
8629
|
+
if (!task?.enabled) {
|
|
8630
|
+
return c.json({ error: "Session is not a task" }, 400);
|
|
8631
|
+
}
|
|
8632
|
+
return c.json({
|
|
8633
|
+
taskId: id,
|
|
8634
|
+
status: task.status,
|
|
8635
|
+
result: task.result,
|
|
8636
|
+
error: task.error,
|
|
8637
|
+
iterations: task.iterations,
|
|
8638
|
+
model: session.model,
|
|
8639
|
+
name: session.name,
|
|
8640
|
+
createdAt: session.createdAt.toISOString(),
|
|
8641
|
+
updatedAt: session.updatedAt.toISOString()
|
|
8642
|
+
});
|
|
8643
|
+
});
|
|
8644
|
+
tasks.post("/:id/cancel", async (c) => {
|
|
8645
|
+
const id = c.req.param("id");
|
|
8646
|
+
const session = await sessionQueries.getById(id);
|
|
8647
|
+
if (!session) {
|
|
8648
|
+
return c.json({ error: "Task not found" }, 404);
|
|
8649
|
+
}
|
|
8650
|
+
const task = session.config?.task;
|
|
8651
|
+
if (!task?.enabled) {
|
|
8652
|
+
return c.json({ error: "Session is not a task" }, 400);
|
|
8653
|
+
}
|
|
8654
|
+
if (task.status !== "running") {
|
|
8655
|
+
return c.json({ error: `Task is already ${task.status}` }, 400);
|
|
8656
|
+
}
|
|
8657
|
+
const abortController = taskAbortControllers.get(id);
|
|
8658
|
+
if (abortController) {
|
|
8659
|
+
abortController.abort();
|
|
8660
|
+
taskAbortControllers.delete(id);
|
|
8661
|
+
}
|
|
8662
|
+
const cancelledTask = {
|
|
8663
|
+
...task,
|
|
8664
|
+
status: "failed",
|
|
8665
|
+
error: "Task cancelled by user"
|
|
8666
|
+
};
|
|
8667
|
+
await sessionQueries.update(id, {
|
|
8668
|
+
config: { ...session.config, task: cancelledTask }
|
|
8669
|
+
});
|
|
8670
|
+
return c.json({ taskId: id, status: "failed", error: "Task cancelled by user" });
|
|
8671
|
+
});
|
|
8672
|
+
var tasks_default = tasks;
|
|
8673
|
+
|
|
8138
8674
|
// src/server/index.ts
|
|
8139
8675
|
init_config();
|
|
8140
8676
|
init_db();
|
|
@@ -8471,7 +9007,7 @@ function stopWebUI() {
|
|
|
8471
9007
|
}
|
|
8472
9008
|
}
|
|
8473
9009
|
async function createApp(options = {}) {
|
|
8474
|
-
const app = new
|
|
9010
|
+
const app = new Hono6();
|
|
8475
9011
|
app.use("*", cors({
|
|
8476
9012
|
origin: "*",
|
|
8477
9013
|
// Allow all origins
|
|
@@ -8489,6 +9025,7 @@ async function createApp(options = {}) {
|
|
|
8489
9025
|
app.route("/agents", agents);
|
|
8490
9026
|
app.route("/sessions", terminals);
|
|
8491
9027
|
app.route("/terminals", terminals);
|
|
9028
|
+
app.route("/tasks", tasks_default);
|
|
8492
9029
|
app.get("/openapi.json", async (c) => {
|
|
8493
9030
|
return c.json(generateOpenAPISpec());
|
|
8494
9031
|
});
|