@standardagents/builder 0.17.0 → 0.17.1
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 +330 -45
- 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 +244 -41
- 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 +202 -41
- package/dist/runtime.js.map +1 -1
- package/dist/test.d.ts +1 -1
- package/package.json +4 -4
package/dist/runtime.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { e as ThreadEnv, h as ThreadMetadata, M as Message, l as FileRecord, F as FlowState, n as FileStats, G as GrepResult, m as AttachmentRef, r as MessageContent, E as Env, g as ThreadInstance } from './index-
|
|
2
|
-
export { A as Agent, f as BuilderThreadEndpointHandler, B as Controller, a as ControllerContext, j as FlowResult, p as ImageContentPart, I as ImageMetadata, L as LLMResponse, q as MultimodalContent, R as RequestContext, S as StorageBackend, k as TelemetryEvent, o as TextContentPart, b as ThreadEndpointContext, T as ToolCall, i as ToolResult, c as createThreadEndpointHandler, d as defineController } from './index-
|
|
1
|
+
import { e as ThreadEnv, h as ThreadMetadata, M as Message, l as FileRecord, F as FlowState, n as FileStats, G as GrepResult, m as AttachmentRef, r as MessageContent, E as Env, g as ThreadInstance } from './index-Dx1js-H1.js';
|
|
2
|
+
export { A as Agent, f as BuilderThreadEndpointHandler, B as Controller, a as ControllerContext, j as FlowResult, p as ImageContentPart, I as ImageMetadata, L as LLMResponse, q as MultimodalContent, R as RequestContext, S as StorageBackend, k as TelemetryEvent, o as TextContentPart, b as ThreadEndpointContext, T as ToolCall, i as ToolResult, c as createThreadEndpointHandler, d as defineController } from './index-Dx1js-H1.js';
|
|
3
3
|
import { CodeExecutionOptions, CodeExecutionResult, SubagentRegistryEntry, InjectMessageInput, QueueMessageInput, ModelDefinition as ModelDefinition$1, ToolArgs, PromptTextPart, PromptEnvPart, VariableDefinition, SubpromptConfig as SubpromptConfig$1, PromptToolConfig as PromptToolConfig$1, SubagentToolConfig as SubagentToolConfig$1, ReasoningConfig, SideConfig as SideConfig$1, LLMProviderInterface, ContentPart, TextPart, ImagePart, FilePart, NamespaceContext, DefinitionLoader } from '@standardagents/spec';
|
|
4
4
|
export { AgentType, DefinitionLoader, GlobalNamespaceContext, HookSignatures, ImageContent, ModelCapabilities, ModelProvider, NamespaceContext, PackageSignature, PackedExports, PackedMeta, PackedMetadata, PackedNamespaceContext, PromptInput, PromptTextPart, ProviderAssistantMessage, ProviderError, ProviderErrorCode, ProviderFactory, ProviderFactoryConfig, ProviderFinishReason, ProviderGeneratedImage, ProviderMessage, ProviderMessageContent, ModelCapabilities as ProviderModelCapabilities, ProviderReasoningDetail, ProviderRequest, ProviderResponse, ProviderStreamChunk, ProviderSystemMessage, ProviderTool, ProviderToolCallPart, ProviderToolMessage, ProviderToolResultContent, ProviderUsage, ProviderUserMessage, ReasoningConfig, StructuredPrompt, TextContent, Tool, ToolArgs, ToolArgsNode, ToolArgsRawShape, ToolContent, belongsToPackage, defineAgent, defineHook, defineModel, definePrompt, defineTool, isPacked, isVisibleInNamespace, mapReasoningLevel } from '@standardagents/spec';
|
|
5
5
|
import { DurableObject, WorkerEntrypoint } from 'cloudflare:workers';
|
package/dist/runtime.js
CHANGED
|
@@ -1445,6 +1445,23 @@ function convertUsage(usage) {
|
|
|
1445
1445
|
provider: usage.provider
|
|
1446
1446
|
};
|
|
1447
1447
|
}
|
|
1448
|
+
function inferProviderFromModelId(model) {
|
|
1449
|
+
const trimmed = model?.trim();
|
|
1450
|
+
if (!trimmed) return null;
|
|
1451
|
+
const slashIndex = trimmed.indexOf("/");
|
|
1452
|
+
if (slashIndex <= 0) return null;
|
|
1453
|
+
return trimmed.slice(0, slashIndex);
|
|
1454
|
+
}
|
|
1455
|
+
function inferInitialActualProvider(providerName, modelDef) {
|
|
1456
|
+
if (providerName !== "openrouter") return null;
|
|
1457
|
+
return inferProviderFromModelId(modelDef.model);
|
|
1458
|
+
}
|
|
1459
|
+
function normalizeProviderMetadataValue(value) {
|
|
1460
|
+
if (typeof value !== "string") return void 0;
|
|
1461
|
+
const trimmed = value.trim();
|
|
1462
|
+
if (!trimmed || trimmed.toLowerCase() === "unknown") return void 0;
|
|
1463
|
+
return trimmed;
|
|
1464
|
+
}
|
|
1448
1465
|
var NON_VISION_PLACEHOLDER_TEXT, LLMRequest;
|
|
1449
1466
|
var init_LLMRequest = __esm({
|
|
1450
1467
|
"src/agents/LLMRequest.ts"() {
|
|
@@ -1613,6 +1630,7 @@ var init_LLMRequest = __esm({
|
|
|
1613
1630
|
console.error("Failed to get provider name:", err);
|
|
1614
1631
|
}
|
|
1615
1632
|
const { requestBody, visionFiltering } = buildRequestBody(context, modelDef);
|
|
1633
|
+
const initialActualProvider = inferInitialActualProvider(providerName, modelDef);
|
|
1616
1634
|
const requestBodyForLog = {
|
|
1617
1635
|
...requestBody,
|
|
1618
1636
|
messages: stripBase64FromMessages(
|
|
@@ -1631,6 +1649,7 @@ var init_LLMRequest = __esm({
|
|
|
1631
1649
|
id,
|
|
1632
1650
|
message_id: state.rootMessageId || crypto.randomUUID(),
|
|
1633
1651
|
provider: providerName || this.getProviderFromModel(modelId),
|
|
1652
|
+
actual_provider: initialActualProvider ?? void 0,
|
|
1634
1653
|
model: modelId,
|
|
1635
1654
|
model_name: modelDef.model,
|
|
1636
1655
|
endpoint: "chat.completions",
|
|
@@ -1651,14 +1670,15 @@ var init_LLMRequest = __esm({
|
|
|
1651
1670
|
await state.storage.sql.exec(
|
|
1652
1671
|
`
|
|
1653
1672
|
INSERT INTO logs (
|
|
1654
|
-
id, message_id, provider, model, model_name, endpoint,
|
|
1673
|
+
id, message_id, provider, actual_provider, model, model_name, endpoint,
|
|
1655
1674
|
request_body, tools_available, message_history_length, prompt_name,
|
|
1656
1675
|
parent_log_id, retry_of_log_id, tools_schema, system_prompt, is_complete, created_at
|
|
1657
|
-
) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16)
|
|
1676
|
+
) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15, ?16, ?17)
|
|
1658
1677
|
`,
|
|
1659
1678
|
logData.id,
|
|
1660
1679
|
logData.message_id,
|
|
1661
1680
|
logData.provider,
|
|
1681
|
+
logData.actual_provider,
|
|
1662
1682
|
logData.model,
|
|
1663
1683
|
logData.model_name,
|
|
1664
1684
|
logData.endpoint,
|
|
@@ -1910,7 +1930,7 @@ var init_LLMRequest = __esm({
|
|
|
1910
1930
|
const calculatedCost = calculateUsageCost(response.usage, resolvedPricing);
|
|
1911
1931
|
const providerReportedCost = typeof response.usage.cost === "number" ? response.usage.cost : typeof response.usage.cost === "string" ? parseFloat(response.usage.cost) : null;
|
|
1912
1932
|
const cost_total = providerReportedCost != null && !Number.isNaN(providerReportedCost) ? providerReportedCost : calculatedCost?.costTotal ?? null;
|
|
1913
|
-
const actualProvider = response.usage.provider;
|
|
1933
|
+
const actualProvider = normalizeProviderMetadataValue(response.usage.provider) ?? null;
|
|
1914
1934
|
const aggregateResponse = response._aggregate_response;
|
|
1915
1935
|
const responseBody = aggregateResponse ? JSON.stringify(aggregateResponse) : JSON.stringify(response);
|
|
1916
1936
|
const providerTools = [];
|
|
@@ -2338,8 +2358,13 @@ ${errorStack}` : ""}${errorDetails}`;
|
|
|
2338
2358
|
}).catch((err) => {
|
|
2339
2359
|
console.error("Async metadata fetch failed (non-fatal):", err);
|
|
2340
2360
|
});
|
|
2341
|
-
|
|
2342
|
-
|
|
2361
|
+
const rootState = state.rootState || state;
|
|
2362
|
+
rootState.pendingMetadataPromises = rootState.pendingMetadataPromises || [];
|
|
2363
|
+
rootState.pendingMetadataPromises.push(metadataPromise);
|
|
2364
|
+
if (rootState !== state) {
|
|
2365
|
+
state.pendingMetadataPromises = state.pendingMetadataPromises || [];
|
|
2366
|
+
state.pendingMetadataPromises.push(metadataPromise);
|
|
2367
|
+
}
|
|
2343
2368
|
}
|
|
2344
2369
|
/**
|
|
2345
2370
|
* Update log record with async metadata from provider.
|
|
@@ -2349,9 +2374,12 @@ ${errorStack}` : ""}${errorDetails}`;
|
|
|
2349
2374
|
const updates = [];
|
|
2350
2375
|
const values = [];
|
|
2351
2376
|
let paramIndex = 1;
|
|
2352
|
-
|
|
2377
|
+
const actualProvider = normalizeProviderMetadataValue(
|
|
2378
|
+
metadata.actual_provider ?? metadata.actualProvider ?? metadata.providerName
|
|
2379
|
+
);
|
|
2380
|
+
if (actualProvider !== void 0) {
|
|
2353
2381
|
updates.push(`actual_provider = ?${paramIndex++}`);
|
|
2354
|
-
values.push(
|
|
2382
|
+
values.push(actualProvider);
|
|
2355
2383
|
}
|
|
2356
2384
|
if (metadata.generation_cost !== void 0) {
|
|
2357
2385
|
updates.push(`cost_total = ?${paramIndex++}`);
|
|
@@ -2369,7 +2397,7 @@ ${errorStack}` : ""}${errorDetails}`;
|
|
|
2369
2397
|
log_id: logId,
|
|
2370
2398
|
data: {
|
|
2371
2399
|
id: logId,
|
|
2372
|
-
...
|
|
2400
|
+
...actualProvider !== void 0 && { actual_provider: actualProvider },
|
|
2373
2401
|
...metadata.generation_cost !== void 0 && { cost_total: metadata.generation_cost }
|
|
2374
2402
|
}
|
|
2375
2403
|
});
|
|
@@ -3095,6 +3123,11 @@ var init_ToolExecutor = __esm({
|
|
|
3095
3123
|
state.sequence.queue.push(...toolCalls);
|
|
3096
3124
|
state.sequence.isHandling = true;
|
|
3097
3125
|
while (state.sequence.queue.length > 0) {
|
|
3126
|
+
if (state.stopped) {
|
|
3127
|
+
state.sequence.queue = [];
|
|
3128
|
+
state.sequence.isHandling = false;
|
|
3129
|
+
break;
|
|
3130
|
+
}
|
|
3098
3131
|
if (await state.thread.instance.shouldStop() || state.abortController?.signal.aborted) {
|
|
3099
3132
|
state.sequence.queue = [];
|
|
3100
3133
|
state.sequence.isHandling = false;
|
|
@@ -3123,7 +3156,17 @@ var init_ToolExecutor = __esm({
|
|
|
3123
3156
|
});
|
|
3124
3157
|
continue;
|
|
3125
3158
|
}
|
|
3126
|
-
const
|
|
3159
|
+
const previousToolCall = state.currentToolCall;
|
|
3160
|
+
state.currentToolCall = {
|
|
3161
|
+
id: call.id,
|
|
3162
|
+
name: call.function.name
|
|
3163
|
+
};
|
|
3164
|
+
let result;
|
|
3165
|
+
try {
|
|
3166
|
+
result = await this.executeToolCall(call, state, toolMessageId);
|
|
3167
|
+
} finally {
|
|
3168
|
+
state.currentToolCall = previousToolCall;
|
|
3169
|
+
}
|
|
3127
3170
|
if (result.status === "error") {
|
|
3128
3171
|
const error = new Error(result.error || "Tool execution failed");
|
|
3129
3172
|
if (result.stack) {
|
|
@@ -4992,6 +5035,11 @@ ${attachmentPaths}`;
|
|
|
4992
5035
|
}
|
|
4993
5036
|
}
|
|
4994
5037
|
const toolStatus = processedResult.status === "success" ? "success" : "error";
|
|
5038
|
+
const parentNotifications = this.consumeParentNotificationsForToolCall(
|
|
5039
|
+
state,
|
|
5040
|
+
call
|
|
5041
|
+
);
|
|
5042
|
+
const notificationContent = parentNotifications[parentNotifications.length - 1]?.content;
|
|
4995
5043
|
let message = {
|
|
4996
5044
|
id: messageId,
|
|
4997
5045
|
role: "tool",
|
|
@@ -5005,15 +5053,20 @@ ${attachmentPaths}`;
|
|
|
5005
5053
|
parent_id: state.parentMessageId || null,
|
|
5006
5054
|
depth: state.depth,
|
|
5007
5055
|
attachments: attachmentRefs && attachmentRefs.length > 0 ? JSON.stringify(attachmentRefs) : null,
|
|
5008
|
-
subagent_id: typeof processedResult.subagent_id === "string" && processedResult.subagent_id.trim().length > 0 ? processedResult.subagent_id.trim() : null
|
|
5056
|
+
subagent_id: typeof processedResult.subagent_id === "string" && processedResult.subagent_id.trim().length > 0 ? processedResult.subagent_id.trim() : null,
|
|
5057
|
+
metadata: parentNotifications.length > 0 ? {
|
|
5058
|
+
parent_notification: true,
|
|
5059
|
+
parent_notifications: parentNotifications,
|
|
5060
|
+
parent_notification_content: notificationContent
|
|
5061
|
+
} : void 0
|
|
5009
5062
|
};
|
|
5010
5063
|
message = await FlowEngine2.runBeforeCreateMessageHook(state, message);
|
|
5011
5064
|
message.created_at = Date.now() * TIMESTAMP_MULTIPLIER;
|
|
5012
5065
|
const currentPrompt = state.promptPath.length > 0 ? state.promptPath[state.promptPath.length - 1] : null;
|
|
5013
5066
|
await state.storage.sql.exec(
|
|
5014
5067
|
`
|
|
5015
|
-
INSERT INTO messages (id, role, content, name, tool_call_id, created_at, tool_status, parent_id, depth, attachments, subagent_id, prompt)
|
|
5016
|
-
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12)
|
|
5068
|
+
INSERT INTO messages (id, role, content, name, tool_call_id, created_at, tool_status, parent_id, depth, attachments, subagent_id, prompt, metadata)
|
|
5069
|
+
VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13)
|
|
5017
5070
|
`,
|
|
5018
5071
|
message.id,
|
|
5019
5072
|
message.role,
|
|
@@ -5026,7 +5079,8 @@ ${attachmentPaths}`;
|
|
|
5026
5079
|
message.depth,
|
|
5027
5080
|
message.attachments,
|
|
5028
5081
|
message.subagent_id ?? null,
|
|
5029
|
-
currentPrompt
|
|
5082
|
+
currentPrompt,
|
|
5083
|
+
message.metadata ? JSON.stringify(message.metadata) : null
|
|
5030
5084
|
);
|
|
5031
5085
|
await FlowEngine2.runAfterCreateMessageHook(state, message);
|
|
5032
5086
|
const parentLogId = state.currentLogId || null;
|
|
@@ -5091,6 +5145,23 @@ ${attachmentPaths}`;
|
|
|
5091
5145
|
await this.logError(state, error, `storeToolResult:${call.function.name}`);
|
|
5092
5146
|
}
|
|
5093
5147
|
}
|
|
5148
|
+
static consumeParentNotificationsForToolCall(state, call) {
|
|
5149
|
+
const pending = state.parentNotifications ?? [];
|
|
5150
|
+
if (pending.length === 0) return [];
|
|
5151
|
+
const matched = [];
|
|
5152
|
+
const remaining = [];
|
|
5153
|
+
for (const notification of pending) {
|
|
5154
|
+
const matchesCallId = notification.toolCallId === call.id;
|
|
5155
|
+
const matchesToolName = !notification.toolCallId && notification.toolName === call.function.name;
|
|
5156
|
+
if (matchesCallId || matchesToolName) {
|
|
5157
|
+
matched.push(notification);
|
|
5158
|
+
} else {
|
|
5159
|
+
remaining.push(notification);
|
|
5160
|
+
}
|
|
5161
|
+
}
|
|
5162
|
+
state.parentNotifications = remaining;
|
|
5163
|
+
return matched;
|
|
5164
|
+
}
|
|
5094
5165
|
static async createSilentGeneratedAssetPathMessagesFromToolResult(state, sourceToolMessage, refs, enabled) {
|
|
5095
5166
|
if (!enabled || !refs || refs.length === 0) {
|
|
5096
5167
|
return;
|
|
@@ -5552,6 +5623,8 @@ var init_FlowEngine = __esm({
|
|
|
5552
5623
|
stoppedBy: state.stoppedBy,
|
|
5553
5624
|
stopReason: state.stopReason,
|
|
5554
5625
|
stopReasonCode: state.stopReasonCode,
|
|
5626
|
+
sessionStopped: state.sessionStopped,
|
|
5627
|
+
sessionStopResult: state.sessionStopResult,
|
|
5555
5628
|
stepCount: state.stepCount,
|
|
5556
5629
|
stream: state.stream.httpStream
|
|
5557
5630
|
};
|
|
@@ -5751,6 +5824,8 @@ var init_FlowEngine = __esm({
|
|
|
5751
5824
|
stoppedBy: stateInput.stoppedBy,
|
|
5752
5825
|
stopReason: stateInput.stopReason,
|
|
5753
5826
|
stopReasonCode: stateInput.stopReasonCode,
|
|
5827
|
+
sessionStopped: stateInput.sessionStopped,
|
|
5828
|
+
sessionStopResult: stateInput.sessionStopResult,
|
|
5754
5829
|
messageHistory: [],
|
|
5755
5830
|
sequence: stateInput.sequence || {
|
|
5756
5831
|
queue: [],
|
|
@@ -11720,34 +11795,79 @@ var init_ThreadStateImpl = __esm({
|
|
|
11720
11795
|
this._metadata.tenvs = nextEnv;
|
|
11721
11796
|
}
|
|
11722
11797
|
async notifyParent(content) {
|
|
11723
|
-
|
|
11798
|
+
const trimmedContent = content?.trim();
|
|
11799
|
+
if (!trimmedContent) {
|
|
11724
11800
|
throw new Error("notifyParent requires non-empty content");
|
|
11725
11801
|
}
|
|
11726
|
-
|
|
11727
|
-
|
|
11728
|
-
|
|
11802
|
+
if (this._flowState) {
|
|
11803
|
+
const currentToolCall = this._flowState.currentToolCall;
|
|
11804
|
+
const notification = {
|
|
11805
|
+
content: trimmedContent,
|
|
11806
|
+
toolCallId: currentToolCall?.id ?? null,
|
|
11807
|
+
toolName: currentToolCall?.name ?? this._flowState.active?.tool ?? null,
|
|
11808
|
+
created_at: Date.now() * 1e3
|
|
11809
|
+
};
|
|
11810
|
+
this._flowState.parentNotifications = [
|
|
11811
|
+
...this._flowState.parentNotifications ?? [],
|
|
11812
|
+
notification
|
|
11813
|
+
];
|
|
11814
|
+
}
|
|
11815
|
+
const parentTarget = await this._getOptionalParentThreadStub();
|
|
11816
|
+
if (parentTarget && typeof parentTarget.parentStub.queueMessage === "function") {
|
|
11817
|
+
await parentTarget.parentStub.queueMessage(parentTarget.parentThreadId, {
|
|
11818
|
+
role: "user",
|
|
11819
|
+
content: trimmedContent,
|
|
11820
|
+
silent: true,
|
|
11821
|
+
metadata: { subagent_id: this.threadId }
|
|
11822
|
+
});
|
|
11729
11823
|
}
|
|
11730
|
-
await parentStub.queueMessage(parentThreadId, {
|
|
11731
|
-
role: "user",
|
|
11732
|
-
content: content.trim(),
|
|
11733
|
-
silent: true,
|
|
11734
|
-
metadata: { subagent_id: this.threadId }
|
|
11735
|
-
});
|
|
11736
11824
|
}
|
|
11737
11825
|
async setStatus(status) {
|
|
11738
11826
|
if (!status || !status.trim()) {
|
|
11739
11827
|
throw new Error("setStatus requires non-empty status");
|
|
11740
11828
|
}
|
|
11741
|
-
const
|
|
11742
|
-
if (typeof parentStub.updateChildRegistryStatus !== "function") {
|
|
11743
|
-
|
|
11829
|
+
const parentTarget = await this._getOptionalParentThreadStub();
|
|
11830
|
+
if (!parentTarget || typeof parentTarget.parentStub.updateChildRegistryStatus !== "function") {
|
|
11831
|
+
return;
|
|
11744
11832
|
}
|
|
11745
|
-
await parentStub.updateChildRegistryStatus(
|
|
11746
|
-
parentThreadId,
|
|
11833
|
+
await parentTarget.parentStub.updateChildRegistryStatus(
|
|
11834
|
+
parentTarget.parentThreadId,
|
|
11747
11835
|
this.threadId,
|
|
11748
11836
|
status.trim()
|
|
11749
11837
|
);
|
|
11750
11838
|
}
|
|
11839
|
+
async stopSession(options = {}) {
|
|
11840
|
+
if (!this._flowState) {
|
|
11841
|
+
throw new Error("stopSession requires active execution");
|
|
11842
|
+
}
|
|
11843
|
+
const notifyParent = options.notifyParent?.trim();
|
|
11844
|
+
if (options.notifyParent !== void 0 && !notifyParent) {
|
|
11845
|
+
throw new Error("stopSession notifyParent requires non-empty content");
|
|
11846
|
+
}
|
|
11847
|
+
const status = options.status?.trim();
|
|
11848
|
+
if (options.status !== void 0 && !status) {
|
|
11849
|
+
throw new Error("stopSession status requires non-empty status");
|
|
11850
|
+
}
|
|
11851
|
+
if (notifyParent) {
|
|
11852
|
+
await this.notifyParent(notifyParent);
|
|
11853
|
+
}
|
|
11854
|
+
if (status) {
|
|
11855
|
+
await this.setStatus(status);
|
|
11856
|
+
}
|
|
11857
|
+
const result = options.result?.trim() || "Session stopped.";
|
|
11858
|
+
this._flowState.sessionStopped = true;
|
|
11859
|
+
this._flowState.sessionStopResult = result;
|
|
11860
|
+
this._flowState.stopped = true;
|
|
11861
|
+
this._flowState.stoppedBy = this._flowState.currentSide;
|
|
11862
|
+
this._flowState.stopReason = "Session stopped by state.stopSession()";
|
|
11863
|
+
this._flowState.stopReasonCode = "state_stop_session";
|
|
11864
|
+
this._flowState.emitTelemetry?.({
|
|
11865
|
+
type: "stopped",
|
|
11866
|
+
reason: this._flowState.stopReason,
|
|
11867
|
+
side: this._flowState.currentSide,
|
|
11868
|
+
timestamp: Date.now()
|
|
11869
|
+
});
|
|
11870
|
+
}
|
|
11751
11871
|
async getChildThread(referenceId) {
|
|
11752
11872
|
const agentBuilder = this._getAgentBuilderStub();
|
|
11753
11873
|
const child = await agentBuilder.getThread(referenceId);
|
|
@@ -12160,19 +12280,47 @@ var init_ThreadStateImpl = __esm({
|
|
|
12160
12280
|
return Object.keys(normalized).length > 0 ? normalized : null;
|
|
12161
12281
|
}
|
|
12162
12282
|
async _getParentThreadId() {
|
|
12283
|
+
const parent = await this._getOptionalParentThreadId();
|
|
12284
|
+
if (!parent) {
|
|
12285
|
+
throw new Error(`Thread ${this.threadId} has no parent thread`);
|
|
12286
|
+
}
|
|
12287
|
+
return parent;
|
|
12288
|
+
}
|
|
12289
|
+
async _getOptionalParentThreadId() {
|
|
12163
12290
|
const metadataParent = typeof this._metadata.parent === "string" && this._metadata.parent.trim().length > 0 ? this._metadata.parent.trim() : null;
|
|
12164
12291
|
if (metadataParent) {
|
|
12165
12292
|
return metadataParent;
|
|
12166
12293
|
}
|
|
12167
|
-
|
|
12168
|
-
|
|
12294
|
+
let thread = null;
|
|
12295
|
+
try {
|
|
12296
|
+
const agentBuilder = this._getAgentBuilderStub();
|
|
12297
|
+
thread = await agentBuilder.getThread(this.threadId);
|
|
12298
|
+
} catch {
|
|
12299
|
+
return null;
|
|
12300
|
+
}
|
|
12169
12301
|
const parent = thread && typeof thread.parent === "string" && thread.parent.trim().length > 0 ? thread.parent.trim() : null;
|
|
12170
|
-
if (
|
|
12171
|
-
|
|
12302
|
+
if (parent) {
|
|
12303
|
+
this._metadata.parent = parent;
|
|
12172
12304
|
}
|
|
12173
|
-
this._metadata.parent = parent;
|
|
12174
12305
|
return parent;
|
|
12175
12306
|
}
|
|
12307
|
+
async _getOptionalParentThreadStub() {
|
|
12308
|
+
const parentThreadId = await this._getOptionalParentThreadId();
|
|
12309
|
+
if (!parentThreadId) {
|
|
12310
|
+
return null;
|
|
12311
|
+
}
|
|
12312
|
+
try {
|
|
12313
|
+
const threadNamespace = this._threadInstance.env.AGENT_BUILDER_THREAD;
|
|
12314
|
+
if (!threadNamespace || typeof threadNamespace.idFromName !== "function" || typeof threadNamespace.get !== "function") {
|
|
12315
|
+
return null;
|
|
12316
|
+
}
|
|
12317
|
+
const durableId = threadNamespace.idFromName(parentThreadId);
|
|
12318
|
+
const parentStub = threadNamespace.get(durableId);
|
|
12319
|
+
return { parentThreadId, parentStub };
|
|
12320
|
+
} catch {
|
|
12321
|
+
return null;
|
|
12322
|
+
}
|
|
12323
|
+
}
|
|
12176
12324
|
async _getParentThreadStub() {
|
|
12177
12325
|
const parentThreadId = await this._getParentThreadId();
|
|
12178
12326
|
const durableId = this._threadInstance.env.AGENT_BUILDER_THREAD.idFromName(parentThreadId);
|
|
@@ -14241,6 +14389,7 @@ function createEndpointThreadStateBridge(state) {
|
|
|
14241
14389
|
setEnv: (propertyName, value, options) => state.setEnv(propertyName, value, options),
|
|
14242
14390
|
notifyParent: (content) => state.notifyParent(content),
|
|
14243
14391
|
setStatus: (status) => state.setStatus(status),
|
|
14392
|
+
stopSession: (options) => state.stopSession(options),
|
|
14244
14393
|
queueTool: (toolName, args) => state.queueTool(toolName, args),
|
|
14245
14394
|
invokeTool: (toolName, args) => state.invokeTool(toolName, args),
|
|
14246
14395
|
scheduleEffect: (name, args, delay) => state.scheduleEffect(name, args, delay),
|
|
@@ -15460,6 +15609,15 @@ var DurableThread = class extends DurableObject {
|
|
|
15460
15609
|
const terminalToolNames = await this.getTerminalSessionToolNames(agentId);
|
|
15461
15610
|
const sessionFailToolNames = terminalToolNames.fail;
|
|
15462
15611
|
const hasTerminalSessionTools = terminalToolNames.all.size > 0;
|
|
15612
|
+
if (flowResult.sessionStopped) {
|
|
15613
|
+
await emitParentHandoffStatus("result");
|
|
15614
|
+
return {
|
|
15615
|
+
status: "success",
|
|
15616
|
+
result: flowResult.sessionStopResult?.trim() || "Session stopped.",
|
|
15617
|
+
attachments: void 0,
|
|
15618
|
+
terminal: true
|
|
15619
|
+
};
|
|
15620
|
+
}
|
|
15463
15621
|
const latestInRunCursor = await this.ctx.storage.sql.exec(
|
|
15464
15622
|
`
|
|
15465
15623
|
SELECT role, name, content, tool_status, attachments
|
|
@@ -16039,27 +16197,30 @@ ${paths.join("\n")}`;
|
|
|
16039
16197
|
if (!parentThreadId || !flowResult.stopped) {
|
|
16040
16198
|
return;
|
|
16041
16199
|
}
|
|
16200
|
+
const sessionStopped = flowResult.sessionStopped === true;
|
|
16042
16201
|
const terminalToolNames = await this.getTerminalSessionToolNames(agentName);
|
|
16043
16202
|
const sessionFailToolNames = terminalToolNames.fail;
|
|
16044
16203
|
const hasTerminalSessionTools = terminalToolNames.all.size > 0;
|
|
16045
|
-
const latestTerminalMessage = hasTerminalSessionTools ? await this.getLatestTerminalSessionMessageAfter(
|
|
16204
|
+
const latestTerminalMessage = !sessionStopped && hasTerminalSessionTools ? await this.getLatestTerminalSessionMessageAfter(
|
|
16046
16205
|
previousTopLevelMessageId,
|
|
16047
16206
|
terminalToolNames.all
|
|
16048
16207
|
) : null;
|
|
16049
|
-
const latest = latestTerminalMessage ?? await this.getLatestTopLevelMessage();
|
|
16050
|
-
if (!latest && !hasTerminalSessionTools) {
|
|
16208
|
+
const latest = sessionStopped ? null : latestTerminalMessage ?? await this.getLatestTopLevelMessage();
|
|
16209
|
+
if (!sessionStopped && !latest && !hasTerminalSessionTools) {
|
|
16051
16210
|
return;
|
|
16052
16211
|
}
|
|
16053
|
-
if (latest && latest.id === previousTopLevelMessageId && !hasTerminalSessionTools) {
|
|
16212
|
+
if (!sessionStopped && latest && latest.id === previousTopLevelMessageId && !hasTerminalSessionTools) {
|
|
16054
16213
|
return;
|
|
16055
16214
|
}
|
|
16056
16215
|
const isTerminalSessionMessage = !!latest && latest.role === "tool" && !!latest.name && terminalToolNames.all.has(latest.name);
|
|
16057
16216
|
const isFailSessionTerminal = isTerminalSessionMessage && !!latest.name && sessionFailToolNames.has(latest.name);
|
|
16058
16217
|
const isSuccessfulTerminalSessionMessage = isTerminalSessionMessage && latest?.tool_status !== "error";
|
|
16059
|
-
const isFailureWithoutTerminalMessage = hasTerminalSessionTools && !isSuccessfulTerminalSessionMessage;
|
|
16218
|
+
const isFailureWithoutTerminalMessage = !sessionStopped && hasTerminalSessionTools && !isSuccessfulTerminalSessionMessage;
|
|
16060
16219
|
const isErrorTerminal = latest?.tool_status === "error" || isFailSessionTerminal || isFailureWithoutTerminalMessage;
|
|
16061
16220
|
let refs = [];
|
|
16062
|
-
if (
|
|
16221
|
+
if (sessionStopped) {
|
|
16222
|
+
refs = [];
|
|
16223
|
+
} else if (hasTerminalSessionTools) {
|
|
16063
16224
|
refs = this.parseAttachmentRefsJson(latestTerminalMessage?.attachments ?? null) ?? [];
|
|
16064
16225
|
} else if (latest?.attachments) {
|
|
16065
16226
|
refs = this.parseAttachmentRefsJson(latest.attachments) ?? [];
|
|
@@ -16077,7 +16238,7 @@ ${paths.join("\n")}`;
|
|
|
16077
16238
|
parentStub,
|
|
16078
16239
|
`from-subagent-${threadId}`
|
|
16079
16240
|
);
|
|
16080
|
-
const resultContent = isFailureWithoutTerminalMessage ? this.buildMissingTerminalSessionFailure(flowResult) : latest?.content || (isErrorTerminal ? "Subagent execution failed." : "Subagent completed.");
|
|
16241
|
+
const resultContent = sessionStopped ? flowResult.sessionStopResult?.trim() || "Session stopped." : isFailureWithoutTerminalMessage ? this.buildMissingTerminalSessionFailure(flowResult) : latest?.content || (isErrorTerminal ? "Subagent execution failed." : "Subagent completed.");
|
|
16081
16242
|
const attachmentSummary = this.formatSubagentAttachmentPathSummary(copiedRefs);
|
|
16082
16243
|
const messageContent = isErrorTerminal ? `Subagent (reference: ${threadId}) has reported a failure:
|
|
16083
16244
|
|
|
@@ -16093,7 +16254,7 @@ ${resultContent}${attachmentSummary}`;
|
|
|
16093
16254
|
metadata: { subagent_id: threadId }
|
|
16094
16255
|
});
|
|
16095
16256
|
}
|
|
16096
|
-
const terminalChildRun = hasTerminalSessionTools;
|
|
16257
|
+
const terminalChildRun = sessionStopped || hasTerminalSessionTools;
|
|
16097
16258
|
await parentStub.updateChildRegistryStatus(
|
|
16098
16259
|
parentThreadId,
|
|
16099
16260
|
threadId,
|