@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.
Files changed (119) hide show
  1. package/README.md +216 -222
  2. package/dist/src/capabilities/tool-definition-validator/definition-parser.js +8 -0
  3. package/dist/src/capabilities/tool-types.d.ts +4 -0
  4. package/dist/src/model-gateway/protocol/message-contract.d.ts +1 -0
  5. package/dist/src/model-gateway/protocol/message-contract.js +1 -1
  6. package/dist/src/model-gateway/server/chat-handler.js +5 -7
  7. package/dist/src/model-gateway/server/chat-stream-response.d.ts +7 -0
  8. package/dist/src/model-gateway/server/chat-stream-response.js +25 -0
  9. package/dist/src/runtime/adapters/registered-tool-worker-capabilities/payload-rejection.d.ts +2 -2
  10. package/dist/src/runtime/adapters/registered-tool-worker-capabilities/payload-rejection.js +2 -2
  11. package/dist/src/runtime/adapters/registered-tool-worker-capabilities/prepared-execution.js +17 -11
  12. package/dist/src/runtime/capabilities/tool-availability.js +6 -0
  13. package/dist/src/runtime/context/capability-brief.d.ts +2 -2
  14. package/dist/src/runtime/context/capability-brief.js +3 -3
  15. package/dist/src/runtime/context/capability-descriptions.d.ts +3 -2
  16. package/dist/src/runtime/context/capability-descriptions.js +57 -20
  17. package/dist/src/runtime/long-term-memory/conversation-authoring/context.d.ts +6 -1
  18. package/dist/src/runtime/long-term-memory/conversation-authoring/context.js +51 -25
  19. package/dist/src/runtime/long-term-memory/initial-context.d.ts +17 -0
  20. package/dist/src/runtime/long-term-memory/initial-context.js +57 -0
  21. package/dist/src/runtime/long-term-memory/projection.js +1 -1
  22. package/dist/src/runtime/orchestration/role-calls/candidate-validation.js +2 -1
  23. package/dist/src/runtime/orchestration/role-calls/checkpoint-state.d.ts +1 -1
  24. package/dist/src/runtime/orchestration/role-calls/checkpoint-state.js +5 -2
  25. package/dist/src/runtime/orchestration/role-calls/contracts.d.ts +2 -1
  26. package/dist/src/runtime/orchestration/role-calls/ledger.d.ts +2 -1
  27. package/dist/src/runtime/orchestration/role-calls/ledger.js +2 -2
  28. package/dist/src/runtime/orchestration/role-calls/memory-recall-contract.d.ts +7 -0
  29. package/dist/src/runtime/orchestration/role-calls/memory-recall-state-validation.d.ts +2 -0
  30. package/dist/src/runtime/orchestration/role-calls/memory-recall-state-validation.js +88 -0
  31. package/dist/src/runtime/orchestration/role-calls/reducer.d.ts +1 -1
  32. package/dist/src/runtime/orchestration/role-calls/reducer.js +2 -1
  33. package/dist/src/runtime/orchestration/worker-capabilities/contracts.d.ts +3 -1
  34. package/dist/src/runtime/orchestration/worker-capabilities/contracts.js +1 -1
  35. package/dist/src/runtime/orchestration/worker-capabilities/execution/approval-group.js +5 -1
  36. package/dist/src/runtime/orchestration/worker-capabilities/execution/execution-freshness.d.ts +5 -0
  37. package/dist/src/runtime/orchestration/worker-capabilities/execution/execution-freshness.js +31 -0
  38. package/dist/src/runtime/plugins/manifest-projection.js +3 -0
  39. package/dist/src/runtime/request/capability-execution-freshness.js +6 -1
  40. package/dist/src/runtime/request/execution-agent-root-execution.js +11 -1
  41. package/dist/src/runtime/request/root-contract.d.ts +2 -0
  42. package/dist/src/runtime/request/root-execution-kernel.js +1 -0
  43. package/dist/src/runtime/request/runner.js +9 -3
  44. package/dist/src/runtime/request/supervisor-root-execution.js +6 -0
  45. package/dist/src/runtime/steps/execution-agent/contracts.d.ts +10 -0
  46. package/dist/src/runtime/steps/execution-agent/decision-parsing.js +13 -1
  47. package/dist/src/runtime/steps/execution-agent/direct-response-configuration.d.ts +3 -0
  48. package/dist/src/runtime/steps/execution-agent/direct-response-configuration.js +64 -0
  49. package/dist/src/runtime/steps/execution-agent/direct-response-contract.d.ts +7 -0
  50. package/dist/src/runtime/steps/execution-agent/direct-response-contract.js +56 -0
  51. package/dist/src/runtime/steps/execution-agent/direct-response-policy.d.ts +9 -0
  52. package/dist/src/runtime/steps/execution-agent/direct-response-policy.js +30 -0
  53. package/dist/src/runtime/steps/execution-agent/direct-response-prompt.d.ts +7 -0
  54. package/dist/src/runtime/steps/execution-agent/direct-response-prompt.js +43 -0
  55. package/dist/src/runtime/steps/execution-agent/format.js +2 -0
  56. package/dist/src/runtime/steps/execution-agent/input.d.ts +2 -0
  57. package/dist/src/runtime/steps/execution-agent/input.js +22 -1
  58. package/dist/src/runtime/steps/execution-agent/plugin-catalog.d.ts +4 -0
  59. package/dist/src/runtime/steps/execution-agent/plugin-catalog.js +8 -0
  60. package/dist/src/runtime/steps/execution-agent/prompt.d.ts +1 -0
  61. package/dist/src/runtime/steps/execution-agent/prompt.js +3 -4
  62. package/dist/src/runtime/steps/execution-agent/response-run.js +5 -11
  63. package/dist/src/runtime/steps/execution-agent/run.js +4 -1
  64. package/dist/src/runtime/steps/execution-agent/state-context.d.ts +2 -3
  65. package/dist/src/runtime/steps/execution-agent/state-context.js +2 -39
  66. package/dist/src/runtime/steps/planner-decision/capability-brief.d.ts +2 -0
  67. package/dist/src/runtime/steps/planner-decision/prompt.js +26 -49
  68. package/dist/src/runtime/steps/supervisor-decision/input.d.ts +1 -0
  69. package/dist/src/runtime/steps/supervisor-decision/input.js +5 -0
  70. package/dist/src/runtime/steps/supervisor-decision/prompt.d.ts +1 -0
  71. package/dist/src/runtime/steps/supervisor-decision/prompt.js +6 -2
  72. package/dist/src/runtime/steps/supervisor-decision/run.d.ts +1 -0
  73. package/dist/src/runtime/steps/supervisor-decision/run.js +4 -0
  74. package/dist/src/runtime/steps/supervisor-response/run.d.ts +2 -0
  75. package/dist/src/runtime/steps/supervisor-response/run.js +3 -6
  76. package/dist/src/web-ui/app/ARCHITECTURE.md +1 -1
  77. package/dist/src/web-ui/app/app.js +1 -0
  78. package/dist/src/web-ui/app/components/automations/timeline.js +3 -2
  79. package/dist/src/web-ui/app/components/dashboard/compact-layout.js +137 -0
  80. package/dist/src/web-ui/app/components/dashboard/icons.js +5 -0
  81. package/dist/src/web-ui/app/components/dashboard/widget-card.js +85 -0
  82. package/dist/src/web-ui/app/components/dashboard/widget-dialog.js +83 -0
  83. package/dist/src/web-ui/app/components/dashboard/widget-summaries.js +155 -0
  84. package/dist/src/web-ui/app/components/dashboard/workspace.js +28 -4
  85. package/dist/src/web-ui/app/components/operations-summary.js +2 -1
  86. package/dist/src/web-ui/app/components/passive-learning/home-widget-preview.js +32 -0
  87. package/dist/src/web-ui/app/components/passive-learning/home.js +4 -1
  88. package/dist/src/web-ui/app/components/schedules/details.js +3 -2
  89. package/dist/src/web-ui/app/components/spark-chat/panel.js +1 -1
  90. package/dist/src/web-ui/app/components/spark-chat/settings.js +1 -1
  91. package/dist/src/web-ui/app/components/system-host/home-widget-permission-preview.js +75 -0
  92. package/dist/src/web-ui/app/components/system-host/home-widget-summary.js +93 -0
  93. package/dist/src/web-ui/app/components/system-host/macos-permission-rendering.js +2 -2
  94. package/dist/src/web-ui/app/components/system-host/native-windows-access.js +1 -1
  95. package/dist/src/web-ui/app/components/system-host/rendering.js +3 -3
  96. package/dist/src/web-ui/app/components/system-host/windows-store-setup.js +2 -2
  97. package/dist/src/web-ui/app/computer-access-feature.js +13 -1
  98. package/dist/src/web-ui/app/configuration-feature.js +2 -0
  99. package/dist/src/web-ui/app/controllers/operations-controller.js +2 -1
  100. package/dist/src/web-ui/app/controllers/reasoning-mode-controller.js +1 -1
  101. package/dist/src/web-ui/app/dashboard-feature.js +9 -0
  102. package/dist/src/web-ui/app/lib/reasoning-controls.js +6 -1
  103. package/dist/src/web-ui/app/passive-learning-feature.js +2 -2
  104. package/dist/src/web-ui/app/styles/95-home-widgets.css +109 -0
  105. package/dist/src/web-ui/app/styles.css +1 -0
  106. package/docs/plugins.md +37 -32
  107. package/package.json +1 -1
  108. package/plugins/capability-brief/plugin.json +1 -1
  109. package/plugins/code-outline/plugin.json +1 -1
  110. package/plugins/document-reader/plugin.json +1 -1
  111. package/plugins/exec/plugin.json +1 -1
  112. package/plugins/filesystem/plugin.json +1 -1
  113. package/plugins/json-inspector/plugin.json +1 -1
  114. package/plugins/local-search/plugin.json +1 -1
  115. package/plugins/memory/plugin.json +1 -1
  116. package/plugins/project-orientation/plugin.json +1 -1
  117. package/plugins/system/plugin.json +1 -1
  118. package/plugins/system-probe/plugin.json +1 -1
  119. 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, } from "../../../capabilities/normal-invocation/contracts.js";
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, } from "../../../capabilities/normal-invocation/contracts.js";
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
- if (!current.isCurrent())
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({ action: "respond", ...presentation });
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 { resumeCapabilityApprovalGroup } from "../orchestration/worker-capabilities/execution/approval-group.js";
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 settled = await resumeCapabilityApprovalGroup({
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
- exactKeys(record, ["action", ...presentationKeys(contract)], issues, "decision");
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;