@standardagents/builder 0.17.0 → 0.17.2
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 +331 -46
- package/dist/built-in-routes.js.map +1 -1
- package/dist/client/ThreadInspectorPane.vue_vue_type_script_setup_true_lang.js +15 -19
- package/dist/client/assets/ThreadInspectorPane.css +1 -1
- package/dist/client/assets/img/favicon.svg +10 -2
- package/dist/{index-BnrKzXpJ.d.ts → index-Dx1js-H1.d.ts} +22 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +245 -42
- package/dist/index.js.map +1 -1
- package/dist/plugin.js +42 -0
- package/dist/plugin.js.map +1 -1
- package/dist/runtime.d.ts +2 -2
- package/dist/runtime.js +203 -42
- package/dist/runtime.js.map +1 -1
- package/dist/test.d.ts +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -917,7 +917,7 @@ function resolvePlatformRouting(providerName, env) {
|
|
|
917
917
|
var DEFAULT_PLATFORM_PROXY_ORIGIN, PROVIDER_BASE_PATHS;
|
|
918
918
|
var init_platform_routing = __esm({
|
|
919
919
|
"src/agents/providers/platform-routing.ts"() {
|
|
920
|
-
DEFAULT_PLATFORM_PROXY_ORIGIN = "https://
|
|
920
|
+
DEFAULT_PLATFORM_PROXY_ORIGIN = "https://api.standardagents.ai";
|
|
921
921
|
PROVIDER_BASE_PATHS = {
|
|
922
922
|
cloudflare: "/ai/v1"
|
|
923
923
|
};
|
|
@@ -1454,6 +1454,23 @@ function convertUsage(usage) {
|
|
|
1454
1454
|
provider: usage.provider
|
|
1455
1455
|
};
|
|
1456
1456
|
}
|
|
1457
|
+
function inferProviderFromModelId(model) {
|
|
1458
|
+
const trimmed = model?.trim();
|
|
1459
|
+
if (!trimmed) return null;
|
|
1460
|
+
const slashIndex = trimmed.indexOf("/");
|
|
1461
|
+
if (slashIndex <= 0) return null;
|
|
1462
|
+
return trimmed.slice(0, slashIndex);
|
|
1463
|
+
}
|
|
1464
|
+
function inferInitialActualProvider(providerName, modelDef) {
|
|
1465
|
+
if (providerName !== "openrouter") return null;
|
|
1466
|
+
return inferProviderFromModelId(modelDef.model);
|
|
1467
|
+
}
|
|
1468
|
+
function normalizeProviderMetadataValue(value) {
|
|
1469
|
+
if (typeof value !== "string") return void 0;
|
|
1470
|
+
const trimmed = value.trim();
|
|
1471
|
+
if (!trimmed || trimmed.toLowerCase() === "unknown") return void 0;
|
|
1472
|
+
return trimmed;
|
|
1473
|
+
}
|
|
1457
1474
|
var NON_VISION_PLACEHOLDER_TEXT, LLMRequest;
|
|
1458
1475
|
var init_LLMRequest = __esm({
|
|
1459
1476
|
"src/agents/LLMRequest.ts"() {
|
|
@@ -1622,6 +1639,7 @@ var init_LLMRequest = __esm({
|
|
|
1622
1639
|
console.error("Failed to get provider name:", err);
|
|
1623
1640
|
}
|
|
1624
1641
|
const { requestBody, visionFiltering } = buildRequestBody(context, modelDef);
|
|
1642
|
+
const initialActualProvider = inferInitialActualProvider(providerName, modelDef);
|
|
1625
1643
|
const requestBodyForLog = {
|
|
1626
1644
|
...requestBody,
|
|
1627
1645
|
messages: stripBase64FromMessages(
|
|
@@ -1640,6 +1658,7 @@ var init_LLMRequest = __esm({
|
|
|
1640
1658
|
id,
|
|
1641
1659
|
message_id: state.rootMessageId || crypto.randomUUID(),
|
|
1642
1660
|
provider: providerName || this.getProviderFromModel(modelId),
|
|
1661
|
+
actual_provider: initialActualProvider ?? void 0,
|
|
1643
1662
|
model: modelId,
|
|
1644
1663
|
model_name: modelDef.model,
|
|
1645
1664
|
endpoint: "chat.completions",
|
|
@@ -1660,14 +1679,15 @@ var init_LLMRequest = __esm({
|
|
|
1660
1679
|
await state.storage.sql.exec(
|
|
1661
1680
|
`
|
|
1662
1681
|
INSERT INTO logs (
|
|
1663
|
-
id, message_id, provider, model, model_name, endpoint,
|
|
1682
|
+
id, message_id, provider, actual_provider, model, model_name, endpoint,
|
|
1664
1683
|
request_body, tools_available, message_history_length, prompt_name,
|
|
1665
1684
|
parent_log_id, retry_of_log_id, tools_schema, system_prompt, is_complete, created_at
|
|
1666
|
-
) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16)
|
|
1685
|
+
) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17)
|
|
1667
1686
|
`,
|
|
1668
1687
|
logData.id,
|
|
1669
1688
|
logData.message_id,
|
|
1670
1689
|
logData.provider,
|
|
1690
|
+
logData.actual_provider,
|
|
1671
1691
|
logData.model,
|
|
1672
1692
|
logData.model_name,
|
|
1673
1693
|
logData.endpoint,
|
|
@@ -1919,7 +1939,7 @@ var init_LLMRequest = __esm({
|
|
|
1919
1939
|
const calculatedCost = calculateUsageCost(response.usage, resolvedPricing);
|
|
1920
1940
|
const providerReportedCost = typeof response.usage.cost === "number" ? response.usage.cost : typeof response.usage.cost === "string" ? parseFloat(response.usage.cost) : null;
|
|
1921
1941
|
const cost_total = providerReportedCost != null && !Number.isNaN(providerReportedCost) ? providerReportedCost : calculatedCost?.costTotal ?? null;
|
|
1922
|
-
const actualProvider = response.usage.provider;
|
|
1942
|
+
const actualProvider = normalizeProviderMetadataValue(response.usage.provider) ?? null;
|
|
1923
1943
|
const aggregateResponse = response._aggregate_response;
|
|
1924
1944
|
const responseBody = aggregateResponse ? JSON.stringify(aggregateResponse) : JSON.stringify(response);
|
|
1925
1945
|
const providerTools = [];
|
|
@@ -2347,8 +2367,13 @@ ${errorStack}` : ""}${errorDetails}`;
|
|
|
2347
2367
|
}).catch((err) => {
|
|
2348
2368
|
console.error("Async metadata fetch failed (non-fatal):", err);
|
|
2349
2369
|
});
|
|
2350
|
-
|
|
2351
|
-
|
|
2370
|
+
const rootState = state.rootState || state;
|
|
2371
|
+
rootState.pendingMetadataPromises = rootState.pendingMetadataPromises || [];
|
|
2372
|
+
rootState.pendingMetadataPromises.push(metadataPromise);
|
|
2373
|
+
if (rootState !== state) {
|
|
2374
|
+
state.pendingMetadataPromises = state.pendingMetadataPromises || [];
|
|
2375
|
+
state.pendingMetadataPromises.push(metadataPromise);
|
|
2376
|
+
}
|
|
2352
2377
|
}
|
|
2353
2378
|
/**
|
|
2354
2379
|
* Update log record with async metadata from provider.
|
|
@@ -2358,9 +2383,12 @@ ${errorStack}` : ""}${errorDetails}`;
|
|
|
2358
2383
|
const updates = [];
|
|
2359
2384
|
const values = [];
|
|
2360
2385
|
let paramIndex = 1;
|
|
2361
|
-
|
|
2386
|
+
const actualProvider = normalizeProviderMetadataValue(
|
|
2387
|
+
metadata.actual_provider ?? metadata.actualProvider ?? metadata.providerName
|
|
2388
|
+
);
|
|
2389
|
+
if (actualProvider !== void 0) {
|
|
2362
2390
|
updates.push(`actual_provider = ?${paramIndex++}`);
|
|
2363
|
-
values.push(
|
|
2391
|
+
values.push(actualProvider);
|
|
2364
2392
|
}
|
|
2365
2393
|
if (metadata.generation_cost !== void 0) {
|
|
2366
2394
|
updates.push(`cost_total = ?${paramIndex++}`);
|
|
@@ -2378,7 +2406,7 @@ ${errorStack}` : ""}${errorDetails}`;
|
|
|
2378
2406
|
log_id: logId,
|
|
2379
2407
|
data: {
|
|
2380
2408
|
id: logId,
|
|
2381
|
-
...
|
|
2409
|
+
...actualProvider !== void 0 && { actual_provider: actualProvider },
|
|
2382
2410
|
...metadata.generation_cost !== void 0 && { cost_total: metadata.generation_cost }
|
|
2383
2411
|
}
|
|
2384
2412
|
});
|
|
@@ -3104,6 +3132,11 @@ var init_ToolExecutor = __esm({
|
|
|
3104
3132
|
state.sequence.queue.push(...toolCalls);
|
|
3105
3133
|
state.sequence.isHandling = true;
|
|
3106
3134
|
while (state.sequence.queue.length > 0) {
|
|
3135
|
+
if (state.stopped) {
|
|
3136
|
+
state.sequence.queue = [];
|
|
3137
|
+
state.sequence.isHandling = false;
|
|
3138
|
+
break;
|
|
3139
|
+
}
|
|
3107
3140
|
if (await state.thread.instance.shouldStop() || state.abortController?.signal.aborted) {
|
|
3108
3141
|
state.sequence.queue = [];
|
|
3109
3142
|
state.sequence.isHandling = false;
|
|
@@ -3132,7 +3165,17 @@ var init_ToolExecutor = __esm({
|
|
|
3132
3165
|
});
|
|
3133
3166
|
continue;
|
|
3134
3167
|
}
|
|
3135
|
-
const
|
|
3168
|
+
const previousToolCall = state.currentToolCall;
|
|
3169
|
+
state.currentToolCall = {
|
|
3170
|
+
id: call.id,
|
|
3171
|
+
name: call.function.name
|
|
3172
|
+
};
|
|
3173
|
+
let result;
|
|
3174
|
+
try {
|
|
3175
|
+
result = await this.executeToolCall(call, state, toolMessageId);
|
|
3176
|
+
} finally {
|
|
3177
|
+
state.currentToolCall = previousToolCall;
|
|
3178
|
+
}
|
|
3136
3179
|
if (result.status === "error") {
|
|
3137
3180
|
const error = new Error(result.error || "Tool execution failed");
|
|
3138
3181
|
if (result.stack) {
|
|
@@ -5001,6 +5044,11 @@ ${attachmentPaths}`;
|
|
|
5001
5044
|
}
|
|
5002
5045
|
}
|
|
5003
5046
|
const toolStatus = processedResult.status === "success" ? "success" : "error";
|
|
5047
|
+
const parentNotifications = this.consumeParentNotificationsForToolCall(
|
|
5048
|
+
state,
|
|
5049
|
+
call
|
|
5050
|
+
);
|
|
5051
|
+
const notificationContent = parentNotifications[parentNotifications.length - 1]?.content;
|
|
5004
5052
|
let message = {
|
|
5005
5053
|
id: messageId,
|
|
5006
5054
|
role: "tool",
|
|
@@ -5014,15 +5062,20 @@ ${attachmentPaths}`;
|
|
|
5014
5062
|
parent_id: state.parentMessageId || null,
|
|
5015
5063
|
depth: state.depth,
|
|
5016
5064
|
attachments: attachmentRefs && attachmentRefs.length > 0 ? JSON.stringify(attachmentRefs) : null,
|
|
5017
|
-
subagent_id: typeof processedResult.subagent_id === "string" && processedResult.subagent_id.trim().length > 0 ? processedResult.subagent_id.trim() : null
|
|
5065
|
+
subagent_id: typeof processedResult.subagent_id === "string" && processedResult.subagent_id.trim().length > 0 ? processedResult.subagent_id.trim() : null,
|
|
5066
|
+
metadata: parentNotifications.length > 0 ? {
|
|
5067
|
+
parent_notification: true,
|
|
5068
|
+
parent_notifications: parentNotifications,
|
|
5069
|
+
parent_notification_content: notificationContent
|
|
5070
|
+
} : void 0
|
|
5018
5071
|
};
|
|
5019
5072
|
message = await FlowEngine2.runBeforeCreateMessageHook(state, message);
|
|
5020
5073
|
message.created_at = Date.now() * TIMESTAMP_MULTIPLIER;
|
|
5021
5074
|
const currentPrompt = state.promptPath.length > 0 ? state.promptPath[state.promptPath.length - 1] : null;
|
|
5022
5075
|
await state.storage.sql.exec(
|
|
5023
5076
|
`
|
|
5024
|
-
INSERT INTO messages (id, role, content, name, tool_call_id, created_at, tool_status, parent_id, depth, attachments, subagent_id, prompt)
|
|
5025
|
-
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12)
|
|
5077
|
+
INSERT INTO messages (id, role, content, name, tool_call_id, created_at, tool_status, parent_id, depth, attachments, subagent_id, prompt, metadata)
|
|
5078
|
+
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13)
|
|
5026
5079
|
`,
|
|
5027
5080
|
message.id,
|
|
5028
5081
|
message.role,
|
|
@@ -5035,7 +5088,8 @@ ${attachmentPaths}`;
|
|
|
5035
5088
|
message.depth,
|
|
5036
5089
|
message.attachments,
|
|
5037
5090
|
message.subagent_id ?? null,
|
|
5038
|
-
currentPrompt
|
|
5091
|
+
currentPrompt,
|
|
5092
|
+
message.metadata ? JSON.stringify(message.metadata) : null
|
|
5039
5093
|
);
|
|
5040
5094
|
await FlowEngine2.runAfterCreateMessageHook(state, message);
|
|
5041
5095
|
const parentLogId = state.currentLogId || null;
|
|
@@ -5100,6 +5154,23 @@ ${attachmentPaths}`;
|
|
|
5100
5154
|
await this.logError(state, error, `storeToolResult:${call.function.name}`);
|
|
5101
5155
|
}
|
|
5102
5156
|
}
|
|
5157
|
+
static consumeParentNotificationsForToolCall(state, call) {
|
|
5158
|
+
const pending = state.parentNotifications ?? [];
|
|
5159
|
+
if (pending.length === 0) return [];
|
|
5160
|
+
const matched = [];
|
|
5161
|
+
const remaining = [];
|
|
5162
|
+
for (const notification of pending) {
|
|
5163
|
+
const matchesCallId = notification.toolCallId === call.id;
|
|
5164
|
+
const matchesToolName = !notification.toolCallId && notification.toolName === call.function.name;
|
|
5165
|
+
if (matchesCallId || matchesToolName) {
|
|
5166
|
+
matched.push(notification);
|
|
5167
|
+
} else {
|
|
5168
|
+
remaining.push(notification);
|
|
5169
|
+
}
|
|
5170
|
+
}
|
|
5171
|
+
state.parentNotifications = remaining;
|
|
5172
|
+
return matched;
|
|
5173
|
+
}
|
|
5103
5174
|
static async createSilentGeneratedAssetPathMessagesFromToolResult(state, sourceToolMessage, refs, enabled) {
|
|
5104
5175
|
if (!enabled || !refs || refs.length === 0) {
|
|
5105
5176
|
return;
|
|
@@ -5561,6 +5632,8 @@ var init_FlowEngine = __esm({
|
|
|
5561
5632
|
stoppedBy: state.stoppedBy,
|
|
5562
5633
|
stopReason: state.stopReason,
|
|
5563
5634
|
stopReasonCode: state.stopReasonCode,
|
|
5635
|
+
sessionStopped: state.sessionStopped,
|
|
5636
|
+
sessionStopResult: state.sessionStopResult,
|
|
5564
5637
|
stepCount: state.stepCount,
|
|
5565
5638
|
stream: state.stream.httpStream
|
|
5566
5639
|
};
|
|
@@ -5760,6 +5833,8 @@ var init_FlowEngine = __esm({
|
|
|
5760
5833
|
stoppedBy: stateInput.stoppedBy,
|
|
5761
5834
|
stopReason: stateInput.stopReason,
|
|
5762
5835
|
stopReasonCode: stateInput.stopReasonCode,
|
|
5836
|
+
sessionStopped: stateInput.sessionStopped,
|
|
5837
|
+
sessionStopResult: stateInput.sessionStopResult,
|
|
5763
5838
|
messageHistory: [],
|
|
5764
5839
|
sequence: stateInput.sequence || {
|
|
5765
5840
|
queue: [],
|
|
@@ -11729,34 +11804,79 @@ var init_ThreadStateImpl = __esm({
|
|
|
11729
11804
|
this._metadata.tenvs = nextEnv;
|
|
11730
11805
|
}
|
|
11731
11806
|
async notifyParent(content) {
|
|
11732
|
-
|
|
11807
|
+
const trimmedContent = content?.trim();
|
|
11808
|
+
if (!trimmedContent) {
|
|
11733
11809
|
throw new Error("notifyParent requires non-empty content");
|
|
11734
11810
|
}
|
|
11735
|
-
|
|
11736
|
-
|
|
11737
|
-
|
|
11811
|
+
if (this._flowState) {
|
|
11812
|
+
const currentToolCall = this._flowState.currentToolCall;
|
|
11813
|
+
const notification = {
|
|
11814
|
+
content: trimmedContent,
|
|
11815
|
+
toolCallId: currentToolCall?.id ?? null,
|
|
11816
|
+
toolName: currentToolCall?.name ?? this._flowState.active?.tool ?? null,
|
|
11817
|
+
created_at: Date.now() * 1e3
|
|
11818
|
+
};
|
|
11819
|
+
this._flowState.parentNotifications = [
|
|
11820
|
+
...this._flowState.parentNotifications ?? [],
|
|
11821
|
+
notification
|
|
11822
|
+
];
|
|
11823
|
+
}
|
|
11824
|
+
const parentTarget = await this._getOptionalParentThreadStub();
|
|
11825
|
+
if (parentTarget && typeof parentTarget.parentStub.queueMessage === "function") {
|
|
11826
|
+
await parentTarget.parentStub.queueMessage(parentTarget.parentThreadId, {
|
|
11827
|
+
role: "user",
|
|
11828
|
+
content: trimmedContent,
|
|
11829
|
+
silent: true,
|
|
11830
|
+
metadata: { subagent_id: this.threadId }
|
|
11831
|
+
});
|
|
11738
11832
|
}
|
|
11739
|
-
await parentStub.queueMessage(parentThreadId, {
|
|
11740
|
-
role: "user",
|
|
11741
|
-
content: content.trim(),
|
|
11742
|
-
silent: true,
|
|
11743
|
-
metadata: { subagent_id: this.threadId }
|
|
11744
|
-
});
|
|
11745
11833
|
}
|
|
11746
11834
|
async setStatus(status) {
|
|
11747
11835
|
if (!status || !status.trim()) {
|
|
11748
11836
|
throw new Error("setStatus requires non-empty status");
|
|
11749
11837
|
}
|
|
11750
|
-
const
|
|
11751
|
-
if (typeof parentStub.updateChildRegistryStatus !== "function") {
|
|
11752
|
-
|
|
11838
|
+
const parentTarget = await this._getOptionalParentThreadStub();
|
|
11839
|
+
if (!parentTarget || typeof parentTarget.parentStub.updateChildRegistryStatus !== "function") {
|
|
11840
|
+
return;
|
|
11753
11841
|
}
|
|
11754
|
-
await parentStub.updateChildRegistryStatus(
|
|
11755
|
-
parentThreadId,
|
|
11842
|
+
await parentTarget.parentStub.updateChildRegistryStatus(
|
|
11843
|
+
parentTarget.parentThreadId,
|
|
11756
11844
|
this.threadId,
|
|
11757
11845
|
status.trim()
|
|
11758
11846
|
);
|
|
11759
11847
|
}
|
|
11848
|
+
async stopSession(options = {}) {
|
|
11849
|
+
if (!this._flowState) {
|
|
11850
|
+
throw new Error("stopSession requires active execution");
|
|
11851
|
+
}
|
|
11852
|
+
const notifyParent = options.notifyParent?.trim();
|
|
11853
|
+
if (options.notifyParent !== void 0 && !notifyParent) {
|
|
11854
|
+
throw new Error("stopSession notifyParent requires non-empty content");
|
|
11855
|
+
}
|
|
11856
|
+
const status = options.status?.trim();
|
|
11857
|
+
if (options.status !== void 0 && !status) {
|
|
11858
|
+
throw new Error("stopSession status requires non-empty status");
|
|
11859
|
+
}
|
|
11860
|
+
if (notifyParent) {
|
|
11861
|
+
await this.notifyParent(notifyParent);
|
|
11862
|
+
}
|
|
11863
|
+
if (status) {
|
|
11864
|
+
await this.setStatus(status);
|
|
11865
|
+
}
|
|
11866
|
+
const result = options.result?.trim() || "Session stopped.";
|
|
11867
|
+
this._flowState.sessionStopped = true;
|
|
11868
|
+
this._flowState.sessionStopResult = result;
|
|
11869
|
+
this._flowState.stopped = true;
|
|
11870
|
+
this._flowState.stoppedBy = this._flowState.currentSide;
|
|
11871
|
+
this._flowState.stopReason = "Session stopped by state.stopSession()";
|
|
11872
|
+
this._flowState.stopReasonCode = "state_stop_session";
|
|
11873
|
+
this._flowState.emitTelemetry?.({
|
|
11874
|
+
type: "stopped",
|
|
11875
|
+
reason: this._flowState.stopReason,
|
|
11876
|
+
side: this._flowState.currentSide,
|
|
11877
|
+
timestamp: Date.now()
|
|
11878
|
+
});
|
|
11879
|
+
}
|
|
11760
11880
|
async getChildThread(referenceId) {
|
|
11761
11881
|
const agentBuilder = this._getAgentBuilderStub();
|
|
11762
11882
|
const child = await agentBuilder.getThread(referenceId);
|
|
@@ -12169,19 +12289,47 @@ var init_ThreadStateImpl = __esm({
|
|
|
12169
12289
|
return Object.keys(normalized).length > 0 ? normalized : null;
|
|
12170
12290
|
}
|
|
12171
12291
|
async _getParentThreadId() {
|
|
12292
|
+
const parent = await this._getOptionalParentThreadId();
|
|
12293
|
+
if (!parent) {
|
|
12294
|
+
throw new Error(`Thread ${this.threadId} has no parent thread`);
|
|
12295
|
+
}
|
|
12296
|
+
return parent;
|
|
12297
|
+
}
|
|
12298
|
+
async _getOptionalParentThreadId() {
|
|
12172
12299
|
const metadataParent = typeof this._metadata.parent === "string" && this._metadata.parent.trim().length > 0 ? this._metadata.parent.trim() : null;
|
|
12173
12300
|
if (metadataParent) {
|
|
12174
12301
|
return metadataParent;
|
|
12175
12302
|
}
|
|
12176
|
-
|
|
12177
|
-
|
|
12303
|
+
let thread = null;
|
|
12304
|
+
try {
|
|
12305
|
+
const agentBuilder = this._getAgentBuilderStub();
|
|
12306
|
+
thread = await agentBuilder.getThread(this.threadId);
|
|
12307
|
+
} catch {
|
|
12308
|
+
return null;
|
|
12309
|
+
}
|
|
12178
12310
|
const parent = thread && typeof thread.parent === "string" && thread.parent.trim().length > 0 ? thread.parent.trim() : null;
|
|
12179
|
-
if (
|
|
12180
|
-
|
|
12311
|
+
if (parent) {
|
|
12312
|
+
this._metadata.parent = parent;
|
|
12181
12313
|
}
|
|
12182
|
-
this._metadata.parent = parent;
|
|
12183
12314
|
return parent;
|
|
12184
12315
|
}
|
|
12316
|
+
async _getOptionalParentThreadStub() {
|
|
12317
|
+
const parentThreadId = await this._getOptionalParentThreadId();
|
|
12318
|
+
if (!parentThreadId) {
|
|
12319
|
+
return null;
|
|
12320
|
+
}
|
|
12321
|
+
try {
|
|
12322
|
+
const threadNamespace = this._threadInstance.env.AGENT_BUILDER_THREAD;
|
|
12323
|
+
if (!threadNamespace || typeof threadNamespace.idFromName !== "function" || typeof threadNamespace.get !== "function") {
|
|
12324
|
+
return null;
|
|
12325
|
+
}
|
|
12326
|
+
const durableId = threadNamespace.idFromName(parentThreadId);
|
|
12327
|
+
const parentStub = threadNamespace.get(durableId);
|
|
12328
|
+
return { parentThreadId, parentStub };
|
|
12329
|
+
} catch {
|
|
12330
|
+
return null;
|
|
12331
|
+
}
|
|
12332
|
+
}
|
|
12185
12333
|
async _getParentThreadStub() {
|
|
12186
12334
|
const parentThreadId = await this._getParentThreadId();
|
|
12187
12335
|
const durableId = this._threadInstance.env.AGENT_BUILDER_THREAD.idFromName(parentThreadId);
|
|
@@ -18882,6 +19030,18 @@ function readRawRequestBody(req) {
|
|
|
18882
19030
|
req.on("error", reject);
|
|
18883
19031
|
});
|
|
18884
19032
|
}
|
|
19033
|
+
function resolveContainedFile(baseDir, requestPath) {
|
|
19034
|
+
const resolvedBase = path8__default.resolve(baseDir);
|
|
19035
|
+
const resolved = path8__default.resolve(resolvedBase, `.${path8__default.sep}${requestPath.replace(/^\/+/, "")}`);
|
|
19036
|
+
if (resolved !== resolvedBase && !resolved.startsWith(resolvedBase + path8__default.sep)) {
|
|
19037
|
+
return null;
|
|
19038
|
+
}
|
|
19039
|
+
try {
|
|
19040
|
+
return fs8__default.existsSync(resolved) && fs8__default.statSync(resolved).isFile() ? resolved : null;
|
|
19041
|
+
} catch {
|
|
19042
|
+
return null;
|
|
19043
|
+
}
|
|
19044
|
+
}
|
|
18885
19045
|
function injectUiConfigIntoHtml(htmlContent) {
|
|
18886
19046
|
const configScript = `<script>window.__AGENTBUILDER_CONFIG__ = { devMode: true };</script>`;
|
|
18887
19047
|
return htmlContent.replace(/\/agents\//g, "/").replace("</head>", `${configScript}</head>`);
|
|
@@ -19024,6 +19184,15 @@ function createDevMiddleware(server, context) {
|
|
|
19024
19184
|
if (isStaticAsset) {
|
|
19025
19185
|
const cleanUrl = clientPath.split("?")[0];
|
|
19026
19186
|
filePath = path8__default.join(clientDir, cleanUrl);
|
|
19187
|
+
if (!fs8__default.existsSync(filePath)) {
|
|
19188
|
+
const projectPublicFile = resolveContainedFile(
|
|
19189
|
+
path8__default.resolve(server.config.root, "public"),
|
|
19190
|
+
cleanUrl
|
|
19191
|
+
);
|
|
19192
|
+
if (projectPublicFile) {
|
|
19193
|
+
filePath = projectPublicFile;
|
|
19194
|
+
}
|
|
19195
|
+
}
|
|
19027
19196
|
} else {
|
|
19028
19197
|
filePath = path8__default.join(clientDir, "index.html");
|
|
19029
19198
|
}
|
|
@@ -20320,6 +20489,27 @@ export { CodeExecutionBridge, DurableAgentBuilder, DurableThread };
|
|
|
20320
20489
|
}
|
|
20321
20490
|
}
|
|
20322
20491
|
copyRecursive(clientDir, mountDir);
|
|
20492
|
+
const projectPublicDir = path8__default.resolve(process.cwd(), "public");
|
|
20493
|
+
if (fs8__default.existsSync(projectPublicDir)) {
|
|
20494
|
+
let copyPublicRecursive2 = function(src, dest) {
|
|
20495
|
+
const entries = fs8__default.readdirSync(src, { withFileTypes: true });
|
|
20496
|
+
for (const entry of entries) {
|
|
20497
|
+
const srcPath = path8__default.join(src, entry.name);
|
|
20498
|
+
const destPath = path8__default.join(dest, entry.name);
|
|
20499
|
+
if (entry.isDirectory()) {
|
|
20500
|
+
fs8__default.mkdirSync(destPath, { recursive: true });
|
|
20501
|
+
copyPublicRecursive2(srcPath, destPath);
|
|
20502
|
+
} else if (fs8__default.existsSync(destPath)) {
|
|
20503
|
+
console.warn(
|
|
20504
|
+
`[agentbuilder] Skipping public/ file that collides with a built UI asset: ${destPath}`
|
|
20505
|
+
);
|
|
20506
|
+
} else {
|
|
20507
|
+
fs8__default.copyFileSync(srcPath, destPath);
|
|
20508
|
+
}
|
|
20509
|
+
}
|
|
20510
|
+
};
|
|
20511
|
+
copyPublicRecursive2(projectPublicDir, mountDir);
|
|
20512
|
+
}
|
|
20323
20513
|
}
|
|
20324
20514
|
};
|
|
20325
20515
|
return [
|
|
@@ -22233,6 +22423,7 @@ function createEndpointThreadStateBridge(state) {
|
|
|
22233
22423
|
setEnv: (propertyName, value, options) => state.setEnv(propertyName, value, options),
|
|
22234
22424
|
notifyParent: (content) => state.notifyParent(content),
|
|
22235
22425
|
setStatus: (status) => state.setStatus(status),
|
|
22426
|
+
stopSession: (options) => state.stopSession(options),
|
|
22236
22427
|
queueTool: (toolName, args) => state.queueTool(toolName, args),
|
|
22237
22428
|
invokeTool: (toolName, args) => state.invokeTool(toolName, args),
|
|
22238
22429
|
scheduleEffect: (name, args, delay) => state.scheduleEffect(name, args, delay),
|
|
@@ -23452,6 +23643,15 @@ var DurableThread = class extends DurableObject {
|
|
|
23452
23643
|
const terminalToolNames = await this.getTerminalSessionToolNames(agentId);
|
|
23453
23644
|
const sessionFailToolNames = terminalToolNames.fail;
|
|
23454
23645
|
const hasTerminalSessionTools = terminalToolNames.all.size > 0;
|
|
23646
|
+
if (flowResult.sessionStopped) {
|
|
23647
|
+
await emitParentHandoffStatus("result");
|
|
23648
|
+
return {
|
|
23649
|
+
status: "success",
|
|
23650
|
+
result: flowResult.sessionStopResult?.trim() || "Session stopped.",
|
|
23651
|
+
attachments: void 0,
|
|
23652
|
+
terminal: true
|
|
23653
|
+
};
|
|
23654
|
+
}
|
|
23455
23655
|
const latestInRunCursor = await this.ctx.storage.sql.exec(
|
|
23456
23656
|
`
|
|
23457
23657
|
SELECT role, name, content, tool_status, attachments
|
|
@@ -24031,27 +24231,30 @@ ${paths.join("\n")}`;
|
|
|
24031
24231
|
if (!parentThreadId || !flowResult.stopped) {
|
|
24032
24232
|
return;
|
|
24033
24233
|
}
|
|
24234
|
+
const sessionStopped = flowResult.sessionStopped === true;
|
|
24034
24235
|
const terminalToolNames = await this.getTerminalSessionToolNames(agentName);
|
|
24035
24236
|
const sessionFailToolNames = terminalToolNames.fail;
|
|
24036
24237
|
const hasTerminalSessionTools = terminalToolNames.all.size > 0;
|
|
24037
|
-
const latestTerminalMessage = hasTerminalSessionTools ? await this.getLatestTerminalSessionMessageAfter(
|
|
24238
|
+
const latestTerminalMessage = !sessionStopped && hasTerminalSessionTools ? await this.getLatestTerminalSessionMessageAfter(
|
|
24038
24239
|
previousTopLevelMessageId,
|
|
24039
24240
|
terminalToolNames.all
|
|
24040
24241
|
) : null;
|
|
24041
|
-
const latest = latestTerminalMessage ?? await this.getLatestTopLevelMessage();
|
|
24042
|
-
if (!latest && !hasTerminalSessionTools) {
|
|
24242
|
+
const latest = sessionStopped ? null : latestTerminalMessage ?? await this.getLatestTopLevelMessage();
|
|
24243
|
+
if (!sessionStopped && !latest && !hasTerminalSessionTools) {
|
|
24043
24244
|
return;
|
|
24044
24245
|
}
|
|
24045
|
-
if (latest && latest.id === previousTopLevelMessageId && !hasTerminalSessionTools) {
|
|
24246
|
+
if (!sessionStopped && latest && latest.id === previousTopLevelMessageId && !hasTerminalSessionTools) {
|
|
24046
24247
|
return;
|
|
24047
24248
|
}
|
|
24048
24249
|
const isTerminalSessionMessage = !!latest && latest.role === "tool" && !!latest.name && terminalToolNames.all.has(latest.name);
|
|
24049
24250
|
const isFailSessionTerminal = isTerminalSessionMessage && !!latest.name && sessionFailToolNames.has(latest.name);
|
|
24050
24251
|
const isSuccessfulTerminalSessionMessage = isTerminalSessionMessage && latest?.tool_status !== "error";
|
|
24051
|
-
const isFailureWithoutTerminalMessage = hasTerminalSessionTools && !isSuccessfulTerminalSessionMessage;
|
|
24252
|
+
const isFailureWithoutTerminalMessage = !sessionStopped && hasTerminalSessionTools && !isSuccessfulTerminalSessionMessage;
|
|
24052
24253
|
const isErrorTerminal = latest?.tool_status === "error" || isFailSessionTerminal || isFailureWithoutTerminalMessage;
|
|
24053
24254
|
let refs = [];
|
|
24054
|
-
if (
|
|
24255
|
+
if (sessionStopped) {
|
|
24256
|
+
refs = [];
|
|
24257
|
+
} else if (hasTerminalSessionTools) {
|
|
24055
24258
|
refs = this.parseAttachmentRefsJson(latestTerminalMessage?.attachments ?? null) ?? [];
|
|
24056
24259
|
} else if (latest?.attachments) {
|
|
24057
24260
|
refs = this.parseAttachmentRefsJson(latest.attachments) ?? [];
|
|
@@ -24069,7 +24272,7 @@ ${paths.join("\n")}`;
|
|
|
24069
24272
|
parentStub,
|
|
24070
24273
|
`from-subagent-${threadId}`
|
|
24071
24274
|
);
|
|
24072
|
-
const resultContent = isFailureWithoutTerminalMessage ? this.buildMissingTerminalSessionFailure(flowResult) : latest?.content || (isErrorTerminal ? "Subagent execution failed." : "Subagent completed.");
|
|
24275
|
+
const resultContent = sessionStopped ? flowResult.sessionStopResult?.trim() || "Session stopped." : isFailureWithoutTerminalMessage ? this.buildMissingTerminalSessionFailure(flowResult) : latest?.content || (isErrorTerminal ? "Subagent execution failed." : "Subagent completed.");
|
|
24073
24276
|
const attachmentSummary = this.formatSubagentAttachmentPathSummary(copiedRefs);
|
|
24074
24277
|
const messageContent = isErrorTerminal ? `Subagent (reference: ${threadId}) has reported a failure:
|
|
24075
24278
|
|
|
@@ -24085,7 +24288,7 @@ ${resultContent}${attachmentSummary}`;
|
|
|
24085
24288
|
metadata: { subagent_id: threadId }
|
|
24086
24289
|
});
|
|
24087
24290
|
}
|
|
24088
|
-
const terminalChildRun = hasTerminalSessionTools;
|
|
24291
|
+
const terminalChildRun = sessionStopped || hasTerminalSessionTools;
|
|
24089
24292
|
await parentStub.updateChildRegistryStatus(
|
|
24090
24293
|
parentThreadId,
|
|
24091
24294
|
threadId,
|