@standardagents/builder 0.10.1-dev.d2d335e → 0.10.1-next.9e1860c
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/built-in-routes.js +6092 -117
- package/dist/built-in-routes.js.map +1 -1
- package/dist/client/assets/index.css +1 -1
- package/dist/client/index.js +28 -19
- package/dist/client/vendor.js +1 -1
- package/dist/client/vue.js +1 -1
- package/dist/index.d.ts +442 -814
- package/dist/index.js +5015 -3848
- package/dist/index.js.map +1 -1
- package/dist/plugin.d.ts +1 -0
- package/dist/plugin.js +190 -73
- package/dist/plugin.js.map +1 -1
- package/dist/sip.wasm +0 -0
- package/package.json +9 -5
package/dist/plugin.d.ts
CHANGED
package/dist/plugin.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import fs2 from 'fs';
|
|
2
2
|
import path3 from 'path';
|
|
3
3
|
import { fileURLToPath } from 'url';
|
|
4
|
-
import { createRequire } from 'module';
|
|
5
4
|
|
|
6
5
|
// src/plugin.ts
|
|
7
6
|
var TSCONFIG_CONTENT = `{
|
|
@@ -398,6 +397,9 @@ declare module 'virtual:@standardagents/builder' {
|
|
|
398
397
|
listThreads(params?: {
|
|
399
398
|
agent_name?: string;
|
|
400
399
|
user_id?: string;
|
|
400
|
+
search?: string;
|
|
401
|
+
startDate?: number;
|
|
402
|
+
endDate?: number;
|
|
401
403
|
limit?: number;
|
|
402
404
|
offset?: number;
|
|
403
405
|
}): Promise<{ threads: ThreadRegistryEntry[]; total: number }>;
|
|
@@ -813,16 +815,6 @@ function generatePromptFile(data) {
|
|
|
813
815
|
const toolsCode = formatToolsArray(data.tools);
|
|
814
816
|
lines.push(` tools: ${toolsCode},`);
|
|
815
817
|
}
|
|
816
|
-
if (data.handoffAgents && data.handoffAgents.length > 0) {
|
|
817
|
-
const agentsStr = data.handoffAgents.map((a) => `'${escapeString2(a)}'`).join(", ");
|
|
818
|
-
lines.push(` handoffAgents: [${agentsStr}],`);
|
|
819
|
-
}
|
|
820
|
-
if (data.beforeTool) {
|
|
821
|
-
lines.push(` beforeTool: '${escapeString2(data.beforeTool)}',`);
|
|
822
|
-
}
|
|
823
|
-
if (data.afterTool) {
|
|
824
|
-
lines.push(` afterTool: '${escapeString2(data.afterTool)}',`);
|
|
825
|
-
}
|
|
826
818
|
if (data.reasoning && hasNonNullProperties(data.reasoning)) {
|
|
827
819
|
const reasoningCode = formatReasoningConfig(data.reasoning);
|
|
828
820
|
lines.push(` reasoning: ${reasoningCode},`);
|
|
@@ -1000,9 +992,6 @@ function generateAgentFile(data) {
|
|
|
1000
992
|
if (data.toolDescription) {
|
|
1001
993
|
lines.push(` toolDescription: '${escapeString3(data.toolDescription)}',`);
|
|
1002
994
|
}
|
|
1003
|
-
if (data.tags && data.tags.length > 0) {
|
|
1004
|
-
lines.push(` tags: ${JSON.stringify(data.tags)},`);
|
|
1005
|
-
}
|
|
1006
995
|
lines.push(`});`);
|
|
1007
996
|
lines.push("");
|
|
1008
997
|
return lines.join("\n");
|
|
@@ -1022,11 +1011,11 @@ function formatSideConfig(config) {
|
|
|
1022
1011
|
if (config.stopToolResponseProperty) {
|
|
1023
1012
|
parts.push(` stopToolResponseProperty: '${escapeString3(config.stopToolResponseProperty)}',`);
|
|
1024
1013
|
}
|
|
1025
|
-
if (config.
|
|
1026
|
-
parts.push(`
|
|
1014
|
+
if (config.maxSteps !== void 0) {
|
|
1015
|
+
parts.push(` maxSteps: ${config.maxSteps},`);
|
|
1027
1016
|
}
|
|
1028
|
-
if (config.
|
|
1029
|
-
parts.push(`
|
|
1017
|
+
if (config.endSessionTool) {
|
|
1018
|
+
parts.push(` endSessionTool: '${escapeString3(config.endSessionTool)}',`);
|
|
1030
1019
|
}
|
|
1031
1020
|
if (config.manualStopCondition !== void 0) {
|
|
1032
1021
|
parts.push(` manualStopCondition: ${config.manualStopCondition},`);
|
|
@@ -1126,7 +1115,7 @@ function validateModelData(data) {
|
|
|
1126
1115
|
if (!data.provider || typeof data.provider !== "string") {
|
|
1127
1116
|
return "Model provider is required and must be a string";
|
|
1128
1117
|
}
|
|
1129
|
-
const validProviders = ["openai", "openrouter", "anthropic", "google"];
|
|
1118
|
+
const validProviders = ["openai", "openrouter", "anthropic", "google", "test"];
|
|
1130
1119
|
if (!validProviders.includes(data.provider)) {
|
|
1131
1120
|
return `Invalid provider '${data.provider}'. Must be one of: ${validProviders.join(", ")}`;
|
|
1132
1121
|
}
|
|
@@ -1173,11 +1162,8 @@ function transformPromptData(data) {
|
|
|
1173
1162
|
required_schema: "requiredSchema",
|
|
1174
1163
|
include_chat: "includeChat",
|
|
1175
1164
|
include_past_tools: "includePastTools",
|
|
1176
|
-
before_tool: "beforeTool",
|
|
1177
|
-
after_tool: "afterTool",
|
|
1178
1165
|
parallel_tool_calls: "parallelToolCalls",
|
|
1179
1166
|
tool_choice: "toolChoice",
|
|
1180
|
-
handoff_agents: "handoffAgents",
|
|
1181
1167
|
reasoning_effort: "reasoningEffort",
|
|
1182
1168
|
reasoning_max_tokens: "reasoningMaxTokens",
|
|
1183
1169
|
reasoning_exclude: "reasoningExclude",
|
|
@@ -1328,9 +1314,6 @@ function validatePromptData(data) {
|
|
|
1328
1314
|
if (data.tools !== void 0 && !Array.isArray(data.tools)) {
|
|
1329
1315
|
return "tools must be an array";
|
|
1330
1316
|
}
|
|
1331
|
-
if (data.handoffAgents !== void 0 && !Array.isArray(data.handoffAgents)) {
|
|
1332
|
-
return "handoffAgents must be an array";
|
|
1333
|
-
}
|
|
1334
1317
|
if (data.reasoning !== void 0) {
|
|
1335
1318
|
if (typeof data.reasoning !== "object") {
|
|
1336
1319
|
return "reasoning must be an object";
|
|
@@ -1375,11 +1358,11 @@ function transformAgentData(data) {
|
|
|
1375
1358
|
if (data.side_a_stop_tool_response_property) {
|
|
1376
1359
|
transformed.sideA.stopToolResponseProperty = data.side_a_stop_tool_response_property;
|
|
1377
1360
|
}
|
|
1378
|
-
if (data.
|
|
1379
|
-
transformed.sideA.
|
|
1361
|
+
if (data.side_a_max_steps !== void 0) {
|
|
1362
|
+
transformed.sideA.maxSteps = data.side_a_max_steps;
|
|
1380
1363
|
}
|
|
1381
|
-
if (data.
|
|
1382
|
-
transformed.sideA.
|
|
1364
|
+
if (data.side_a_end_session_tool) {
|
|
1365
|
+
transformed.sideA.endSessionTool = data.side_a_end_session_tool;
|
|
1383
1366
|
}
|
|
1384
1367
|
if (data.side_a_manual_stop_condition !== void 0) {
|
|
1385
1368
|
transformed.sideA.manualStopCondition = data.side_a_manual_stop_condition;
|
|
@@ -1400,11 +1383,11 @@ function transformAgentData(data) {
|
|
|
1400
1383
|
if (data.side_b_stop_tool_response_property) {
|
|
1401
1384
|
transformed.sideB.stopToolResponseProperty = data.side_b_stop_tool_response_property;
|
|
1402
1385
|
}
|
|
1403
|
-
if (data.
|
|
1404
|
-
transformed.sideB.
|
|
1386
|
+
if (data.side_b_max_steps !== void 0) {
|
|
1387
|
+
transformed.sideB.maxSteps = data.side_b_max_steps;
|
|
1405
1388
|
}
|
|
1406
|
-
if (data.
|
|
1407
|
-
transformed.sideB.
|
|
1389
|
+
if (data.side_b_end_session_tool) {
|
|
1390
|
+
transformed.sideB.endSessionTool = data.side_b_end_session_tool;
|
|
1408
1391
|
}
|
|
1409
1392
|
if (data.side_b_manual_stop_condition !== void 0) {
|
|
1410
1393
|
transformed.sideB.manualStopCondition = data.side_b_manual_stop_condition;
|
|
@@ -1416,9 +1399,6 @@ function transformAgentData(data) {
|
|
|
1416
1399
|
if (data.tool_description) {
|
|
1417
1400
|
transformed.toolDescription = data.tool_description;
|
|
1418
1401
|
}
|
|
1419
|
-
if (data.tags) {
|
|
1420
|
-
transformed.tags = data.tags;
|
|
1421
|
-
}
|
|
1422
1402
|
return transformed;
|
|
1423
1403
|
}
|
|
1424
1404
|
function getAgentFilePath(agentsDir, name) {
|
|
@@ -1606,9 +1586,9 @@ function validateAgentData(data) {
|
|
|
1606
1586
|
if (data.sideA.stopTool && !data.sideA.stopToolResponseProperty) {
|
|
1607
1587
|
return "sideA.stopToolResponseProperty is required when sideA.stopTool is set";
|
|
1608
1588
|
}
|
|
1609
|
-
if (data.sideA.
|
|
1610
|
-
if (typeof data.sideA.
|
|
1611
|
-
return "sideA.
|
|
1589
|
+
if (data.sideA.maxSteps !== void 0) {
|
|
1590
|
+
if (typeof data.sideA.maxSteps !== "number" || data.sideA.maxSteps <= 0) {
|
|
1591
|
+
return "sideA.maxSteps must be a positive number";
|
|
1612
1592
|
}
|
|
1613
1593
|
}
|
|
1614
1594
|
if (data.type === "dual_ai") {
|
|
@@ -1621,9 +1601,9 @@ function validateAgentData(data) {
|
|
|
1621
1601
|
if (data.sideB.stopTool && !data.sideB.stopToolResponseProperty) {
|
|
1622
1602
|
return "sideB.stopToolResponseProperty is required when sideB.stopTool is set";
|
|
1623
1603
|
}
|
|
1624
|
-
if (data.sideB.
|
|
1625
|
-
if (typeof data.sideB.
|
|
1626
|
-
return "sideB.
|
|
1604
|
+
if (data.sideB.maxSteps !== void 0) {
|
|
1605
|
+
if (typeof data.sideB.maxSteps !== "number" || data.sideB.maxSteps <= 0) {
|
|
1606
|
+
return "sideB.maxSteps must be a positive number";
|
|
1627
1607
|
}
|
|
1628
1608
|
}
|
|
1629
1609
|
}
|
|
@@ -1635,21 +1615,10 @@ function validateAgentData(data) {
|
|
|
1635
1615
|
return "maxSessionTurns must be a positive number";
|
|
1636
1616
|
}
|
|
1637
1617
|
}
|
|
1638
|
-
if (data.tags !== void 0) {
|
|
1639
|
-
if (!Array.isArray(data.tags)) {
|
|
1640
|
-
return "tags must be an array";
|
|
1641
|
-
}
|
|
1642
|
-
for (const tag of data.tags) {
|
|
1643
|
-
if (typeof tag !== "string") {
|
|
1644
|
-
return "Each tag must be a string";
|
|
1645
|
-
}
|
|
1646
|
-
}
|
|
1647
|
-
}
|
|
1648
1618
|
return null;
|
|
1649
1619
|
}
|
|
1650
1620
|
|
|
1651
1621
|
// src/plugin.ts
|
|
1652
|
-
createRequire(import.meta.url);
|
|
1653
1622
|
var VIRTUAL_TOOLS_ID = "virtual:@standardagents-tools";
|
|
1654
1623
|
var RESOLVED_VIRTUAL_TOOLS_ID = "\0" + VIRTUAL_TOOLS_ID;
|
|
1655
1624
|
var VIRTUAL_ROUTES_ID = "virtual:@standardagents-routes";
|
|
@@ -1668,6 +1637,8 @@ var VIRTUAL_PROMPTS_ID = "virtual:@standardagents-prompts";
|
|
|
1668
1637
|
var RESOLVED_VIRTUAL_PROMPTS_ID = "\0" + VIRTUAL_PROMPTS_ID;
|
|
1669
1638
|
var VIRTUAL_AGENTS_ID = "virtual:@standardagents-agents";
|
|
1670
1639
|
var RESOLVED_VIRTUAL_AGENTS_ID = "\0" + VIRTUAL_AGENTS_ID;
|
|
1640
|
+
var VIRTUAL_EFFECTS_ID = "virtual:@standardagents-effects";
|
|
1641
|
+
var RESOLVED_VIRTUAL_EFFECTS_ID = "\0" + VIRTUAL_EFFECTS_ID;
|
|
1671
1642
|
var VIRTUAL_BUILDER_ID = "virtual:@standardagents/builder";
|
|
1672
1643
|
var RESOLVED_VIRTUAL_BUILDER_ID = "\0" + VIRTUAL_BUILDER_ID;
|
|
1673
1644
|
function scanApiDirectory(dir, baseRoute = "") {
|
|
@@ -1843,6 +1814,33 @@ async function scanPromptsDirectory(dir) {
|
|
|
1843
1814
|
async function scanAgentsDirectory(dir) {
|
|
1844
1815
|
return scanConfigDirectory(dir, /export\s+default\s+defineAgent/);
|
|
1845
1816
|
}
|
|
1817
|
+
async function scanEffectsDirectory(dir) {
|
|
1818
|
+
const effects = [];
|
|
1819
|
+
if (!fs2.existsSync(dir)) {
|
|
1820
|
+
return effects;
|
|
1821
|
+
}
|
|
1822
|
+
const entries = await fs2.promises.readdir(dir, { withFileTypes: true });
|
|
1823
|
+
for (const entry of entries) {
|
|
1824
|
+
if (entry.isFile() && entry.name.endsWith(".ts")) {
|
|
1825
|
+
const fileName = entry.name.replace(".ts", "");
|
|
1826
|
+
const filePath = path3.join(dir, entry.name);
|
|
1827
|
+
const importPath = "./" + path3.relative(process.cwd(), filePath).replace(/\\/g, "/");
|
|
1828
|
+
if (fileName === "CLAUDE" || fileName.startsWith("_")) {
|
|
1829
|
+
continue;
|
|
1830
|
+
}
|
|
1831
|
+
try {
|
|
1832
|
+
const content = fs2.readFileSync(filePath, "utf-8");
|
|
1833
|
+
if (!content.includes("defineEffect")) {
|
|
1834
|
+
continue;
|
|
1835
|
+
}
|
|
1836
|
+
} catch {
|
|
1837
|
+
continue;
|
|
1838
|
+
}
|
|
1839
|
+
effects.push({ name: fileName, importPath });
|
|
1840
|
+
}
|
|
1841
|
+
}
|
|
1842
|
+
return effects;
|
|
1843
|
+
}
|
|
1846
1844
|
function parseRequestBody(req) {
|
|
1847
1845
|
return new Promise((resolve, reject) => {
|
|
1848
1846
|
let body = "";
|
|
@@ -1873,6 +1871,7 @@ function agentbuilder(options = {}) {
|
|
|
1873
1871
|
const modelsDir = options.modelsDir ? path3.resolve(process.cwd(), options.modelsDir) : path3.resolve(process.cwd(), "agents/models");
|
|
1874
1872
|
const promptsDir = options.promptsDir ? path3.resolve(process.cwd(), options.promptsDir) : path3.resolve(process.cwd(), "agents/prompts");
|
|
1875
1873
|
const agentsDir = options.agentsDir ? path3.resolve(process.cwd(), options.agentsDir) : path3.resolve(process.cwd(), "agents/agents");
|
|
1874
|
+
const effectsDir = options.effectsDir ? path3.resolve(process.cwd(), options.effectsDir) : path3.resolve(process.cwd(), "agents/effects");
|
|
1876
1875
|
const outputDir = path3.resolve(process.cwd(), ".agents");
|
|
1877
1876
|
const typeGenConfig = {
|
|
1878
1877
|
modelsDir,
|
|
@@ -2072,7 +2071,15 @@ function agentbuilder(options = {}) {
|
|
|
2072
2071
|
"zod",
|
|
2073
2072
|
"openai"
|
|
2074
2073
|
];
|
|
2074
|
+
const currentDir = path3.dirname(fileURLToPath(import.meta.url));
|
|
2075
|
+
const isInDist = currentDir.endsWith("dist");
|
|
2076
|
+
const builderClientDir = path3.resolve(
|
|
2077
|
+
currentDir,
|
|
2078
|
+
isInDist ? "./client" : "../dist/client"
|
|
2079
|
+
);
|
|
2075
2080
|
return {
|
|
2081
|
+
// Set publicDir to builder's client assets so Cloudflare plugin preserves assets config
|
|
2082
|
+
publicDir: fs2.existsSync(builderClientDir) ? builderClientDir : void 0,
|
|
2076
2083
|
optimizeDeps: {
|
|
2077
2084
|
// Exclude our packages from pre-bundling - they contain cloudflare:workers imports
|
|
2078
2085
|
// that cannot be resolved during dependency optimization
|
|
@@ -2145,6 +2152,9 @@ function agentbuilder(options = {}) {
|
|
|
2145
2152
|
if (id === VIRTUAL_AGENTS_ID) {
|
|
2146
2153
|
return RESOLVED_VIRTUAL_AGENTS_ID;
|
|
2147
2154
|
}
|
|
2155
|
+
if (id === VIRTUAL_EFFECTS_ID) {
|
|
2156
|
+
return RESOLVED_VIRTUAL_EFFECTS_ID;
|
|
2157
|
+
}
|
|
2148
2158
|
if (id === VIRTUAL_BUILDER_ID) {
|
|
2149
2159
|
return RESOLVED_VIRTUAL_BUILDER_ID;
|
|
2150
2160
|
}
|
|
@@ -2223,6 +2233,48 @@ function isPublicRoute(routePath) {
|
|
|
2223
2233
|
return false;
|
|
2224
2234
|
}
|
|
2225
2235
|
|
|
2236
|
+
// CORS headers for API responses
|
|
2237
|
+
const CORS_HEADERS = {
|
|
2238
|
+
"Access-Control-Allow-Origin": "*",
|
|
2239
|
+
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, PATCH, OPTIONS",
|
|
2240
|
+
"Access-Control-Allow-Headers": "Content-Type, Authorization, X-Requested-With",
|
|
2241
|
+
"Access-Control-Max-Age": "86400",
|
|
2242
|
+
};
|
|
2243
|
+
|
|
2244
|
+
// Helper to create headers with CORS
|
|
2245
|
+
function corsHeaders(contentType) {
|
|
2246
|
+
return {
|
|
2247
|
+
"Content-Type": contentType,
|
|
2248
|
+
...CORS_HEADERS,
|
|
2249
|
+
};
|
|
2250
|
+
}
|
|
2251
|
+
|
|
2252
|
+
// Helper to add CORS headers to any Response without touching the body
|
|
2253
|
+
function addCorsHeaders(response) {
|
|
2254
|
+
// Skip WebSocket upgrade responses - they can't be wrapped
|
|
2255
|
+
if (response.status === 101) {
|
|
2256
|
+
return response;
|
|
2257
|
+
}
|
|
2258
|
+
|
|
2259
|
+
// Skip if already has CORS headers
|
|
2260
|
+
if (response.headers.has("Access-Control-Allow-Origin")) {
|
|
2261
|
+
return response;
|
|
2262
|
+
}
|
|
2263
|
+
|
|
2264
|
+
// Create new headers with CORS added
|
|
2265
|
+
const newHeaders = new Headers(response.headers);
|
|
2266
|
+
for (const [key, value] of Object.entries(CORS_HEADERS)) {
|
|
2267
|
+
newHeaders.set(key, value);
|
|
2268
|
+
}
|
|
2269
|
+
|
|
2270
|
+
// Return new Response with same body stream (not cloned, just transferred)
|
|
2271
|
+
return new Response(response.body, {
|
|
2272
|
+
status: response.status,
|
|
2273
|
+
statusText: response.statusText,
|
|
2274
|
+
headers: newHeaders,
|
|
2275
|
+
});
|
|
2276
|
+
}
|
|
2277
|
+
|
|
2226
2278
|
export async function router(request, env) {
|
|
2227
2279
|
const url = new URL(request.url);
|
|
2228
2280
|
const pathname = url.pathname;
|
|
@@ -2232,6 +2284,14 @@ export async function router(request, env) {
|
|
|
2232
2284
|
return null;
|
|
2233
2285
|
}
|
|
2234
2286
|
|
|
2287
|
+
// Handle CORS preflight requests
|
|
2288
|
+
if (request.method === "OPTIONS") {
|
|
2289
|
+
return new Response(null, {
|
|
2290
|
+
status: 204,
|
|
2291
|
+
headers: CORS_HEADERS,
|
|
2292
|
+
});
|
|
2293
|
+
}
|
|
2294
|
+
|
|
2235
2295
|
// Strip mount point prefix for route matching, ensuring we keep the leading slash
|
|
2236
2296
|
let routePath = pathname.slice(MOUNT_POINT.length) || "/";
|
|
2237
2297
|
if (!routePath.startsWith('/')) {
|
|
@@ -2266,7 +2326,7 @@ ${threadRouteCode}
|
|
|
2266
2326
|
|
|
2267
2327
|
// If requireAuth returns a Response, it's an error (401)
|
|
2268
2328
|
if (authResult instanceof Response) {
|
|
2269
|
-
return authResult;
|
|
2329
|
+
return addCorsHeaders(authResult);
|
|
2270
2330
|
}
|
|
2271
2331
|
|
|
2272
2332
|
authContext = authResult;
|
|
@@ -2285,16 +2345,17 @@ ${threadRouteCode}
|
|
|
2285
2345
|
const result = await controller(context);
|
|
2286
2346
|
|
|
2287
2347
|
if (result instanceof Response) {
|
|
2288
|
-
return result;
|
|
2348
|
+
return addCorsHeaders(result);
|
|
2289
2349
|
}
|
|
2290
2350
|
if (typeof result === "string") {
|
|
2291
2351
|
return new Response(result, {
|
|
2292
|
-
headers:
|
|
2293
|
-
"Content-Type": "text/plain",
|
|
2294
|
-
},
|
|
2352
|
+
headers: corsHeaders("text/plain"),
|
|
2295
2353
|
});
|
|
2296
2354
|
}
|
|
2297
|
-
|
|
2355
|
+
// JSON responses get CORS headers
|
|
2356
|
+
return new Response(JSON.stringify(result), {
|
|
2357
|
+
headers: corsHeaders("application/json"),
|
|
2358
|
+
});
|
|
2298
2359
|
}
|
|
2299
2360
|
|
|
2300
2361
|
// Serve UI for all other routes (SPA fallback)
|
|
@@ -2309,13 +2370,15 @@ async function serveUI(pathname, env) {
|
|
|
2309
2370
|
// Create a proper request for the asset path
|
|
2310
2371
|
// Use a dummy origin since we only care about the path
|
|
2311
2372
|
// Re-add mount point since pathname was stripped by router
|
|
2312
|
-
|
|
2373
|
+
// Handle root mountPoint "/" specially to avoid double slashes
|
|
2374
|
+
const mountPrefix = MOUNT_POINT === "/" ? "" : MOUNT_POINT;
|
|
2375
|
+
const assetUrl = \`http://localhost\${mountPrefix}\${pathname}\`;
|
|
2313
2376
|
let response = await env.ASSETS.fetch(assetUrl);
|
|
2314
2377
|
|
|
2315
2378
|
// If not found, fall back to index.html for SPA routing
|
|
2316
2379
|
const isIndexHtml = response.status === 404 || pathname === "/" || !pathname.includes(".");
|
|
2317
2380
|
if (isIndexHtml) {
|
|
2318
|
-
response = await env.ASSETS.fetch(\`http://localhost\${
|
|
2381
|
+
response = await env.ASSETS.fetch(\`http://localhost\${mountPrefix}/index.html\`);
|
|
2319
2382
|
|
|
2320
2383
|
// Transform HTML to use configured mount point
|
|
2321
2384
|
if (response.status === 200) {
|
|
@@ -2462,6 +2525,31 @@ ${agentsCode}
|
|
|
2462
2525
|
};
|
|
2463
2526
|
|
|
2464
2527
|
export const agentNames = ${JSON.stringify(agents.filter((a) => !a.error).map((a) => a.name))};
|
|
2528
|
+
`;
|
|
2529
|
+
}
|
|
2530
|
+
if (id === RESOLVED_VIRTUAL_EFFECTS_ID) {
|
|
2531
|
+
const effects = await scanEffectsDirectory(effectsDir);
|
|
2532
|
+
const effectsCode = effects.map(({ name, importPath, error }) => {
|
|
2533
|
+
if (error) {
|
|
2534
|
+
const escapedError = error.replace(/"/g, '\\"').replace(/\n/g, "\\n");
|
|
2535
|
+
return ` "${name}": async () => { throw new Error("${escapedError}"); },`;
|
|
2536
|
+
} else {
|
|
2537
|
+
return ` "${name}": async () => {
|
|
2538
|
+
try {
|
|
2539
|
+
return (await import("${importPath}")).default;
|
|
2540
|
+
} catch (error) {
|
|
2541
|
+
console.error('Failed to import effect ${name}:', error);
|
|
2542
|
+
throw error;
|
|
2543
|
+
}
|
|
2544
|
+
},`;
|
|
2545
|
+
}
|
|
2546
|
+
}).join("\n");
|
|
2547
|
+
return `// Virtual agent effects module
|
|
2548
|
+
export const effects = {
|
|
2549
|
+
${effectsCode}
|
|
2550
|
+
};
|
|
2551
|
+
|
|
2552
|
+
export const effectNames = ${JSON.stringify(effects.filter((e) => !e.error).map((e) => e.name))};
|
|
2465
2553
|
`;
|
|
2466
2554
|
}
|
|
2467
2555
|
if (id === RESOLVED_VIRTUAL_BUILDER_ID) {
|
|
@@ -2470,6 +2558,7 @@ export const agentNames = ${JSON.stringify(agents.filter((a) => !a.error).map((a
|
|
|
2470
2558
|
const models = await scanModelsDirectory(modelsDir);
|
|
2471
2559
|
const prompts = await scanPromptsDirectory(promptsDir);
|
|
2472
2560
|
const agents = await scanAgentsDirectory(agentsDir);
|
|
2561
|
+
const effects = await scanEffectsDirectory(effectsDir);
|
|
2473
2562
|
const toAbsolutePath = (relativePath) => {
|
|
2474
2563
|
if (relativePath.startsWith("./")) {
|
|
2475
2564
|
return path3.resolve(process.cwd(), relativePath).replace(/\\/g, "/");
|
|
@@ -2548,6 +2637,22 @@ export const agentNames = ${JSON.stringify(agents.filter((a) => !a.error).map((a
|
|
|
2548
2637
|
console.error('Failed to import agent ${name}:', error);
|
|
2549
2638
|
throw error;
|
|
2550
2639
|
}
|
|
2640
|
+
},`;
|
|
2641
|
+
}
|
|
2642
|
+
}).join("\n");
|
|
2643
|
+
const effectsCode = effects.map(({ name, importPath, error }) => {
|
|
2644
|
+
const absPath = toAbsolutePath(importPath);
|
|
2645
|
+
if (error) {
|
|
2646
|
+
const escapedError = error.replace(/"/g, '\\"').replace(/\n/g, "\\n");
|
|
2647
|
+
return ` "${name}": async () => { throw new Error("${escapedError}"); },`;
|
|
2648
|
+
} else {
|
|
2649
|
+
return ` "${name}": async () => {
|
|
2650
|
+
try {
|
|
2651
|
+
return (await import("${absPath}")).default;
|
|
2652
|
+
} catch (error) {
|
|
2653
|
+
console.error('Failed to import effect ${name}:', error);
|
|
2654
|
+
throw error;
|
|
2655
|
+
}
|
|
2551
2656
|
},`;
|
|
2552
2657
|
}
|
|
2553
2658
|
}).join("\n");
|
|
@@ -2558,7 +2663,8 @@ import { DurableAgentBuilder as _BaseDurableAgentBuilder } from '@standardagents
|
|
|
2558
2663
|
|
|
2559
2664
|
// Import sip WASM module and initializer
|
|
2560
2665
|
// Static import allows workerd to pre-compile the WASM at bundle time
|
|
2561
|
-
|
|
2666
|
+
// WASM is bundled in builder's dist to avoid transitive dependency resolution issues
|
|
2667
|
+
import _sipWasm from '@standardagents/builder/dist/sip.wasm';
|
|
2562
2668
|
import { initWithWasmModule as _initSipWasm } from '@standardagents/sip';
|
|
2563
2669
|
|
|
2564
2670
|
// Re-export router from virtual:@standardagents-routes
|
|
@@ -2585,6 +2691,10 @@ const _agents = {
|
|
|
2585
2691
|
${agentsCode}
|
|
2586
2692
|
};
|
|
2587
2693
|
|
|
2694
|
+
const _effects = {
|
|
2695
|
+
${effectsCode}
|
|
2696
|
+
};
|
|
2697
|
+
|
|
2588
2698
|
/**
|
|
2589
2699
|
* DurableThread with all virtual module methods already implemented.
|
|
2590
2700
|
* Simply extend this class in your agents/Thread.ts file.
|
|
@@ -2619,6 +2729,10 @@ export class DurableThread extends _BaseDurableThread {
|
|
|
2619
2729
|
agents() {
|
|
2620
2730
|
return _agents;
|
|
2621
2731
|
}
|
|
2732
|
+
|
|
2733
|
+
effects() {
|
|
2734
|
+
return _effects;
|
|
2735
|
+
}
|
|
2622
2736
|
}
|
|
2623
2737
|
|
|
2624
2738
|
/**
|
|
@@ -2645,6 +2759,10 @@ export class DurableAgentBuilder extends _BaseDurableAgentBuilder {
|
|
|
2645
2759
|
agents() {
|
|
2646
2760
|
return _agents;
|
|
2647
2761
|
}
|
|
2762
|
+
|
|
2763
|
+
effects() {
|
|
2764
|
+
return _effects;
|
|
2765
|
+
}
|
|
2648
2766
|
}
|
|
2649
2767
|
`;
|
|
2650
2768
|
}
|
|
@@ -2657,6 +2775,7 @@ export class DurableAgentBuilder extends _BaseDurableAgentBuilder {
|
|
|
2657
2775
|
this.addWatchFile(modelsDir);
|
|
2658
2776
|
this.addWatchFile(promptsDir);
|
|
2659
2777
|
this.addWatchFile(agentsDir);
|
|
2778
|
+
this.addWatchFile(effectsDir);
|
|
2660
2779
|
},
|
|
2661
2780
|
configureServer(server) {
|
|
2662
2781
|
server.watcher.on("add", async (file) => {
|
|
@@ -2901,20 +3020,12 @@ export class DurableAgentBuilder extends _BaseDurableAgentBuilder {
|
|
|
2901
3020
|
const getIncludePastTools = (c) => c.match(/includePastTools:\s*(true|false)/)?.[1] === "true";
|
|
2902
3021
|
const getParallelToolCalls = (c) => c.match(/parallelToolCalls:\s*(true|false)/)?.[1] === "true";
|
|
2903
3022
|
const getToolChoice = (c) => c.match(/toolChoice:\s*['"]([^'"]+)['"]/)?.[1];
|
|
2904
|
-
const getBeforeTool = (c) => c.match(/beforeTool:\s*['"]([^'"]+)['"]/)?.[1];
|
|
2905
|
-
const getAfterTool = (c) => c.match(/afterTool:\s*['"]([^'"]+)['"]/)?.[1];
|
|
2906
3023
|
const getTools = (c) => {
|
|
2907
3024
|
const match = c.match(/tools:\s*\[([^\]]*)\]/);
|
|
2908
3025
|
if (!match) return [];
|
|
2909
3026
|
const items = match[1].match(/['"]([^'"]+)['"]/g);
|
|
2910
3027
|
return items ? items.map((s) => s.replace(/['"]/g, "")) : [];
|
|
2911
3028
|
};
|
|
2912
|
-
const getHandoffAgents = (c) => {
|
|
2913
|
-
const match = c.match(/handoffAgents:\s*\[([^\]]*)\]/);
|
|
2914
|
-
if (!match) return [];
|
|
2915
|
-
const items = match[1].match(/['"]([^'"]+)['"]/g);
|
|
2916
|
-
return items ? items.map((s) => s.replace(/['"]/g, "")) : [];
|
|
2917
|
-
};
|
|
2918
3029
|
const getPrompt = (c) => {
|
|
2919
3030
|
const backtickMatch = c.match(/prompt:\s*`([\s\S]*?)`/);
|
|
2920
3031
|
if (backtickMatch) return backtickMatch[1];
|
|
@@ -2942,10 +3053,7 @@ export class DurableAgentBuilder extends _BaseDurableAgentBuilder {
|
|
|
2942
3053
|
include_past_tools: getIncludePastTools(content),
|
|
2943
3054
|
parallel_tool_calls: getParallelToolCalls(content),
|
|
2944
3055
|
tool_choice: getToolChoice(content) || "auto",
|
|
2945
|
-
before_tool: getBeforeTool(content) || null,
|
|
2946
|
-
after_tool: getAfterTool(content) || null,
|
|
2947
3056
|
tools: getTools(content),
|
|
2948
|
-
prompts: getHandoffAgents(content),
|
|
2949
3057
|
reasoning: null,
|
|
2950
3058
|
// Complex to parse
|
|
2951
3059
|
created_at: Math.floor(Date.now() / 1e3)
|
|
@@ -3111,6 +3219,13 @@ export class DurableAgentBuilder extends _BaseDurableAgentBuilder {
|
|
|
3111
3219
|
const items = match[1].match(/['"]([^'"]+)['"]/g);
|
|
3112
3220
|
return items ? items.map((s) => s.replace(/['"]/g, "")) : [];
|
|
3113
3221
|
};
|
|
3222
|
+
const getSidePrompt = (c, side) => {
|
|
3223
|
+
const sideRegex = new RegExp(`${side}:\\s*\\{([^}]+)\\}`, "s");
|
|
3224
|
+
const sideMatch = c.match(sideRegex);
|
|
3225
|
+
if (!sideMatch) return null;
|
|
3226
|
+
const promptMatch = sideMatch[1].match(/prompt:\s*['"]([^'"]+)['"]/);
|
|
3227
|
+
return promptMatch ? promptMatch[1] : null;
|
|
3228
|
+
};
|
|
3114
3229
|
const name = getName(content);
|
|
3115
3230
|
if (!name) return null;
|
|
3116
3231
|
return {
|
|
@@ -3121,6 +3236,8 @@ export class DurableAgentBuilder extends _BaseDurableAgentBuilder {
|
|
|
3121
3236
|
default_prompt: getDefaultPrompt(content) || "",
|
|
3122
3237
|
default_model: getDefaultModel(content) || "",
|
|
3123
3238
|
tools: getTools(content),
|
|
3239
|
+
side_a_agent_prompt: getSidePrompt(content, "sideA"),
|
|
3240
|
+
side_b_agent_prompt: getSidePrompt(content, "sideB"),
|
|
3124
3241
|
created_at: Math.floor(Date.now() / 1e3)
|
|
3125
3242
|
};
|
|
3126
3243
|
} catch (error) {
|