@standardagents/builder 0.40.4 → 0.40.5
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 +42 -32
- package/dist/built-in-routes.js.map +1 -1
- package/dist/index.js +152 -94
- package/dist/index.js.map +1 -1
- package/dist/plugin.d.ts +9 -0
- package/dist/plugin.js +105 -21
- package/dist/plugin.js.map +1 -1
- package/dist/runtime.d.ts +3 -4
- package/dist/runtime.js +324 -341
- package/dist/runtime.js.map +1 -1
- package/package.json +8 -8
package/dist/index.js
CHANGED
|
@@ -5083,9 +5083,7 @@ Message one with subagent_message(referenceId, message).`
|
|
|
5083
5083
|
if (resumable) {
|
|
5084
5084
|
await this.settleResumableChildAfterRun(
|
|
5085
5085
|
state,
|
|
5086
|
-
|
|
5087
|
-
childThreadId,
|
|
5088
|
-
childResult
|
|
5086
|
+
childThreadId
|
|
5089
5087
|
);
|
|
5090
5088
|
} else if (stub.terminateThread) {
|
|
5091
5089
|
await stub.terminateThread(childThreadId);
|
|
@@ -5097,7 +5095,7 @@ Message one with subagent_message(referenceId, message).`
|
|
|
5097
5095
|
attachments: copiedAttachments,
|
|
5098
5096
|
subagent_id: childThreadId
|
|
5099
5097
|
};
|
|
5100
|
-
return resumable
|
|
5098
|
+
return resumable ? this.withReferenceInToolResult(toolResult, childThreadId) : toolResult;
|
|
5101
5099
|
}
|
|
5102
5100
|
const backgroundRun = (async () => {
|
|
5103
5101
|
try {
|
|
@@ -5132,9 +5130,7 @@ Message one with subagent_message(referenceId, message).`
|
|
|
5132
5130
|
if (resumable) {
|
|
5133
5131
|
await this.settleResumableChildAfterRun(
|
|
5134
5132
|
state,
|
|
5135
|
-
|
|
5136
|
-
childThreadId,
|
|
5137
|
-
childResult
|
|
5133
|
+
childThreadId
|
|
5138
5134
|
);
|
|
5139
5135
|
} else if (stub.terminateThread) {
|
|
5140
5136
|
await stub.terminateThread(childThreadId);
|
|
@@ -5529,18 +5525,8 @@ Message one with subagent_message(referenceId, message).`
|
|
|
5529
5525
|
JSON.stringify(next)
|
|
5530
5526
|
);
|
|
5531
5527
|
}
|
|
5532
|
-
static
|
|
5533
|
-
|
|
5534
|
-
}
|
|
5535
|
-
static async settleResumableChildAfterRun(state, childThread, reference, result) {
|
|
5536
|
-
if (!this.isTerminalSubagentResult(result)) {
|
|
5537
|
-
await this.updateChildStatus(state, reference, "idle");
|
|
5538
|
-
return;
|
|
5539
|
-
}
|
|
5540
|
-
await this.updateChildStatus(state, reference, "terminated");
|
|
5541
|
-
if (typeof childThread.terminateThread === "function") {
|
|
5542
|
-
await childThread.terminateThread(reference);
|
|
5543
|
-
}
|
|
5528
|
+
static async settleResumableChildAfterRun(state, reference) {
|
|
5529
|
+
await this.updateChildStatus(state, reference, "idle");
|
|
5544
5530
|
}
|
|
5545
5531
|
static async buildChildInvocationMessages(state, childThread, content, receivesMessages, parentAttachments, initialArguments) {
|
|
5546
5532
|
const copiedAttachments = await this.copyAttachmentsBetweenThreads(
|
|
@@ -16819,7 +16805,7 @@ function createHmrReloader() {
|
|
|
16819
16805
|
const isConfigFile = isModelFile || isProviderFile || isPromptFile || isAgentFile || isEffectFile;
|
|
16820
16806
|
if (!isToolFile && !isThreadApiFile && !isHookFile && !isConfigFile && !isUserEndpointFile) return;
|
|
16821
16807
|
reloader.invalidateSourceFileModule(server, file);
|
|
16822
|
-
if (isConfigFile || isToolFile) regenerateTypes();
|
|
16808
|
+
if (isConfigFile || isToolFile || isHookFile) regenerateTypes();
|
|
16823
16809
|
if (isToolFile) await reloader.reloadToolsModule(server);
|
|
16824
16810
|
if (isModelFile) await reloader.reloadModelsModule(server);
|
|
16825
16811
|
if (isProviderFile) await reloader.reloadProvidersModule(server);
|
|
@@ -18947,6 +18933,29 @@ async function scanPromptsDirectory(dir) {
|
|
|
18947
18933
|
async function scanAgentsDirectory(dir) {
|
|
18948
18934
|
return scanConfigDirectory(dir, /export\s+default\s+defineAgent/);
|
|
18949
18935
|
}
|
|
18936
|
+
function findLegacyRootAgentFiles(agentsDir) {
|
|
18937
|
+
const agentsRoot = path9__default.dirname(agentsDir);
|
|
18938
|
+
if (path9__default.basename(agentsDir) !== "agents" || path9__default.basename(agentsRoot) !== "agents") {
|
|
18939
|
+
return [];
|
|
18940
|
+
}
|
|
18941
|
+
if (!fs9__default.existsSync(agentsRoot)) return [];
|
|
18942
|
+
return fs9__default.readdirSync(agentsRoot, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".ts")).map((entry) => path9__default.join(agentsRoot, entry.name)).filter((filePath) => {
|
|
18943
|
+
try {
|
|
18944
|
+
return /export\s+default\s+defineAgent/.test(fs9__default.readFileSync(filePath, "utf8"));
|
|
18945
|
+
} catch {
|
|
18946
|
+
return false;
|
|
18947
|
+
}
|
|
18948
|
+
}).sort();
|
|
18949
|
+
}
|
|
18950
|
+
function warnLegacyRootAgentFiles(agentsDir) {
|
|
18951
|
+
const expectedDir = path9__default.relative(process.cwd(), agentsDir).replace(/\\/g, "/");
|
|
18952
|
+
for (const filePath of findLegacyRootAgentFiles(agentsDir)) {
|
|
18953
|
+
const source = path9__default.relative(process.cwd(), filePath).replace(/\\/g, "/");
|
|
18954
|
+
console.warn(
|
|
18955
|
+
`[agentbuilder] Agent definition "${source}" is outside the scanned agent directory. Move it to "${expectedDir}/" so it is registered.`
|
|
18956
|
+
);
|
|
18957
|
+
}
|
|
18958
|
+
}
|
|
18950
18959
|
async function scanEffectsDirectory(dir) {
|
|
18951
18960
|
const effects = [];
|
|
18952
18961
|
if (!fs9__default.existsSync(dir)) {
|
|
@@ -22657,7 +22666,32 @@ function isHostedInstance(env) {
|
|
|
22657
22666
|
}
|
|
22658
22667
|
return Boolean(value);
|
|
22659
22668
|
}
|
|
22660
|
-
function
|
|
22669
|
+
function normalizeTrustedDevHosts(hosts) {
|
|
22670
|
+
const normalized = /* @__PURE__ */ new Set();
|
|
22671
|
+
for (const rawHost of hosts ?? []) {
|
|
22672
|
+
const candidate = rawHost.trim().toLowerCase().replace(/\.$/, "");
|
|
22673
|
+
try {
|
|
22674
|
+
const parsed = new URL(`http://${candidate}`);
|
|
22675
|
+
if (!candidate || candidate.includes("*") || parsed.hostname.toLowerCase().replace(/\.$/, "") !== candidate || parsed.port || parsed.username || parsed.password || parsed.pathname !== "/" || parsed.search || parsed.hash) {
|
|
22676
|
+
throw new Error("invalid hostname");
|
|
22677
|
+
}
|
|
22678
|
+
} catch {
|
|
22679
|
+
throw new Error(
|
|
22680
|
+
`Invalid trusted development hostname "${rawHost}". Use an exact hostname without a scheme, port, path, or wildcard.`
|
|
22681
|
+
);
|
|
22682
|
+
}
|
|
22683
|
+
normalized.add(candidate);
|
|
22684
|
+
}
|
|
22685
|
+
return [...normalized];
|
|
22686
|
+
}
|
|
22687
|
+
function compiledTrustedDevHosts() {
|
|
22688
|
+
try {
|
|
22689
|
+
return typeof __STANDARD_AGENTS_TRUSTED_DEV_HOSTS__ !== "undefined" && Array.isArray(__STANDARD_AGENTS_TRUSTED_DEV_HOSTS__) ? __STANDARD_AGENTS_TRUSTED_DEV_HOSTS__ : [];
|
|
22690
|
+
} catch {
|
|
22691
|
+
return [];
|
|
22692
|
+
}
|
|
22693
|
+
}
|
|
22694
|
+
function isTrustedLocalDevelopmentRequest(request, env, trustedDevHosts = compiledTrustedDevHosts()) {
|
|
22661
22695
|
if (isHostedInstance(env)) return false;
|
|
22662
22696
|
let hostname;
|
|
22663
22697
|
try {
|
|
@@ -22665,7 +22699,7 @@ function isTrustedLocalDevelopmentRequest(request, env) {
|
|
|
22665
22699
|
} catch {
|
|
22666
22700
|
return false;
|
|
22667
22701
|
}
|
|
22668
|
-
return hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1" || hostname.endsWith(".localhost") || hostname.endsWith(".orb.local");
|
|
22702
|
+
return hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1" || hostname.endsWith(".localhost") || hostname.endsWith(".orb.local") || trustedDevHosts.some((trusted) => trusted.trim().toLowerCase() === hostname);
|
|
22669
22703
|
}
|
|
22670
22704
|
function isPublicApiRoute(routePath, request, env) {
|
|
22671
22705
|
if (PUBLIC_ROUTES.has(routePath)) return true;
|
|
@@ -22814,7 +22848,8 @@ function createDevMiddleware(server, context) {
|
|
|
22814
22848
|
installedProviderPackageMap,
|
|
22815
22849
|
hmr,
|
|
22816
22850
|
sourceDirs,
|
|
22817
|
-
regenerateTypes
|
|
22851
|
+
regenerateTypes,
|
|
22852
|
+
trustedDevHosts
|
|
22818
22853
|
} = context;
|
|
22819
22854
|
server.watcher.on("add", async (file) => {
|
|
22820
22855
|
await hmr.handleFileChange(file, server, sourceDirs, regenerateTypes);
|
|
@@ -22848,7 +22883,8 @@ function createDevMiddleware(server, context) {
|
|
|
22848
22883
|
try {
|
|
22849
22884
|
trustedLocalHost = isTrustedLocalDevelopmentRequest(
|
|
22850
22885
|
new Request(`http://${req.headers.host || "invalid.remote"}${routePath}`),
|
|
22851
|
-
{}
|
|
22886
|
+
{},
|
|
22887
|
+
trustedDevHosts
|
|
22852
22888
|
);
|
|
22853
22889
|
} catch {
|
|
22854
22890
|
}
|
|
@@ -24040,6 +24076,18 @@ ${validUserProviders.map((p) => ` "${p.name}": async () => (await import("${p.i
|
|
|
24040
24076
|
}
|
|
24041
24077
|
}
|
|
24042
24078
|
var DEFAULT_AGENTBUILDER_COMPATIBILITY_DATE = "2025-08-13";
|
|
24079
|
+
var REQUIRED_AGENTBUILDER_COMPATIBILITY_FLAGS = [
|
|
24080
|
+
"nodejs_compat",
|
|
24081
|
+
"enable_ctx_exports"
|
|
24082
|
+
];
|
|
24083
|
+
function compatibilityFlagsWithBuilderRequirements(flags = []) {
|
|
24084
|
+
if (flags.some((flag) => typeof flag !== "string" || flag.trim().length === 0)) {
|
|
24085
|
+
throw new Error(
|
|
24086
|
+
"compatibilityFlags must contain non-empty Cloudflare compatibility flag names"
|
|
24087
|
+
);
|
|
24088
|
+
}
|
|
24089
|
+
return [.../* @__PURE__ */ new Set([...REQUIRED_AGENTBUILDER_COMPATIBILITY_FLAGS, ...flags])];
|
|
24090
|
+
}
|
|
24043
24091
|
var depsToExclude = [
|
|
24044
24092
|
"@standardagents/builder",
|
|
24045
24093
|
"@standardagents/builder/runtime",
|
|
@@ -24070,7 +24118,7 @@ var firstPartyProviderPackages = [
|
|
|
24070
24118
|
"@standardagents/openrouter",
|
|
24071
24119
|
"@standardagents/xai"
|
|
24072
24120
|
];
|
|
24073
|
-
var
|
|
24121
|
+
var baseDepsToInclude = [
|
|
24074
24122
|
"zod",
|
|
24075
24123
|
"zod/v3",
|
|
24076
24124
|
"zod/v4",
|
|
@@ -24081,17 +24129,24 @@ var depsToInclude = [
|
|
|
24081
24129
|
// a root dep). The `parent > child` form pre-bundles it at startup so Vite
|
|
24082
24130
|
// doesn't discover it mid-request and reload the worker (which would destroy
|
|
24083
24131
|
// an in-flight Durable Object execution and drop the client bridge).
|
|
24084
|
-
"@standardagents/openrouter > @openrouter/sdk",
|
|
24085
24132
|
"magic-string",
|
|
24086
24133
|
"@standardagents/spec",
|
|
24087
24134
|
// Incremental JSON reader used by the runtime to surface a tool's progress
|
|
24088
24135
|
// argument from partial streamed tool-call arguments (tool_call_started).
|
|
24089
|
-
"@formkit/jsonreader"
|
|
24090
|
-
// Pre-bundle the provider packages themselves so their whole subtree (SDKs,
|
|
24091
|
-
// pricing tables) lands in the initial optimized bundle and nothing is
|
|
24092
|
-
// discovered lazily by workerd.
|
|
24093
|
-
...firstPartyProviderPackages
|
|
24136
|
+
"@formkit/jsonreader"
|
|
24094
24137
|
];
|
|
24138
|
+
function depsToInclude(options = {}) {
|
|
24139
|
+
const installedProviders = options.isPackageInstalled ? firstPartyProviderPackages.filter(options.isPackageInstalled) : firstPartyProviderPackages;
|
|
24140
|
+
const openRouterTransitive = installedProviders.includes("@standardagents/openrouter") ? ["@standardagents/openrouter > @openrouter/sdk"] : [];
|
|
24141
|
+
return [...baseDepsToInclude, ...openRouterTransitive, ...installedProviders];
|
|
24142
|
+
}
|
|
24143
|
+
function trustedDevHostDefines(options) {
|
|
24144
|
+
return {
|
|
24145
|
+
__STANDARD_AGENTS_TRUSTED_DEV_HOSTS__: JSON.stringify(
|
|
24146
|
+
normalizeTrustedDevHosts(options.trustedDevHosts)
|
|
24147
|
+
)
|
|
24148
|
+
};
|
|
24149
|
+
}
|
|
24095
24150
|
var packingDeps = [
|
|
24096
24151
|
"rollup",
|
|
24097
24152
|
"@rollup/plugin-commonjs",
|
|
@@ -24100,7 +24155,7 @@ var packingDeps = [
|
|
|
24100
24155
|
"fsevents",
|
|
24101
24156
|
"typescript"
|
|
24102
24157
|
];
|
|
24103
|
-
function createPluginViteConfig(pluginModuleUrl) {
|
|
24158
|
+
function createPluginViteConfig(pluginModuleUrl, options = {}) {
|
|
24104
24159
|
const currentDir = path9__default.dirname(fileURLToPath(pluginModuleUrl));
|
|
24105
24160
|
const isInDist = currentDir.endsWith("dist");
|
|
24106
24161
|
const builderClientDir = path9__default.resolve(
|
|
@@ -24108,6 +24163,7 @@ function createPluginViteConfig(pluginModuleUrl) {
|
|
|
24108
24163
|
isInDist ? "./client" : "../dist/client"
|
|
24109
24164
|
);
|
|
24110
24165
|
return {
|
|
24166
|
+
define: trustedDevHostDefines(options),
|
|
24111
24167
|
publicDir: fs9__default.existsSync(builderClientDir) ? builderClientDir : void 0,
|
|
24112
24168
|
build: {
|
|
24113
24169
|
rollupOptions: {
|
|
@@ -24123,7 +24179,7 @@ function createPluginViteConfig(pluginModuleUrl) {
|
|
|
24123
24179
|
// `npm run dev` ("There is a new version of the pre-bundle for X").
|
|
24124
24180
|
holdUntilCrawlEnd: true,
|
|
24125
24181
|
exclude: depsToExclude,
|
|
24126
|
-
include: depsToInclude.filter((dep) => dep !== "zod/v3" && dep !== "zod/v4" && dep !== "zod/v4/core")
|
|
24182
|
+
include: depsToInclude(options).filter((dep) => dep !== "zod/v3" && dep !== "zod/v4" && dep !== "zod/v4/core")
|
|
24127
24183
|
},
|
|
24128
24184
|
ssr: {
|
|
24129
24185
|
noExternal: [
|
|
@@ -24148,7 +24204,7 @@ function createAgentBuilderWorkerConfig(options) {
|
|
|
24148
24204
|
// in vite.config.ts plus their agents/ source tree.
|
|
24149
24205
|
main: options.workerEntry,
|
|
24150
24206
|
compatibility_date: compatibilityDate,
|
|
24151
|
-
compatibility_flags:
|
|
24207
|
+
compatibility_flags: compatibilityFlagsWithBuilderRequirements(options.compatibilityFlags),
|
|
24152
24208
|
observability: {
|
|
24153
24209
|
enabled: true
|
|
24154
24210
|
},
|
|
@@ -24228,7 +24284,11 @@ function createAgentBuilderCloudflarePlugins(options) {
|
|
|
24228
24284
|
}
|
|
24229
24285
|
});
|
|
24230
24286
|
}
|
|
24231
|
-
function applyPluginEnvironmentConfig(config) {
|
|
24287
|
+
function applyPluginEnvironmentConfig(config, options = {}) {
|
|
24288
|
+
config.define = {
|
|
24289
|
+
...config.define || {},
|
|
24290
|
+
...trustedDevHostDefines(options)
|
|
24291
|
+
};
|
|
24232
24292
|
config.optimizeDeps = config.optimizeDeps || {};
|
|
24233
24293
|
config.optimizeDeps.holdUntilCrawlEnd = true;
|
|
24234
24294
|
config.optimizeDeps.exclude = [
|
|
@@ -24237,7 +24297,7 @@ function applyPluginEnvironmentConfig(config) {
|
|
|
24237
24297
|
];
|
|
24238
24298
|
config.optimizeDeps.include = [
|
|
24239
24299
|
...config.optimizeDeps.include || [],
|
|
24240
|
-
...depsToInclude.filter((dep) => !config.optimizeDeps?.include?.includes(dep))
|
|
24300
|
+
...depsToInclude(options).filter((dep) => !config.optimizeDeps?.include?.includes(dep))
|
|
24241
24301
|
];
|
|
24242
24302
|
config.build = config.build || {};
|
|
24243
24303
|
config.build.rollupOptions = config.build.rollupOptions || {};
|
|
@@ -24297,6 +24357,7 @@ function normalizeDeviceApprovalBrand(value) {
|
|
|
24297
24357
|
// src/plugin.ts
|
|
24298
24358
|
function agentbuilder(options = {}) {
|
|
24299
24359
|
const deviceApproval = normalizeDeviceApprovalBrand(options.deviceApproval);
|
|
24360
|
+
const trustedDevHosts = normalizeTrustedDevHosts(options.trustedDevHosts);
|
|
24300
24361
|
const toolsDir = options.toolsDir ? path9__default.resolve(process.cwd(), options.toolsDir) : path9__default.resolve(process.cwd(), "agents/tools");
|
|
24301
24362
|
const hooksDir = options.hooksDir ? path9__default.resolve(process.cwd(), options.hooksDir) : path9__default.resolve(process.cwd(), "agents/hooks");
|
|
24302
24363
|
const threadApiDir = options.apiDir ? path9__default.resolve(process.cwd(), options.apiDir) : path9__default.resolve(process.cwd(), "agents/api");
|
|
@@ -24401,7 +24462,8 @@ export { CodeExecutionBridge, DurableAgentBuilder, DurableThread, ThreadWatchdog
|
|
|
24401
24462
|
installedProviderPackageMap,
|
|
24402
24463
|
hmr,
|
|
24403
24464
|
sourceDirs,
|
|
24404
|
-
regenerateTypes
|
|
24465
|
+
regenerateTypes,
|
|
24466
|
+
trustedDevHosts
|
|
24405
24467
|
};
|
|
24406
24468
|
const workerEntry = path9__default.relative(process.cwd(), generatedWorkerEntry).split(path9__default.sep).join("/");
|
|
24407
24469
|
const corePlugin = {
|
|
@@ -24409,12 +24471,18 @@ export { CodeExecutionBridge, DurableAgentBuilder, DurableThread, ThreadWatchdog
|
|
|
24409
24471
|
enforce: "pre",
|
|
24410
24472
|
config() {
|
|
24411
24473
|
writeGeneratedWorkerEntry();
|
|
24412
|
-
const viteConfig = createPluginViteConfig(import.meta.url
|
|
24474
|
+
const viteConfig = createPluginViteConfig(import.meta.url, {
|
|
24475
|
+
isPackageInstalled: isProviderPackageInstalled,
|
|
24476
|
+
trustedDevHosts
|
|
24477
|
+
});
|
|
24413
24478
|
return viteConfig;
|
|
24414
24479
|
},
|
|
24415
24480
|
// Apply exclusions and inclusions to ALL environments including Cloudflare worker
|
|
24416
24481
|
configEnvironment(_name, config) {
|
|
24417
|
-
applyPluginEnvironmentConfig(config
|
|
24482
|
+
applyPluginEnvironmentConfig(config, {
|
|
24483
|
+
isPackageInstalled: isProviderPackageInstalled,
|
|
24484
|
+
trustedDevHosts
|
|
24485
|
+
});
|
|
24418
24486
|
},
|
|
24419
24487
|
resolveId(id) {
|
|
24420
24488
|
if (id === VIRTUAL_TOOLS_ID) {
|
|
@@ -24459,6 +24527,7 @@ export { CodeExecutionBridge, DurableAgentBuilder, DurableThread, ThreadWatchdog
|
|
|
24459
24527
|
},
|
|
24460
24528
|
buildStart() {
|
|
24461
24529
|
writeGeneratedWorkerEntry();
|
|
24530
|
+
warnLegacyRootAgentFiles(agentsDir);
|
|
24462
24531
|
regenerateTypes();
|
|
24463
24532
|
this.addWatchFile(toolsDir);
|
|
24464
24533
|
this.addWatchFile(threadApiDir);
|
|
@@ -24539,7 +24608,8 @@ export { CodeExecutionBridge, DurableAgentBuilder, DurableThread, ThreadWatchdog
|
|
|
24539
24608
|
corePlugin,
|
|
24540
24609
|
...createAgentBuilderCloudflarePlugins({
|
|
24541
24610
|
workerEntry,
|
|
24542
|
-
compatibilityDate: options.compatibilityDate ?? DEFAULT_AGENTBUILDER_COMPATIBILITY_DATE
|
|
24611
|
+
compatibilityDate: options.compatibilityDate ?? DEFAULT_AGENTBUILDER_COMPATIBILITY_DATE,
|
|
24612
|
+
compatibilityFlags: options.compatibilityFlags
|
|
24543
24613
|
})
|
|
24544
24614
|
];
|
|
24545
24615
|
}
|
|
@@ -29229,12 +29299,9 @@ ${result ?? error ?? "No result content."}${attachmentSummary}`;
|
|
|
29229
29299
|
await parentThread.updateChildRegistryStatus(
|
|
29230
29300
|
params.parent_thread_id,
|
|
29231
29301
|
childThread.id,
|
|
29232
|
-
|
|
29302
|
+
"idle"
|
|
29233
29303
|
);
|
|
29234
29304
|
}
|
|
29235
|
-
if (childResult.terminal && typeof childThreadStub.terminateThread === "function") {
|
|
29236
|
-
await childThreadStub.terminateThread(childThread.id);
|
|
29237
|
-
}
|
|
29238
29305
|
} else if (typeof childThreadStub.terminateThread === "function") {
|
|
29239
29306
|
await childThreadStub.terminateThread(childThread.id);
|
|
29240
29307
|
}
|
|
@@ -33230,11 +33297,13 @@ ${paths.join("\n")}`;
|
|
|
33230
33297
|
try {
|
|
33231
33298
|
const parentId = this.env.AGENT_BUILDER_THREAD.idFromName(parentThreadId);
|
|
33232
33299
|
const parentStub = this.env.AGENT_BUILDER_THREAD.get(parentId);
|
|
33233
|
-
const
|
|
33300
|
+
const childRegistryEntry = await this.getParentRegistryEntryForChild(
|
|
33234
33301
|
parentStub,
|
|
33235
33302
|
parentThreadId,
|
|
33236
33303
|
threadId
|
|
33237
33304
|
);
|
|
33305
|
+
const parentCommunication = childRegistryEntry?.parentCommunication === "explicit" ? "explicit" : "implicit";
|
|
33306
|
+
const resumableChild = childRegistryEntry?.resumable === true;
|
|
33238
33307
|
const copiedRefs = await this.copyAttachmentRefsToThread(
|
|
33239
33308
|
refs,
|
|
33240
33309
|
parentStub,
|
|
@@ -33257,10 +33326,11 @@ ${resultContent}${attachmentSummary}`;
|
|
|
33257
33326
|
});
|
|
33258
33327
|
}
|
|
33259
33328
|
const terminalChildRun = sessionStopped || hasTerminalSessionTools;
|
|
33329
|
+
const terminateChildThread = terminalChildRun && !resumableChild;
|
|
33260
33330
|
await parentStub.updateChildRegistryStatus(
|
|
33261
33331
|
parentThreadId,
|
|
33262
33332
|
threadId,
|
|
33263
|
-
|
|
33333
|
+
terminateChildThread ? "terminated" : "idle"
|
|
33264
33334
|
);
|
|
33265
33335
|
if (parentCommunication !== "explicit") {
|
|
33266
33336
|
await this.persistParentHandoffStatusMessage(
|
|
@@ -33268,23 +33338,22 @@ ${resultContent}${attachmentSummary}`;
|
|
|
33268
33338
|
isErrorTerminal ? "failure" : "result"
|
|
33269
33339
|
);
|
|
33270
33340
|
}
|
|
33271
|
-
if (
|
|
33341
|
+
if (terminateChildThread) {
|
|
33272
33342
|
await this.terminateThread(threadId);
|
|
33273
33343
|
}
|
|
33274
33344
|
} catch (error) {
|
|
33275
33345
|
console.error("[DurableThread] Failed to deliver subagent completion to parent:", error);
|
|
33276
33346
|
}
|
|
33277
33347
|
}
|
|
33278
|
-
async
|
|
33348
|
+
async getParentRegistryEntryForChild(parentStub, parentThreadId, childThreadId) {
|
|
33279
33349
|
if (typeof parentStub.getChildrenRegistry !== "function") {
|
|
33280
|
-
return
|
|
33350
|
+
return void 0;
|
|
33281
33351
|
}
|
|
33282
33352
|
try {
|
|
33283
33353
|
const entries = await parentStub.getChildrenRegistry(parentThreadId);
|
|
33284
|
-
|
|
33285
|
-
return childEntry?.parentCommunication === "explicit" ? "explicit" : "implicit";
|
|
33354
|
+
return entries.find((entry) => entry.reference === childThreadId);
|
|
33286
33355
|
} catch {
|
|
33287
|
-
return
|
|
33356
|
+
return void 0;
|
|
33288
33357
|
}
|
|
33289
33358
|
}
|
|
33290
33359
|
/**
|
|
@@ -34832,7 +34901,7 @@ ${resultContent}${attachmentSummary}`;
|
|
|
34832
34901
|
void 0,
|
|
34833
34902
|
INTERNAL_TOOL_DELIVERY
|
|
34834
34903
|
);
|
|
34835
|
-
if (delivered
|
|
34904
|
+
if (delivered) sides.add(delivered.side);
|
|
34836
34905
|
}
|
|
34837
34906
|
if (threadId) {
|
|
34838
34907
|
for (const side of sides) {
|
|
@@ -35134,17 +35203,14 @@ ${resultContent}${attachmentSummary}`;
|
|
|
35134
35203
|
deliveredResultWaiters = /* @__PURE__ */ new Map();
|
|
35135
35204
|
notifyDeliveredResultWaiters(toolCallId) {
|
|
35136
35205
|
const waiters = this.deliveredResultWaiters?.get(toolCallId);
|
|
35137
|
-
if (!waiters
|
|
35206
|
+
if (!waiters) return;
|
|
35138
35207
|
this.deliveredResultWaiters.delete(toolCallId);
|
|
35139
|
-
let notified = false;
|
|
35140
35208
|
for (const wake of waiters) {
|
|
35141
35209
|
try {
|
|
35142
35210
|
wake();
|
|
35143
|
-
notified = true;
|
|
35144
35211
|
} catch {
|
|
35145
35212
|
}
|
|
35146
35213
|
}
|
|
35147
|
-
return notified;
|
|
35148
35214
|
}
|
|
35149
35215
|
/**
|
|
35150
35216
|
* Await a parked forwarded call's delivered result: one immediate read,
|
|
@@ -35289,46 +35355,37 @@ ${resultContent}${attachmentSummary}`;
|
|
|
35289
35355
|
const side = pending.side === "b" ? "b" : "a";
|
|
35290
35356
|
const content = ok ? result ?? "" : `Error: ${error ?? "tool failed"}`;
|
|
35291
35357
|
const toolStatus = ok ? "success" : "error";
|
|
35292
|
-
|
|
35293
|
-
|
|
35294
|
-
|
|
35295
|
-
|
|
35296
|
-
|
|
35297
|
-
|
|
35298
|
-
|
|
35358
|
+
await this.ctx.storage.sql.exec(
|
|
35359
|
+
`UPDATE messages SET content = ?, tool_status = ? WHERE tool_call_id = ? AND role = 'tool'`,
|
|
35360
|
+
content,
|
|
35361
|
+
toolStatus,
|
|
35362
|
+
toolCallId
|
|
35363
|
+
);
|
|
35364
|
+
const updated = await this.ctx.storage.sql.exec(
|
|
35365
|
+
`SELECT COUNT(*) AS total FROM messages WHERE tool_call_id = ? AND role = 'tool'`,
|
|
35366
|
+
toolCallId
|
|
35367
|
+
);
|
|
35368
|
+
if (Number(updated.toArray()[0]?.total ?? 0) === 0) {
|
|
35369
|
+
const toolRow = await this.ctx.storage.sql.exec(
|
|
35370
|
+
`SELECT tool FROM pending_client_calls WHERE tool_call_id = ? LIMIT 1`,
|
|
35299
35371
|
toolCallId
|
|
35300
35372
|
);
|
|
35301
|
-
|
|
35302
|
-
|
|
35303
|
-
|
|
35373
|
+
await this.ctx.storage.sql.exec(
|
|
35374
|
+
`INSERT INTO messages (id, role, content, name, tool_call_id, tool_status, created_at, status, prompt)
|
|
35375
|
+
VALUES (?, 'tool', ?, ?, ?, ?, ?, 'completed', NULL)`,
|
|
35376
|
+
crypto.randomUUID(),
|
|
35304
35377
|
content,
|
|
35378
|
+
toolRow.toArray()[0]?.tool ?? null,
|
|
35379
|
+
toolCallId,
|
|
35305
35380
|
toolStatus,
|
|
35306
|
-
|
|
35381
|
+
Date.now() * TIMESTAMP_MULTIPLIER
|
|
35307
35382
|
);
|
|
35308
|
-
|
|
35309
|
-
|
|
35310
|
-
|
|
35311
|
-
|
|
35312
|
-
|
|
35313
|
-
|
|
35314
|
-
`SELECT tool FROM pending_client_calls WHERE tool_call_id = ? LIMIT 1`,
|
|
35315
|
-
toolCallId
|
|
35316
|
-
);
|
|
35317
|
-
this.ctx.storage.sql.exec(
|
|
35318
|
-
`INSERT INTO messages (id, role, content, name, tool_call_id, tool_status, created_at, status, prompt)
|
|
35319
|
-
VALUES (?, 'tool', ?, ?, ?, ?, ?, 'completed', NULL)`,
|
|
35320
|
-
resultMessageId,
|
|
35321
|
-
content,
|
|
35322
|
-
toolRow.toArray()[0]?.tool ?? null,
|
|
35323
|
-
toolCallId,
|
|
35324
|
-
toolStatus,
|
|
35325
|
-
resultCreatedAt
|
|
35326
|
-
);
|
|
35327
|
-
}
|
|
35328
|
-
return true;
|
|
35329
|
-
});
|
|
35330
|
-
if (!accepted) return null;
|
|
35331
|
-
const resumedInline = this.notifyDeliveredResultWaiters(toolCallId);
|
|
35383
|
+
}
|
|
35384
|
+
await this.ctx.storage.sql.exec(
|
|
35385
|
+
`UPDATE pending_client_calls SET status = 'resolved' WHERE tool_call_id = ?`,
|
|
35386
|
+
toolCallId
|
|
35387
|
+
);
|
|
35388
|
+
this.notifyDeliveredResultWaiters(toolCallId);
|
|
35332
35389
|
try {
|
|
35333
35390
|
const msgCursor = await this.ctx.storage.sql.exec(
|
|
35334
35391
|
`SELECT id, role, content, name, tool_call_id, tool_status, created_at, depth
|
|
@@ -35339,7 +35396,7 @@ ${resultContent}${attachmentSummary}`;
|
|
|
35339
35396
|
if (msg) this.broadcastMessage(msg);
|
|
35340
35397
|
} catch {
|
|
35341
35398
|
}
|
|
35342
|
-
return { side
|
|
35399
|
+
return { side };
|
|
35343
35400
|
}
|
|
35344
35401
|
// ─── Runtime byte streams ──────────────────────────────────────────────────
|
|
35345
35402
|
// The existing bridge frames carry opaque capability metadata and bytes
|
|
@@ -36513,11 +36570,12 @@ ${resultContent}${attachmentSummary}`;
|
|
|
36513
36570
|
if (!parentThreadId) return;
|
|
36514
36571
|
const parentId = this.env.AGENT_BUILDER_THREAD.idFromName(parentThreadId);
|
|
36515
36572
|
const parentStub = this.env.AGENT_BUILDER_THREAD.get(parentId);
|
|
36516
|
-
const
|
|
36573
|
+
const childRegistryEntry = await this.getParentRegistryEntryForChild(
|
|
36517
36574
|
parentStub,
|
|
36518
36575
|
parentThreadId,
|
|
36519
36576
|
threadId
|
|
36520
36577
|
);
|
|
36578
|
+
const parentCommunication = childRegistryEntry?.parentCommunication === "explicit" ? "explicit" : "implicit";
|
|
36521
36579
|
if (parentCommunication !== "explicit") {
|
|
36522
36580
|
await parentStub.queueMessage(parentThreadId, {
|
|
36523
36581
|
role: "user",
|