@abot-ai/runtime 1.8.0 → 1.8.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/README.md +216 -222
- package/dist/src/capabilities/tool-definition-validator/definition-parser.js +8 -0
- package/dist/src/capabilities/tool-types.d.ts +4 -0
- package/dist/src/model-gateway/protocol/message-contract.d.ts +1 -0
- package/dist/src/model-gateway/protocol/message-contract.js +1 -1
- package/dist/src/model-gateway/server/chat-handler.js +5 -7
- package/dist/src/model-gateway/server/chat-stream-response.d.ts +7 -0
- package/dist/src/model-gateway/server/chat-stream-response.js +25 -0
- package/dist/src/runtime/adapters/registered-tool-worker-capabilities/payload-rejection.d.ts +2 -2
- package/dist/src/runtime/adapters/registered-tool-worker-capabilities/payload-rejection.js +2 -2
- package/dist/src/runtime/adapters/registered-tool-worker-capabilities/prepared-execution.js +17 -11
- package/dist/src/runtime/capabilities/tool-availability.js +6 -0
- package/dist/src/runtime/context/capability-brief.d.ts +2 -2
- package/dist/src/runtime/context/capability-brief.js +3 -3
- package/dist/src/runtime/context/capability-descriptions.d.ts +3 -2
- package/dist/src/runtime/context/capability-descriptions.js +57 -20
- package/dist/src/runtime/long-term-memory/conversation-authoring/context.d.ts +6 -1
- package/dist/src/runtime/long-term-memory/conversation-authoring/context.js +51 -25
- package/dist/src/runtime/long-term-memory/initial-context.d.ts +17 -0
- package/dist/src/runtime/long-term-memory/initial-context.js +57 -0
- package/dist/src/runtime/long-term-memory/projection.js +1 -1
- package/dist/src/runtime/orchestration/role-calls/candidate-validation.js +2 -1
- package/dist/src/runtime/orchestration/role-calls/checkpoint-state.d.ts +1 -1
- package/dist/src/runtime/orchestration/role-calls/checkpoint-state.js +5 -2
- package/dist/src/runtime/orchestration/role-calls/contracts.d.ts +2 -1
- package/dist/src/runtime/orchestration/role-calls/ledger.d.ts +2 -1
- package/dist/src/runtime/orchestration/role-calls/ledger.js +2 -2
- package/dist/src/runtime/orchestration/role-calls/memory-recall-contract.d.ts +7 -0
- package/dist/src/runtime/orchestration/role-calls/memory-recall-state-validation.d.ts +2 -0
- package/dist/src/runtime/orchestration/role-calls/memory-recall-state-validation.js +88 -0
- package/dist/src/runtime/orchestration/role-calls/reducer.d.ts +1 -1
- package/dist/src/runtime/orchestration/role-calls/reducer.js +2 -1
- package/dist/src/runtime/orchestration/worker-capabilities/contracts.d.ts +3 -1
- package/dist/src/runtime/orchestration/worker-capabilities/contracts.js +1 -1
- package/dist/src/runtime/orchestration/worker-capabilities/execution/approval-group.js +5 -1
- package/dist/src/runtime/orchestration/worker-capabilities/execution/execution-freshness.d.ts +5 -0
- package/dist/src/runtime/orchestration/worker-capabilities/execution/execution-freshness.js +31 -0
- package/dist/src/runtime/plugins/manifest-projection.js +3 -0
- package/dist/src/runtime/request/capability-execution-freshness.js +6 -1
- package/dist/src/runtime/request/execution-agent-root-execution.js +11 -1
- package/dist/src/runtime/request/root-contract.d.ts +2 -0
- package/dist/src/runtime/request/root-execution-kernel.js +1 -0
- package/dist/src/runtime/request/runner.js +9 -3
- package/dist/src/runtime/request/supervisor-root-execution.js +6 -0
- package/dist/src/runtime/steps/execution-agent/contracts.d.ts +10 -0
- package/dist/src/runtime/steps/execution-agent/decision-parsing.js +13 -1
- package/dist/src/runtime/steps/execution-agent/direct-response-configuration.d.ts +3 -0
- package/dist/src/runtime/steps/execution-agent/direct-response-configuration.js +64 -0
- package/dist/src/runtime/steps/execution-agent/direct-response-contract.d.ts +7 -0
- package/dist/src/runtime/steps/execution-agent/direct-response-contract.js +56 -0
- package/dist/src/runtime/steps/execution-agent/direct-response-policy.d.ts +9 -0
- package/dist/src/runtime/steps/execution-agent/direct-response-policy.js +30 -0
- package/dist/src/runtime/steps/execution-agent/direct-response-prompt.d.ts +7 -0
- package/dist/src/runtime/steps/execution-agent/direct-response-prompt.js +43 -0
- package/dist/src/runtime/steps/execution-agent/format.js +2 -0
- package/dist/src/runtime/steps/execution-agent/input.d.ts +2 -0
- package/dist/src/runtime/steps/execution-agent/input.js +22 -1
- package/dist/src/runtime/steps/execution-agent/plugin-catalog.d.ts +4 -0
- package/dist/src/runtime/steps/execution-agent/plugin-catalog.js +8 -0
- package/dist/src/runtime/steps/execution-agent/prompt.d.ts +1 -0
- package/dist/src/runtime/steps/execution-agent/prompt.js +3 -4
- package/dist/src/runtime/steps/execution-agent/response-run.js +5 -11
- package/dist/src/runtime/steps/execution-agent/run.js +4 -1
- package/dist/src/runtime/steps/execution-agent/state-context.d.ts +2 -3
- package/dist/src/runtime/steps/execution-agent/state-context.js +2 -39
- package/dist/src/runtime/steps/planner-decision/capability-brief.d.ts +2 -0
- package/dist/src/runtime/steps/planner-decision/prompt.js +26 -49
- package/dist/src/runtime/steps/supervisor-decision/input.d.ts +1 -0
- package/dist/src/runtime/steps/supervisor-decision/input.js +5 -0
- package/dist/src/runtime/steps/supervisor-decision/prompt.d.ts +1 -0
- package/dist/src/runtime/steps/supervisor-decision/prompt.js +6 -2
- package/dist/src/runtime/steps/supervisor-decision/run.d.ts +1 -0
- package/dist/src/runtime/steps/supervisor-decision/run.js +4 -0
- package/dist/src/runtime/steps/supervisor-response/run.d.ts +2 -0
- package/dist/src/runtime/steps/supervisor-response/run.js +3 -6
- package/dist/src/web-ui/app/ARCHITECTURE.md +1 -1
- package/dist/src/web-ui/app/app.js +1 -0
- package/dist/src/web-ui/app/components/automations/timeline.js +3 -2
- package/dist/src/web-ui/app/components/dashboard/compact-layout.js +137 -0
- package/dist/src/web-ui/app/components/dashboard/icons.js +5 -0
- package/dist/src/web-ui/app/components/dashboard/widget-card.js +85 -0
- package/dist/src/web-ui/app/components/dashboard/widget-dialog.js +83 -0
- package/dist/src/web-ui/app/components/dashboard/widget-summaries.js +155 -0
- package/dist/src/web-ui/app/components/dashboard/workspace.js +28 -4
- package/dist/src/web-ui/app/components/operations-summary.js +2 -1
- package/dist/src/web-ui/app/components/passive-learning/home-widget-preview.js +32 -0
- package/dist/src/web-ui/app/components/passive-learning/home.js +4 -1
- package/dist/src/web-ui/app/components/schedules/details.js +3 -2
- package/dist/src/web-ui/app/components/spark-chat/panel.js +1 -1
- package/dist/src/web-ui/app/components/spark-chat/settings.js +1 -1
- package/dist/src/web-ui/app/components/system-host/home-widget-permission-preview.js +75 -0
- package/dist/src/web-ui/app/components/system-host/home-widget-summary.js +93 -0
- package/dist/src/web-ui/app/components/system-host/macos-permission-rendering.js +2 -2
- package/dist/src/web-ui/app/components/system-host/native-windows-access.js +1 -1
- package/dist/src/web-ui/app/components/system-host/rendering.js +3 -3
- package/dist/src/web-ui/app/components/system-host/windows-store-setup.js +2 -2
- package/dist/src/web-ui/app/computer-access-feature.js +13 -1
- package/dist/src/web-ui/app/configuration-feature.js +2 -0
- package/dist/src/web-ui/app/controllers/operations-controller.js +2 -1
- package/dist/src/web-ui/app/controllers/reasoning-mode-controller.js +1 -1
- package/dist/src/web-ui/app/dashboard-feature.js +9 -0
- package/dist/src/web-ui/app/lib/reasoning-controls.js +6 -1
- package/dist/src/web-ui/app/passive-learning-feature.js +2 -2
- package/dist/src/web-ui/app/styles/95-home-widgets.css +109 -0
- package/dist/src/web-ui/app/styles.css +1 -0
- package/docs/plugins.md +37 -32
- package/package.json +1 -1
- package/plugins/capability-brief/plugin.json +1 -1
- package/plugins/code-outline/plugin.json +1 -1
- package/plugins/document-reader/plugin.json +1 -1
- package/plugins/exec/plugin.json +1 -1
- package/plugins/filesystem/plugin.json +1 -1
- package/plugins/json-inspector/plugin.json +1 -1
- package/plugins/local-search/plugin.json +1 -1
- package/plugins/memory/plugin.json +1 -1
- package/plugins/project-orientation/plugin.json +1 -1
- package/plugins/system/plugin.json +1 -1
- package/plugins/system-probe/plugin.json +1 -1
- package/plugins/web/plugin.json +1 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isAssistantToolCallMessage, isStrictTextChatMessage, isToolResultMessage, } from "../../../model-gateway/message-contract.js";
|
|
1
2
|
import { RUNTIME_ROOT_ROLE_ID } from "../roles.js";
|
|
2
3
|
import { hasMemoryRecallIdentity, isBoundedMemoryRecallQuery, normalizeRoleMemoryRecallResult, } from "./memory-recall-decoder.js";
|
|
3
4
|
import { exactKeys, isRecord } from "../../validation/strict-record.js";
|
|
@@ -119,3 +120,90 @@ function hasUnboundMemoryWait(state, pendingCount) {
|
|
|
119
120
|
return true;
|
|
120
121
|
return waitingCalls.some((call) => call.callId !== state.rootCallId);
|
|
121
122
|
}
|
|
123
|
+
/** The existing checkpoint carries this passive startup field, never a model action. */
|
|
124
|
+
export function hasInitialMemoryContext(value, policyId) {
|
|
125
|
+
if (value === undefined)
|
|
126
|
+
return true;
|
|
127
|
+
if (policyId !== "execution-agent-v1" && policyId !== "supervisor-worker-v1")
|
|
128
|
+
return false;
|
|
129
|
+
if (!isRecord(value) || !exactKeys(value, [], ["message", "knowledge"]))
|
|
130
|
+
return false;
|
|
131
|
+
if (value.message !== undefined && !isInitialMemoryMessage(value.message))
|
|
132
|
+
return false;
|
|
133
|
+
if (value.knowledge === undefined)
|
|
134
|
+
return true;
|
|
135
|
+
return isInitialMemoryKnowledge(value.knowledge);
|
|
136
|
+
}
|
|
137
|
+
function isInitialMemoryMessage(value) {
|
|
138
|
+
if (isStrictTextChatMessage(value))
|
|
139
|
+
return true;
|
|
140
|
+
if (isAssistantToolCallMessage(value))
|
|
141
|
+
return true;
|
|
142
|
+
return isToolResultMessage(value);
|
|
143
|
+
}
|
|
144
|
+
function isInitialMemoryKnowledge(value) {
|
|
145
|
+
if (!isRecord(value))
|
|
146
|
+
return false;
|
|
147
|
+
if (value.kind !== "learning_knowledge_reference_v1")
|
|
148
|
+
return false;
|
|
149
|
+
if (value.authority !== "passive_reference")
|
|
150
|
+
return false;
|
|
151
|
+
if (value.presenceEffect !== "does_not_authorize_actions_or_add_user_intent")
|
|
152
|
+
return false;
|
|
153
|
+
if (!isMemoryRevision(value.repositoryRevision))
|
|
154
|
+
return false;
|
|
155
|
+
if (!isMemoryRevision(value.knowledgeRevision))
|
|
156
|
+
return false;
|
|
157
|
+
if (!isMemoryRevision(value.omitted))
|
|
158
|
+
return false;
|
|
159
|
+
if (typeof value.referenceTime !== "string" || !Number.isFinite(Date.parse(value.referenceTime)))
|
|
160
|
+
return false;
|
|
161
|
+
if (!Array.isArray(value.entries) || value.entries.length > 12)
|
|
162
|
+
return false;
|
|
163
|
+
if (!value.entries.every(isInitialMemoryKnowledgeEntry))
|
|
164
|
+
return false;
|
|
165
|
+
const identities = value.entries.map(entry => JSON.stringify([entry.kind, entry.id]));
|
|
166
|
+
return new Set(identities).size === identities.length;
|
|
167
|
+
}
|
|
168
|
+
function isMemoryRevision(value) {
|
|
169
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value))
|
|
170
|
+
return false;
|
|
171
|
+
return value >= 0;
|
|
172
|
+
}
|
|
173
|
+
function isInitialMemoryKnowledgeEntry(value) {
|
|
174
|
+
if (!isRecord(value))
|
|
175
|
+
return false;
|
|
176
|
+
if (value.kind !== "candidate" && value.kind !== "memory")
|
|
177
|
+
return false;
|
|
178
|
+
if (typeof value.id !== "string" || value.id.length === 0)
|
|
179
|
+
return false;
|
|
180
|
+
if (typeof value.version !== "string" || value.version.length === 0)
|
|
181
|
+
return false;
|
|
182
|
+
if (typeof value.content !== "string")
|
|
183
|
+
return false;
|
|
184
|
+
if (!Array.isArray(value.tags) || !value.tags.every(tag => typeof tag === "string"))
|
|
185
|
+
return false;
|
|
186
|
+
if (typeof value.mutable !== "boolean")
|
|
187
|
+
return false;
|
|
188
|
+
if (value.score !== null && !isMemoryScore(value.score))
|
|
189
|
+
return false;
|
|
190
|
+
if (value.reason !== null && typeof value.reason !== "string")
|
|
191
|
+
return false;
|
|
192
|
+
if (!["observed", "inferred", "unspecified"].includes(value.certainty))
|
|
193
|
+
return false;
|
|
194
|
+
if (!isOptionalMemoryTime(value.lastReinforcedAt))
|
|
195
|
+
return false;
|
|
196
|
+
return isOptionalMemoryTime(value.reconsiderAt);
|
|
197
|
+
}
|
|
198
|
+
function isMemoryScore(value) {
|
|
199
|
+
if (typeof value !== "number" || !Number.isFinite(value))
|
|
200
|
+
return false;
|
|
201
|
+
return value >= 0 && value <= 100;
|
|
202
|
+
}
|
|
203
|
+
function isOptionalMemoryTime(value) {
|
|
204
|
+
if (value === null)
|
|
205
|
+
return true;
|
|
206
|
+
if (typeof value !== "string")
|
|
207
|
+
return false;
|
|
208
|
+
return Number.isFinite(Date.parse(value));
|
|
209
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type RoleCallPolicy, type RoleCallPolicyInput, type RoleCallState, type RoleCallTransitionResult, type RoleCallValidationIssue } from "./contracts.js";
|
|
2
2
|
export { hasRoleCallCapabilityAuthority } from "./candidate-validation.js";
|
|
3
|
-
export declare function createInitialRoleCallState(requestId: string): RoleCallState;
|
|
3
|
+
export declare function createInitialRoleCallState(requestId: string, initialMemory?: RoleCallState["initialMemory"]): RoleCallState;
|
|
4
4
|
export declare function applyRoleCallCommand(state: RoleCallState, commandInput: unknown, policy: RoleCallPolicy, admittedHeadRevision?: number): RoleCallTransitionResult;
|
|
5
5
|
export declare function validateRoleCallCandidate(params: {
|
|
6
6
|
state: RoleCallState;
|
|
@@ -8,7 +8,7 @@ import { issueInitialRoleCapabilitySelectionSupervisionState } from "./capabilit
|
|
|
8
8
|
import { createInitialRoleOperationSupervisionState } from "./operation-supervision.js";
|
|
9
9
|
import { reject, seal } from "./reducer-primitives.js";
|
|
10
10
|
export { hasRoleCallCapabilityAuthority } from "./candidate-validation.js";
|
|
11
|
-
export function createInitialRoleCallState(requestId) {
|
|
11
|
+
export function createInitialRoleCallState(requestId, initialMemory) {
|
|
12
12
|
const state = seal({
|
|
13
13
|
contractVersion: ROLE_CALL_LEDGER_CONTRACT_VERSION,
|
|
14
14
|
requestId,
|
|
@@ -23,6 +23,7 @@ export function createInitialRoleCallState(requestId) {
|
|
|
23
23
|
plans: [],
|
|
24
24
|
capabilityExecutions: [],
|
|
25
25
|
memoryRecalls: [],
|
|
26
|
+
...(initialMemory !== undefined ? { initialMemory } : {}),
|
|
26
27
|
operationSupervision: createInitialRoleOperationSupervisionState(),
|
|
27
28
|
capabilitySelectionSupervision: createInitialRoleCapabilitySelectionSupervisionState(),
|
|
28
29
|
rootResponse: null,
|
|
@@ -12,7 +12,7 @@ export declare const WORKER_CAPABILITY_SUMMARY_MAX_LENGTH = 512;
|
|
|
12
12
|
export declare const WORKER_CAPABILITY_COUNT_MAX = 128;
|
|
13
13
|
export declare const WORKER_CAPABILITY_CONTROL_COUNT_MAX = 16;
|
|
14
14
|
export declare const WORKER_CAPABILITY_CONTROL_ID_MAX_LENGTH = 64;
|
|
15
|
-
export { TOOL_NORMAL_INVOCATION_STRING_MAX_LENGTH as WORKER_CAPABILITY_CONTROL_STRING_MAX_LENGTH
|
|
15
|
+
export { TOOL_NORMAL_INVOCATION_STRING_MAX_LENGTH as WORKER_CAPABILITY_CONTROL_STRING_MAX_LENGTH } from "../../../capabilities/normal-invocation/contracts.js";
|
|
16
16
|
export declare const WORKER_CAPABILITY_CONTROL_ENUM_MAX_VALUES = 64;
|
|
17
17
|
export declare const WORKER_CAPABILITY_CONTROL_ENUM_VALUE_MAX_LENGTH = 256;
|
|
18
18
|
export declare const WORKER_CAPABILITY_CONTROL_ARRAY_MAX_ITEMS = 64;
|
|
@@ -165,6 +165,8 @@ export type WorkerCapabilityPreparedExecution = Readonly<{
|
|
|
165
165
|
onAdmitted?(executionId: string): void;
|
|
166
166
|
approvalRequest?: ToolApprovalRequest;
|
|
167
167
|
applyApprovalDecision?(decision: BoundApprovalDecision): void;
|
|
168
|
+
/** Project a fenced rejection with adapter-owned lifecycle and evidence; never execute. */
|
|
169
|
+
rejectBeforeExecution?(executionId: string, code: string, message: string): WorkerCapabilityAdapterResult;
|
|
168
170
|
execute(executionId: string): Promise<WorkerCapabilityAdapterResult>;
|
|
169
171
|
}>;
|
|
170
172
|
export type WorkerCapabilityAdapterPreparationInput<TContext> = Readonly<Omit<WorkerCapabilityAdapterExecutionInput<TContext>, "executionId"> & {
|
|
@@ -8,7 +8,7 @@ export const WORKER_CAPABILITY_SUMMARY_MAX_LENGTH = 512;
|
|
|
8
8
|
export const WORKER_CAPABILITY_COUNT_MAX = 128;
|
|
9
9
|
export const WORKER_CAPABILITY_CONTROL_COUNT_MAX = 16;
|
|
10
10
|
export const WORKER_CAPABILITY_CONTROL_ID_MAX_LENGTH = 64;
|
|
11
|
-
export { TOOL_NORMAL_INVOCATION_STRING_MAX_LENGTH as WORKER_CAPABILITY_CONTROL_STRING_MAX_LENGTH
|
|
11
|
+
export { TOOL_NORMAL_INVOCATION_STRING_MAX_LENGTH as WORKER_CAPABILITY_CONTROL_STRING_MAX_LENGTH } from "../../../capabilities/normal-invocation/contracts.js";
|
|
12
12
|
export const WORKER_CAPABILITY_CONTROL_ENUM_MAX_VALUES = 64;
|
|
13
13
|
export const WORKER_CAPABILITY_CONTROL_ENUM_VALUE_MAX_LENGTH = 256;
|
|
14
14
|
export const WORKER_CAPABILITY_CONTROL_ARRAY_MAX_ITEMS = 64;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { fenceRestoredApprovalExecution } from "./execution-freshness.js";
|
|
1
2
|
import { restorePreparationRejection } from "./preparation-rejection.js";
|
|
2
3
|
import { isDeepStrictEqual } from "node:util";
|
|
3
4
|
import { settleAdmittedPreparedGroup } from "./settle-prepared.js";
|
|
@@ -132,7 +133,10 @@ export async function restoreCapabilityApprovalGroup(params) {
|
|
|
132
133
|
ledger: params.ledger,
|
|
133
134
|
expectedHead: head,
|
|
134
135
|
call,
|
|
135
|
-
invocations
|
|
136
|
+
invocations: invocations.map((invocation) => ({
|
|
137
|
+
...invocation,
|
|
138
|
+
prepared: fenceRestoredApprovalExecution(invocation.prepared, params.executionFreshness),
|
|
139
|
+
})),
|
|
136
140
|
executionIds: group.entries.map((entry) => entry.executionId),
|
|
137
141
|
batch: group.batch,
|
|
138
142
|
diagnostic,
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { WorkerCapabilityExecutionFreshness, WorkerCapabilityPreparedExecution } from "../contracts.js";
|
|
2
|
+
export declare const STEERING_SUPERSEDED_BEFORE_EXTERNAL_EXECUTION: "steering_superseded_before_external_execution";
|
|
3
|
+
export declare const STEERING_SUPERSEDED_SUMMARY = "steering_superseded_before_external_execution: No external execution occurred because a newer active-request update superseded this capability invocation.";
|
|
4
|
+
/** Preserve the admitted identity and decision binding; only fence its dispatch. */
|
|
5
|
+
export declare function fenceRestoredApprovalExecution(prepared: WorkerCapabilityPreparedExecution, freshness: WorkerCapabilityExecutionFreshness | undefined): WorkerCapabilityPreparedExecution;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export const STEERING_SUPERSEDED_BEFORE_EXTERNAL_EXECUTION = "steering_superseded_before_external_execution";
|
|
2
|
+
export const STEERING_SUPERSEDED_SUMMARY = "steering_superseded_before_external_execution: No external execution occurred because a newer active-request update superseded this capability invocation.";
|
|
3
|
+
/** Preserve the admitted identity and decision binding; only fence its dispatch. */
|
|
4
|
+
export function fenceRestoredApprovalExecution(prepared, freshness) {
|
|
5
|
+
if (!freshness)
|
|
6
|
+
return prepared;
|
|
7
|
+
return Object.freeze({
|
|
8
|
+
...prepared,
|
|
9
|
+
async execute(executionId) {
|
|
10
|
+
if (freshness.isCurrent())
|
|
11
|
+
return prepared.execute(executionId);
|
|
12
|
+
if (prepared.rejectBeforeExecution)
|
|
13
|
+
return prepared.rejectBeforeExecution(executionId, STEERING_SUPERSEDED_BEFORE_EXTERNAL_EXECUTION, STEERING_SUPERSEDED_SUMMARY);
|
|
14
|
+
return Object.freeze({
|
|
15
|
+
outcome: "failed",
|
|
16
|
+
observedEffect: "none",
|
|
17
|
+
summary: STEERING_SUPERSEDED_SUMMARY,
|
|
18
|
+
// This is request control, not evidence of a repeatable tool failure.
|
|
19
|
+
failureOutcomeFingerprint: null,
|
|
20
|
+
exactResult: Object.freeze({
|
|
21
|
+
kind: "runtime_capability_rejection_v1",
|
|
22
|
+
authority: "runtime",
|
|
23
|
+
status: "rejected",
|
|
24
|
+
stage: "before_external_execution",
|
|
25
|
+
code: STEERING_SUPERSEDED_BEFORE_EXTERNAL_EXECUTION,
|
|
26
|
+
message: STEERING_SUPERSEDED_SUMMARY,
|
|
27
|
+
}),
|
|
28
|
+
});
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
}
|
|
@@ -41,6 +41,9 @@ export function projectManifestRuntimeContract(discovered, selectedCapabilityIds
|
|
|
41
41
|
definition: {
|
|
42
42
|
name: capabilityId,
|
|
43
43
|
pluginName: manifest.name,
|
|
44
|
+
...(manifest.description !== undefined
|
|
45
|
+
? { pluginDescription: manifest.description }
|
|
46
|
+
: {}),
|
|
44
47
|
...(capability.requiredPermissionMode
|
|
45
48
|
? { requiredPermissionMode: capability.requiredPermissionMode }
|
|
46
49
|
: {}),
|
|
@@ -22,7 +22,12 @@ export function restoreApprovalExecutionFreshness(token, requestSteering) {
|
|
|
22
22
|
});
|
|
23
23
|
if (!isDeepStrictEqual(current.token, token))
|
|
24
24
|
throw new Error("request_approval_steering_mismatch");
|
|
25
|
-
|
|
25
|
+
// A newer accepted prefix invalidates execution, not the saved approval.
|
|
26
|
+
// A closed inbox has no current version and must remain terminal.
|
|
27
|
+
if (!hasLiveSteeringInbox(inbox))
|
|
26
28
|
throw new Error("request_approval_steering_superseded");
|
|
27
29
|
return Object.freeze({ token, isCurrent: current.isCurrent });
|
|
28
30
|
}
|
|
31
|
+
function hasLiveSteeringInbox(inbox) {
|
|
32
|
+
return inbox.isCurrent(inbox.snapshot().version);
|
|
33
|
+
}
|
|
@@ -37,6 +37,8 @@ export const EXECUTION_AGENT_ROOT_CONTRACT = Object.freeze({
|
|
|
37
37
|
});
|
|
38
38
|
},
|
|
39
39
|
async authorResponse(request, options) {
|
|
40
|
+
if (options.directResponse !== undefined)
|
|
41
|
+
return options.directResponse;
|
|
40
42
|
const requestSteering = resolveRequestSteeringInbox(request.requestSteering);
|
|
41
43
|
return runExecutionAgentAuthoredResponse(request, {
|
|
42
44
|
head: options.head,
|
|
@@ -115,7 +117,15 @@ function projectKernelDecision(decision, steeringVersion) {
|
|
|
115
117
|
...presentation,
|
|
116
118
|
});
|
|
117
119
|
case "respond":
|
|
118
|
-
return Object.freeze({
|
|
120
|
+
return Object.freeze({
|
|
121
|
+
action: "respond", ...presentation,
|
|
122
|
+
...(decision.response !== undefined ? {
|
|
123
|
+
directResponse: Object.freeze({
|
|
124
|
+
finalResponse: decision.response,
|
|
125
|
+
memoryCandidates: decision.memoryCandidates ?? Object.freeze([]),
|
|
126
|
+
}),
|
|
127
|
+
} : {}),
|
|
128
|
+
});
|
|
119
129
|
case "blocked":
|
|
120
130
|
return Object.freeze({
|
|
121
131
|
action: "blocked",
|
|
@@ -19,6 +19,7 @@ export type RootContractCallIdentity = Readonly<{
|
|
|
19
19
|
type RootContractAction = MemoryRecallDecision | Readonly<{
|
|
20
20
|
action: "respond";
|
|
21
21
|
responseRecommendation?: string;
|
|
22
|
+
directResponse?: RootAuthoredResponse;
|
|
22
23
|
acknowledgement?: string;
|
|
23
24
|
title?: string;
|
|
24
25
|
}> | Readonly<{
|
|
@@ -99,6 +100,7 @@ export type RootContractAdapter<TRequest> = Readonly<{
|
|
|
99
100
|
callFrame: RoleCallFrame;
|
|
100
101
|
steeringVersion: number;
|
|
101
102
|
responseRecommendation?: string;
|
|
103
|
+
directResponse?: RootAuthoredResponse;
|
|
102
104
|
call: RootContractCallIdentity;
|
|
103
105
|
toolResults: RequestToolResultsView;
|
|
104
106
|
resume?: RoleChildReturnContext;
|
|
@@ -492,6 +492,7 @@ class RootExecutionSession {
|
|
|
492
492
|
? createPlainRootAuthoredResponse(decision.response)
|
|
493
493
|
: await this.policy.rootContract.authorResponse(this.request, {
|
|
494
494
|
responseRecommendation: decision.responseRecommendation,
|
|
495
|
+
directResponse: decision.directResponse,
|
|
495
496
|
memoryRecallMessage: projectRootMemoryRecallMessage({
|
|
496
497
|
head: activation.head,
|
|
497
498
|
callId: activation.call.callId,
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { prepareInitialMemory } from "../long-term-memory/initial-context.js";
|
|
1
2
|
import { createRequestRoleCallPolicy } from "./role-call-policy.js";
|
|
2
3
|
import { restoreApprovalExecutionFreshness } from "./capability-execution-freshness.js";
|
|
3
4
|
import { captureRoleCallLedgerCheckpoint } from "../orchestration/role-calls/checkpoint.js";
|
|
4
5
|
import { isRoleApprovalWait } from "../orchestration/role-executors/approval-continuation.js";
|
|
5
|
-
import {
|
|
6
|
+
import { restoreCapabilityApprovalGroup } from "../orchestration/worker-capabilities/execution/approval-group.js";
|
|
6
7
|
import { createRoleApprovalContinuation, validateRequestApprovalContinuation, } from "./approval-continuation.js";
|
|
7
8
|
import { createRoleCallLedger, resolveRoleCallTransactions, } from "../orchestration/role-calls/index.js";
|
|
8
9
|
import { traceDebug } from "../observability/debug-logger.js";
|
|
@@ -26,8 +27,10 @@ export async function runRequestRunner(request, options = {}) {
|
|
|
26
27
|
}
|
|
27
28
|
: {}),
|
|
28
29
|
});
|
|
30
|
+
const initialMemory = await prepareInitialMemory(request, options.continuation?.ledger.state.initialMemory);
|
|
29
31
|
const ledger = createRoleCallLedger({
|
|
30
32
|
requestId: request.requestId,
|
|
33
|
+
...(initialMemory !== undefined ? { initialMemory } : {}),
|
|
31
34
|
...(options.continuation
|
|
32
35
|
? { checkpoint: options.continuation.ledger }
|
|
33
36
|
: {}),
|
|
@@ -42,15 +45,18 @@ export async function runRequestRunner(request, options = {}) {
|
|
|
42
45
|
let continuation;
|
|
43
46
|
if (options.continuation) {
|
|
44
47
|
validateRequestApprovalContinuation(options.continuation, ledger, request.workerCapabilities.provider.getDescriptors());
|
|
48
|
+
request.abortSignal.throwIfAborted();
|
|
45
49
|
const executionFreshness = restoreApprovalExecutionFreshness(options.continuation.preparedGroup.executionFreshnessToken, request.requestSteering);
|
|
46
|
-
const
|
|
50
|
+
const prepared = await restoreCapabilityApprovalGroup({
|
|
47
51
|
...(executionFreshness ? { executionFreshness } : {}),
|
|
48
52
|
ledger,
|
|
49
53
|
context: request.workerCapabilities.executionContext,
|
|
50
54
|
adapters: request.workerCapabilities.provider.getAdapters(),
|
|
51
55
|
group: options.continuation.preparedGroup,
|
|
52
|
-
decisions: options.decisions ?? [],
|
|
53
56
|
});
|
|
57
|
+
request.abortSignal.throwIfAborted();
|
|
58
|
+
restoreApprovalExecutionFreshness(options.continuation.preparedGroup.executionFreshnessToken, request.requestSteering);
|
|
59
|
+
const settled = await prepared.execute(options.decisions ?? []);
|
|
54
60
|
continuation = createRoleApprovalContinuation(options.continuation, settled.executionIds);
|
|
55
61
|
}
|
|
56
62
|
else {
|
|
@@ -17,6 +17,9 @@ export const SUPERVISOR_ROOT_CONTRACT = Object.freeze({
|
|
|
17
17
|
includeTitle: options.includeTitle,
|
|
18
18
|
allowedRoleIds: options.allowedRoleIds,
|
|
19
19
|
availableWorkerCapabilityCatalog: options.availableWorkerCapabilityCatalog,
|
|
20
|
+
...(options.head.state.initialMemory?.message
|
|
21
|
+
? { initialMemoryMessage: options.head.state.initialMemory.message }
|
|
22
|
+
: {}),
|
|
20
23
|
...(options.memoryRecallMessage
|
|
21
24
|
? { memoryRecallMessage: options.memoryRecallMessage }
|
|
22
25
|
: {}),
|
|
@@ -28,6 +31,9 @@ export const SUPERVISOR_ROOT_CONTRACT = Object.freeze({
|
|
|
28
31
|
responseRecommendation: options.responseRecommendation,
|
|
29
32
|
call: options.call,
|
|
30
33
|
toolResults: options.toolResults,
|
|
34
|
+
...(options.head.state.initialMemory?.message
|
|
35
|
+
? { initialMemoryMessage: options.head.state.initialMemory.message }
|
|
36
|
+
: {}),
|
|
31
37
|
...(options.memoryRecallMessage
|
|
32
38
|
? { memoryRecallMessage: options.memoryRecallMessage }
|
|
33
39
|
: {}),
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { MemoryRecallDecision } from "../memory-recall-decision.js";
|
|
2
|
+
import type { MemoryCandidate } from "../../long-term-memory/contracts.js";
|
|
3
|
+
import type { ConversationMemoryAuthoringContext } from "../../long-term-memory/conversation-authoring/context.js";
|
|
2
4
|
import type { ExecutionWorkPlanOptions, ExecutionWorkPlanReport } from "./work-plan-contract.js";
|
|
3
5
|
import type { RoleCapabilitySelectionProjection, RoleCapabilitySelectionReconsiderationCause } from "../../orchestration/role-calls/index.js";
|
|
4
6
|
import { type CapabilityControls, type CapabilityDescriptor } from "../../orchestration/capability-adapters/index.js";
|
|
@@ -21,6 +23,10 @@ export type ExecutionAgentDecisionPresentation = Readonly<{
|
|
|
21
23
|
}>;
|
|
22
24
|
export type ExecutionAgentRespondDecision = Readonly<ExecutionAgentDecisionPresentation & {
|
|
23
25
|
action: "respond";
|
|
26
|
+
/** Exact prevalidated short answer; absent keeps separate presentation. */
|
|
27
|
+
response?: string;
|
|
28
|
+
/** Assessed proposals bound to the same accepted direct response. */
|
|
29
|
+
memoryCandidates?: readonly MemoryCandidate[];
|
|
24
30
|
}>;
|
|
25
31
|
export type ExecutionAgentOpenCapabilityScopeDecision = Readonly<ExecutionAgentDecisionPresentation & {
|
|
26
32
|
action: "open_capability_scope";
|
|
@@ -113,6 +119,10 @@ export type ExecutionAgentDecisionContractOptions = Readonly<{
|
|
|
113
119
|
includeAcknowledgement?: boolean;
|
|
114
120
|
includeTitle?: boolean;
|
|
115
121
|
allowRespond?: boolean;
|
|
122
|
+
directResponseMaxLength?: number;
|
|
123
|
+
directResponseMemoryAuthoring?: Readonly<{
|
|
124
|
+
context?: ConversationMemoryAuthoringContext;
|
|
125
|
+
}>;
|
|
116
126
|
allowMemoryRecall?: boolean;
|
|
117
127
|
allowPlanner?: boolean;
|
|
118
128
|
allowAuditor?: boolean;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { parseDirectResponse, parseDirectResponseMemoryCandidates, } from "./direct-response-contract.js";
|
|
1
2
|
import { readStructuredDecisionEnvelope } from "../../model/structured-decision-envelope.js";
|
|
2
3
|
import { parseDecisionWithWorkPlan } from "./work-plan-decision-parsing.js";
|
|
3
4
|
import { isMemoryRecallDecisionRecord, parseMemoryRecallDecision, } from "../memory-recall-decision.js";
|
|
@@ -62,12 +63,23 @@ function parseExecutionAgentActionOutput(text, options) {
|
|
|
62
63
|
}
|
|
63
64
|
}
|
|
64
65
|
else if (selectedAction === "respond") {
|
|
65
|
-
|
|
66
|
+
const response = parseDirectResponse(record, options.directResponseMaxLength, issues);
|
|
67
|
+
const memoryCandidates = response !== undefined
|
|
68
|
+
? parseDirectResponseMemoryCandidates(record, options.directResponseMemoryAuthoring)
|
|
69
|
+
: undefined;
|
|
70
|
+
exactKeys(record, [
|
|
71
|
+
"action",
|
|
72
|
+
...(response !== undefined ? ["response"] : []),
|
|
73
|
+
...(memoryCandidates !== undefined ? ["memoryCandidates"] : []),
|
|
74
|
+
...presentationKeys(contract),
|
|
75
|
+
], issues, "decision");
|
|
66
76
|
if (!contract.allowRespond) {
|
|
67
77
|
issues.push(issue("execution_agent_response_not_allowed", "decision.action", "respond is not available until the canonical completion gate is open."));
|
|
68
78
|
}
|
|
69
79
|
decision = {
|
|
70
80
|
action: "respond",
|
|
81
|
+
...(response !== undefined ? { response } : {}),
|
|
82
|
+
...(memoryCandidates !== undefined ? { memoryCandidates } : {}),
|
|
71
83
|
...presentation,
|
|
72
84
|
};
|
|
73
85
|
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import type { RequestExecutionScope } from "../../request/execution-scope.js";
|
|
2
|
+
/** Preserve a separately configured response model/calibration instead of silently bypassing it. */
|
|
3
|
+
export declare function hasCompatibleDirectResponseConfiguration(request: RequestExecutionScope): boolean;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { isDeepStrictEqual } from "node:util";
|
|
2
|
+
import { resolveModelInvocation } from "../../../model-gateway/invocation-policy.js";
|
|
3
|
+
import { resolveModelStepTimeout } from "../../model/model-step-timeout-policy.js";
|
|
4
|
+
import { EXECUTION_AGENT_DECISION_MODEL_STEP, EXECUTION_AGENT_RESPONSE_MODEL_STEP, } from "./contracts.js";
|
|
5
|
+
/** Preserve a separately configured response model/calibration instead of silently bypassing it. */
|
|
6
|
+
export function hasCompatibleDirectResponseConfiguration(request) {
|
|
7
|
+
try {
|
|
8
|
+
const decision = effectiveConfiguration(request, EXECUTION_AGENT_DECISION_MODEL_STEP);
|
|
9
|
+
const response = effectiveConfiguration(request, EXECUTION_AGENT_RESPONSE_MODEL_STEP);
|
|
10
|
+
if (!decision || !response)
|
|
11
|
+
return false;
|
|
12
|
+
return isDeepStrictEqual(decision, response);
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
// Resolution failures keep the existing deferred path and its diagnostics.
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function effectiveConfiguration(request, modelStep) {
|
|
20
|
+
const step = request.runnerConfig.steps[modelStep];
|
|
21
|
+
if (!step)
|
|
22
|
+
return undefined;
|
|
23
|
+
const invocation = resolveModelInvocation({
|
|
24
|
+
modelStep,
|
|
25
|
+
agentMode: request.agentMode,
|
|
26
|
+
...(request.modelPreference
|
|
27
|
+
? { modelPreference: request.modelPreference }
|
|
28
|
+
: {}),
|
|
29
|
+
...(request.modelPolicy ? { modelPolicy: request.modelPolicy } : {}),
|
|
30
|
+
});
|
|
31
|
+
if (hasSpecialResponseFormat(modelStep, invocation.format))
|
|
32
|
+
return undefined;
|
|
33
|
+
const { profile } = invocation;
|
|
34
|
+
return {
|
|
35
|
+
profileId: profile.id,
|
|
36
|
+
providerId: profile.providerId,
|
|
37
|
+
provider: profile.provider,
|
|
38
|
+
model: profile.model,
|
|
39
|
+
contextWindowTokens: profile.contextWindowTokens,
|
|
40
|
+
capabilities: profile.capabilities,
|
|
41
|
+
options: profile.options,
|
|
42
|
+
generation: profile.generation,
|
|
43
|
+
context: profile.context,
|
|
44
|
+
think: invocation.think,
|
|
45
|
+
instructions: invocation.instructions ?? [],
|
|
46
|
+
timeoutMs: resolveModelStepTimeout({
|
|
47
|
+
modelStep,
|
|
48
|
+
fallbackTimeoutMs: step.timeoutMs,
|
|
49
|
+
...(request.modelPreference
|
|
50
|
+
? { modelPreference: request.modelPreference }
|
|
51
|
+
: {}),
|
|
52
|
+
...(request.modelPolicy ? { modelPolicy: request.modelPolicy } : {}),
|
|
53
|
+
}).timeoutMs,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function hasSpecialResponseFormat(modelStep, format) {
|
|
57
|
+
if (modelStep !== EXECUTION_AGENT_RESPONSE_MODEL_STEP)
|
|
58
|
+
return false;
|
|
59
|
+
if (format === undefined)
|
|
60
|
+
return false;
|
|
61
|
+
if (format && typeof format === "object" && "type" in format)
|
|
62
|
+
return format.type !== "text";
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ExecutionAgentDecisionContractOptions, ExecutionAgentDecisionValidationIssue } from "./contracts.js";
|
|
2
|
+
import type { MemoryCandidate } from "../../long-term-memory/contracts.js";
|
|
3
|
+
/** A short-answer option, not a conversion from characters to model tokens. */
|
|
4
|
+
export declare const EXECUTION_AGENT_DIRECT_RESPONSE_MAX_LENGTH = 1024;
|
|
5
|
+
export declare function directResponseVariants(maxLength: number | undefined, presentation: Record<string, unknown>, memoryAuthoring?: boolean): Record<string, unknown>[];
|
|
6
|
+
export declare function parseDirectResponse(record: Record<string, unknown>, maxLength: number | undefined, issues: ExecutionAgentDecisionValidationIssue[]): string | undefined;
|
|
7
|
+
export declare function parseDirectResponseMemoryCandidates(record: Record<string, unknown>, authoring: ExecutionAgentDecisionContractOptions["directResponseMemoryAuthoring"]): readonly MemoryCandidate[] | undefined;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { conversationMemoryCandidatesSchema, parseConversationMemoryCandidates, } from "../../long-term-memory/conversation-authoring/contract.js";
|
|
2
|
+
import { issue } from "./decision-validation.js";
|
|
3
|
+
/** A short-answer option, not a conversion from characters to model tokens. */
|
|
4
|
+
export const EXECUTION_AGENT_DIRECT_RESPONSE_MAX_LENGTH = 1_024;
|
|
5
|
+
export function directResponseVariants(maxLength, presentation, memoryAuthoring = false) {
|
|
6
|
+
if (!isDirectResponseLimit(maxLength))
|
|
7
|
+
return [];
|
|
8
|
+
return [
|
|
9
|
+
{
|
|
10
|
+
type: "object",
|
|
11
|
+
additionalProperties: false,
|
|
12
|
+
properties: {
|
|
13
|
+
action: { type: "string", enum: ["respond"] },
|
|
14
|
+
response: { type: "string", minLength: 1, maxLength },
|
|
15
|
+
...(memoryAuthoring
|
|
16
|
+
? { memoryCandidates: conversationMemoryCandidatesSchema }
|
|
17
|
+
: {}),
|
|
18
|
+
...presentation,
|
|
19
|
+
},
|
|
20
|
+
required: [
|
|
21
|
+
"action", "response",
|
|
22
|
+
...(memoryAuthoring ? ["memoryCandidates"] : []),
|
|
23
|
+
...Object.keys(presentation),
|
|
24
|
+
],
|
|
25
|
+
},
|
|
26
|
+
];
|
|
27
|
+
}
|
|
28
|
+
export function parseDirectResponse(record, maxLength, issues) {
|
|
29
|
+
if (!Object.hasOwn(record, "response"))
|
|
30
|
+
return undefined;
|
|
31
|
+
if (!isDirectResponseLimit(maxLength)) {
|
|
32
|
+
issues.push(issue("execution_agent_direct_response_unavailable", "decision.response", "This request requires the separate response authoring step."));
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
const response = record.response;
|
|
36
|
+
if (typeof response !== "string" || response.trim().length === 0) {
|
|
37
|
+
issues.push(issue("execution_agent_direct_response_invalid", "decision.response", "A direct response must contain the complete non-empty answer."));
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
if (response.length > maxLength) {
|
|
41
|
+
issues.push(issue("execution_agent_direct_response_too_long", "decision.response", `A direct response must fit ${maxLength} characters. Choose respond without response for a longer complete answer; do not shorten or truncate it.`));
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
return response;
|
|
45
|
+
}
|
|
46
|
+
export function parseDirectResponseMemoryCandidates(record, authoring) {
|
|
47
|
+
if (!authoring)
|
|
48
|
+
return undefined;
|
|
49
|
+
return parseConversationMemoryCandidates(record.memoryCandidates, authoring.context);
|
|
50
|
+
}
|
|
51
|
+
function isDirectResponseLimit(value) {
|
|
52
|
+
return (value !== undefined &&
|
|
53
|
+
Number.isInteger(value) &&
|
|
54
|
+
value > 0 &&
|
|
55
|
+
value <= EXECUTION_AGENT_DIRECT_RESPONSE_MAX_LENGTH);
|
|
56
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { RoleCallFrame, RoleCallLedgerHead } from "../../orchestration/role-calls/index.js";
|
|
2
|
+
import type { RequestExecutionScope } from "../../request/execution-scope.js";
|
|
3
|
+
import type { ExecutionMemoryProjection } from "../../long-term-memory/initial-context.js";
|
|
4
|
+
/** Request-local offer only; neither prompt classification nor permission to omit required work. */
|
|
5
|
+
export declare function resolveDirectResponseOffer(request: RequestExecutionScope, head: RoleCallLedgerHead, call: RoleCallFrame): Readonly<{
|
|
6
|
+
reason: string;
|
|
7
|
+
maxLength?: number;
|
|
8
|
+
}>;
|
|
9
|
+
export declare function canAuthorDirectResponseMemory(maxLength: number | undefined, memory: ExecutionMemoryProjection | undefined): memory is ExecutionMemoryProjection;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { EXECUTION_AGENT_DIRECT_RESPONSE_MAX_LENGTH } from "./direct-response-contract.js";
|
|
2
|
+
import { hasCompatibleDirectResponseConfiguration } from "./direct-response-configuration.js";
|
|
3
|
+
/** Request-local offer only; neither prompt classification nor permission to omit required work. */
|
|
4
|
+
export function resolveDirectResponseOffer(request, head, call) {
|
|
5
|
+
if (request.automationOutputContract)
|
|
6
|
+
return { reason: "automation_output_contract" };
|
|
7
|
+
if (request.scheduledExecution)
|
|
8
|
+
return { reason: "scheduled_execution" };
|
|
9
|
+
if (request.sessionKind === "spark")
|
|
10
|
+
return { reason: "spark_session" };
|
|
11
|
+
if (head.state.capabilityExecutions.length > 0)
|
|
12
|
+
return { reason: "capability_work" };
|
|
13
|
+
if (head.state.calls.length !== 1)
|
|
14
|
+
return { reason: "delegated_work" };
|
|
15
|
+
if (head.state.results.length > 0)
|
|
16
|
+
return { reason: "subordinate_results" };
|
|
17
|
+
if (call.adoptedWorkPlan)
|
|
18
|
+
return { reason: "work_plan" };
|
|
19
|
+
if (!hasCompatibleDirectResponseConfiguration(request))
|
|
20
|
+
return { reason: "response_configuration" };
|
|
21
|
+
return {
|
|
22
|
+
reason: "eligible",
|
|
23
|
+
maxLength: Math.min(EXECUTION_AGENT_DIRECT_RESPONSE_MAX_LENGTH, head.policy.limits.maxResponseChars),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export function canAuthorDirectResponseMemory(maxLength, memory) {
|
|
27
|
+
if (maxLength === undefined)
|
|
28
|
+
return false;
|
|
29
|
+
return memory?.authoringEnabled === true;
|
|
30
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { RequestRunnerConfig } from "../../config/runner/contracts.js";
|
|
2
|
+
/** Presentation guidance applies only to the optional final-answer field, never to routing. */
|
|
3
|
+
export declare function buildDirectResponseInstructions(maxLength: number | undefined, runnerConfig: RequestRunnerConfig, memoryAuthoringEnabled?: boolean): readonly string[];
|
|
4
|
+
export declare function buildRespondDecisionInstruction(params: {
|
|
5
|
+
allowRespond: boolean;
|
|
6
|
+
allowDirectResponse?: boolean;
|
|
7
|
+
}): string;
|