@botbotgo/agent-harness 0.0.298 → 0.0.299

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 (166) hide show
  1. package/README.md +77 -37
  2. package/README.zh.md +79 -30
  3. package/dist/acp.d.ts +3 -0
  4. package/dist/acp.js +10 -2
  5. package/dist/api.d.ts +14 -2
  6. package/dist/api.js +19 -3
  7. package/dist/cli.d.ts +18 -1
  8. package/dist/cli.js +1408 -319
  9. package/dist/client/acp.d.ts +9 -3
  10. package/dist/client/acp.js +55 -1
  11. package/dist/client/in-process.d.ts +5 -2
  12. package/dist/client/in-process.js +4 -6
  13. package/dist/client/index.d.ts +1 -1
  14. package/dist/client/types.d.ts +6 -5
  15. package/dist/config/agents/direct.yaml +7 -17
  16. package/dist/config/agents/orchestra.yaml +9 -65
  17. package/dist/config/catalogs/embedding-models.yaml +1 -1
  18. package/dist/config/catalogs/stores.yaml +1 -1
  19. package/dist/config/knowledge/knowledge-runtime.yaml +36 -2
  20. package/dist/config/knowledge/procedural-memory-runtime.yaml +78 -0
  21. package/dist/config/{catalogs/models.yaml → models.yaml} +2 -2
  22. package/dist/config/prompts/direct-system.md +16 -0
  23. package/dist/config/prompts/orchestra-system.md +62 -0
  24. package/dist/config/prompts/routing-system.md +14 -0
  25. package/dist/config/runtime/runtime-memory.yaml +39 -5
  26. package/dist/config/runtime/workspace.yaml +7 -16
  27. package/dist/contracts/runtime.d.ts +242 -1
  28. package/dist/contracts/workspace.d.ts +2 -0
  29. package/dist/index.d.ts +5 -3
  30. package/dist/index.js +2 -1
  31. package/dist/init-project.js +178 -33
  32. package/dist/knowledge/contracts.d.ts +5 -0
  33. package/dist/knowledge/module.d.ts +5 -0
  34. package/dist/knowledge/module.js +340 -18
  35. package/dist/package-version.d.ts +1 -1
  36. package/dist/package-version.js +1 -1
  37. package/dist/persistence/file-store.d.ts +5 -1
  38. package/dist/persistence/file-store.js +16 -0
  39. package/dist/persistence/sqlite-store.d.ts +4 -1
  40. package/dist/persistence/sqlite-store.js +88 -14
  41. package/dist/persistence/types.d.ts +4 -1
  42. package/dist/procedural/config.d.ts +63 -0
  43. package/dist/procedural/config.js +125 -0
  44. package/dist/procedural/index.d.ts +2 -0
  45. package/dist/procedural/index.js +1 -0
  46. package/dist/protocol/ag-ui/http.d.ts +3 -0
  47. package/dist/protocol/ag-ui/http.js +10 -0
  48. package/dist/request-events.d.ts +63 -0
  49. package/dist/request-events.js +400 -0
  50. package/dist/resource/isolation.js +11 -0
  51. package/dist/resource/resource-impl.d.ts +1 -0
  52. package/dist/resource/resource-impl.js +103 -12
  53. package/dist/resources/init-templates/agent-context/deep-research.md +5 -0
  54. package/dist/resources/init-templates/prompts/research-analyst-basic.md +1 -0
  55. package/dist/resources/init-templates/prompts/research-analyst-web-search.md +1 -0
  56. package/dist/resources/init-templates/prompts/research-host-deep-research-basic.md +1 -0
  57. package/dist/resources/init-templates/prompts/research-host-deep-research-web-search.md +1 -0
  58. package/dist/resources/init-templates/prompts/research-host-single-agent-basic.md +1 -0
  59. package/dist/resources/init-templates/prompts/research-host-single-agent-web-search.md +1 -0
  60. package/dist/resources/prompts/runtime/browser-capability-disclaimer-recovery.md +1 -0
  61. package/dist/resources/prompts/runtime/default-subagent.md +2 -0
  62. package/dist/resources/prompts/runtime/durable-memory-context.md +7 -0
  63. package/dist/resources/prompts/runtime/execution-with-tool-evidence-retry.md +1 -0
  64. package/dist/resources/prompts/runtime/execution-with-tool-evidence.md +1 -0
  65. package/dist/resources/prompts/runtime/invalid-tool-selection-recovery.md +1 -0
  66. package/dist/resources/prompts/runtime/memory-manager.md +31 -0
  67. package/dist/resources/prompts/runtime/memory-mutation-reconciliation.md +22 -0
  68. package/dist/resources/prompts/runtime/slash-command-skill.md +6 -0
  69. package/dist/resources/prompts/runtime/strict-tool-json.md +1 -0
  70. package/dist/resources/prompts/runtime/workspace-boundary-guidance.md +3 -0
  71. package/dist/resources/prompts/runtime/workspace-relative-path.md +1 -0
  72. package/dist/resources/prompts/runtime/write-todos-descriptive-content.md +1 -0
  73. package/dist/resources/prompts/runtime/write-todos-full-entry.md +1 -0
  74. package/dist/resources/prompts/runtime/write-todos-non-empty-initial-list.md +1 -0
  75. package/dist/resources/tools/_runtime_tool_helpers.mjs +152 -0
  76. package/dist/resources/tools/cancel_request.mjs +21 -0
  77. package/dist/resources/tools/fetch_url.mjs +23 -0
  78. package/dist/resources/tools/http_request.mjs +30 -0
  79. package/dist/resources/tools/inspect_approvals.mjs +27 -0
  80. package/dist/resources/tools/inspect_artifacts.mjs +21 -0
  81. package/dist/resources/tools/inspect_events.mjs +21 -0
  82. package/dist/resources/tools/inspect_requests.mjs +27 -0
  83. package/dist/resources/tools/inspect_sessions.mjs +21 -0
  84. package/dist/resources/tools/list_files.mjs +27 -0
  85. package/dist/resources/tools/read_artifact.mjs +22 -0
  86. package/dist/resources/tools/request_approval.mjs +27 -0
  87. package/dist/resources/tools/run_command.mjs +21 -0
  88. package/dist/resources/tools/schedule_task.mjs +76 -0
  89. package/dist/resources/tools/search_files.mjs +47 -0
  90. package/dist/resources/tools/send_message.mjs +23 -0
  91. package/dist/runtime/adapter/direct-builtin-utility.d.ts +1 -0
  92. package/dist/runtime/adapter/direct-builtin-utility.js +90 -0
  93. package/dist/runtime/adapter/flow/execution-context.d.ts +1 -1
  94. package/dist/runtime/adapter/flow/execution-context.js +1 -1
  95. package/dist/runtime/adapter/flow/invocation-flow.d.ts +1 -0
  96. package/dist/runtime/adapter/flow/invocation-flow.js +9 -1
  97. package/dist/runtime/adapter/flow/invoke-runtime.d.ts +1 -1
  98. package/dist/runtime/adapter/flow/stream-runtime.d.ts +5 -1
  99. package/dist/runtime/adapter/flow/stream-runtime.js +556 -35
  100. package/dist/runtime/adapter/invocation-result.js +3 -2
  101. package/dist/runtime/adapter/local-tool-invocation.d.ts +1 -1
  102. package/dist/runtime/adapter/local-tool-invocation.js +28 -4
  103. package/dist/runtime/adapter/middleware-assembly.js +3 -1
  104. package/dist/runtime/adapter/model/invocation-request.d.ts +4 -1
  105. package/dist/runtime/adapter/model/invocation-request.js +138 -16
  106. package/dist/runtime/adapter/model/message-assembly.js +2 -6
  107. package/dist/runtime/adapter/model/model-providers.js +103 -5
  108. package/dist/runtime/adapter/resilience.js +17 -2
  109. package/dist/runtime/adapter/runtime-adapter-support.d.ts +11 -7
  110. package/dist/runtime/adapter/runtime-adapter-support.js +39 -5
  111. package/dist/runtime/adapter/tool/builtin-middleware-tools.d.ts +63 -1
  112. package/dist/runtime/adapter/tool/builtin-middleware-tools.js +193 -21
  113. package/dist/runtime/adapter/tool/tool-arguments.d.ts +3 -1
  114. package/dist/runtime/adapter/tool/tool-arguments.js +52 -17
  115. package/dist/runtime/adapter/tool-resolution.d.ts +1 -0
  116. package/dist/runtime/adapter/tool-resolution.js +4 -2
  117. package/dist/runtime/agent-runtime-adapter.d.ts +27 -0
  118. package/dist/runtime/agent-runtime-adapter.js +163 -11
  119. package/dist/runtime/harness/events/event-bus.d.ts +1 -0
  120. package/dist/runtime/harness/events/event-bus.js +3 -0
  121. package/dist/runtime/harness/events/event-sink.d.ts +3 -0
  122. package/dist/runtime/harness/events/event-sink.js +16 -7
  123. package/dist/runtime/harness/events/streaming.d.ts +18 -1
  124. package/dist/runtime/harness/events/streaming.js +23 -10
  125. package/dist/runtime/harness/run/inspection.js +26 -5
  126. package/dist/runtime/harness/run/stream-run.d.ts +13 -4
  127. package/dist/runtime/harness/run/stream-run.js +448 -4
  128. package/dist/runtime/harness/run/surface-semantics.js +7 -34
  129. package/dist/runtime/harness/system/runtime-memory-manager.d.ts +3 -0
  130. package/dist/runtime/harness/system/runtime-memory-manager.js +384 -69
  131. package/dist/runtime/harness/system/runtime-memory-policy.d.ts +20 -1
  132. package/dist/runtime/harness/system/runtime-memory-policy.js +65 -17
  133. package/dist/runtime/harness/system/runtime-memory-records.js +100 -0
  134. package/dist/runtime/harness/system/runtime-memory-sync.js +2 -2
  135. package/dist/runtime/harness/system/store.d.ts +4 -0
  136. package/dist/runtime/harness/system/store.js +153 -0
  137. package/dist/runtime/harness.d.ts +9 -1
  138. package/dist/runtime/harness.js +141 -7
  139. package/dist/runtime/maintenance/sqlite-checkpoint-saver.d.ts +8 -3
  140. package/dist/runtime/maintenance/sqlite-checkpoint-saver.js +152 -53
  141. package/dist/runtime/parsing/output-parsing.d.ts +10 -2
  142. package/dist/runtime/parsing/output-parsing.js +223 -16
  143. package/dist/runtime/parsing/stream-event-parsing.d.ts +7 -0
  144. package/dist/runtime/parsing/stream-event-parsing.js +51 -1
  145. package/dist/runtime/scheduling/system-schedule-manager.d.ts +41 -0
  146. package/dist/runtime/scheduling/system-schedule-manager.js +532 -0
  147. package/dist/runtime/support/embedding-models.d.ts +1 -1
  148. package/dist/runtime/support/embedding-models.js +5 -2
  149. package/dist/runtime/support/runtime-factories.js +1 -1
  150. package/dist/runtime/support/runtime-layout.d.ts +3 -0
  151. package/dist/runtime/support/runtime-layout.js +10 -1
  152. package/dist/runtime/support/runtime-prompts.d.ts +30 -0
  153. package/dist/runtime/support/runtime-prompts.js +55 -0
  154. package/dist/runtime/support/vector-stores.d.ts +1 -1
  155. package/dist/runtime/support/vector-stores.js +5 -2
  156. package/dist/upstream-events.js +8 -7
  157. package/dist/utils/bundled-text.d.ts +3 -0
  158. package/dist/utils/bundled-text.js +25 -0
  159. package/dist/utils/id.js +3 -2
  160. package/dist/workspace/agent-binding-compiler.js +53 -13
  161. package/dist/workspace/object-loader.js +64 -2
  162. package/dist/workspace/support/workspace-ref-utils.d.ts +2 -1
  163. package/dist/workspace/support/workspace-ref-utils.js +24 -5
  164. package/dist/workspace/yaml-object-reader.d.ts +1 -0
  165. package/dist/workspace/yaml-object-reader.js +95 -17
  166. package/package.json +11 -5
@@ -1,9 +1,162 @@
1
1
  import { AGENT_INTERRUPT_SENTINEL_PREFIX, RuntimeOperationTimeoutError } from "../../agent-runtime-adapter.js";
2
+ import { buildRequestPlanState, summarizeBuiltinWriteTodosArgs } from "../../adapter/runtime-adapter-support.js";
2
3
  import { renderRuntimeFailure, renderToolFailure } from "../../support/harness-support.js";
3
4
  import { getBindingPrimaryModel } from "../../support/compiled-binding.js";
4
5
  import { createContentBlocksItem, createToolResultKey, } from "../events/streaming.js";
5
6
  import { projectRuntimeSurfaceFromSingleUpstreamEvent } from "./inspection.js";
6
7
  import { formatAgentName } from "../../../utils/agent-display.js";
8
+ function createInitialPlanState(sessionId, requestId, updatedAt) {
9
+ return {
10
+ sessionId,
11
+ requestId,
12
+ version: 0,
13
+ updatedAt,
14
+ items: [],
15
+ summary: {
16
+ total: 0,
17
+ pending: 0,
18
+ inProgress: 0,
19
+ completed: 0,
20
+ failed: 0,
21
+ cancelled: 0,
22
+ blocked: 0,
23
+ },
24
+ };
25
+ }
26
+ function getPlanStateFromToolResult(input) {
27
+ if (typeof input.output !== "object" || input.output === null) {
28
+ return null;
29
+ }
30
+ const summary = input.output.summary;
31
+ if (summary && typeof summary === "object" && Array.isArray(summary.items)) {
32
+ const typedSummary = summary;
33
+ if (typedSummary.summary && typeof typedSummary.summary === "object") {
34
+ return {
35
+ sessionId: input.sessionId,
36
+ requestId: input.requestId,
37
+ version: input.version,
38
+ updatedAt: input.updatedAt,
39
+ items: typedSummary.items,
40
+ summary: typedSummary.summary,
41
+ };
42
+ }
43
+ }
44
+ const snapshot = summarizeBuiltinWriteTodosArgs(input.output);
45
+ return buildRequestPlanState({
46
+ sessionId: input.sessionId,
47
+ requestId: input.requestId,
48
+ updatedAt: input.updatedAt,
49
+ version: input.version,
50
+ snapshot,
51
+ });
52
+ }
53
+ function getStructuredPlanStateFromToolResult(input) {
54
+ if (typeof input.output !== "object" || input.output === null) {
55
+ return null;
56
+ }
57
+ const summary = input.output.summary;
58
+ if (!summary || typeof summary !== "object" || !Array.isArray(summary.items)) {
59
+ return null;
60
+ }
61
+ const typedSummary = summary;
62
+ if (!typedSummary.summary || typeof typedSummary.summary !== "object") {
63
+ return null;
64
+ }
65
+ return {
66
+ sessionId: input.sessionId,
67
+ requestId: input.requestId,
68
+ version: input.version,
69
+ updatedAt: input.updatedAt,
70
+ items: typedSummary.items,
71
+ summary: typedSummary.summary,
72
+ };
73
+ }
74
+ function buildPlanStateSignature(planState) {
75
+ return JSON.stringify({
76
+ items: planState.items,
77
+ summary: planState.summary,
78
+ });
79
+ }
80
+ function countStructuredTodoIds(items) {
81
+ return items.filter((item) => typeof item.id === "string" && item.id.length > 0).length;
82
+ }
83
+ function shouldEmitPlanState(currentPlanState, nextPlanState) {
84
+ if (!currentPlanState || currentPlanState.items.length === 0) {
85
+ return true;
86
+ }
87
+ if (nextPlanState.items.length === 0) {
88
+ return false;
89
+ }
90
+ const currentStructuredIds = countStructuredTodoIds(currentPlanState.items);
91
+ const nextStructuredIds = countStructuredTodoIds(nextPlanState.items);
92
+ if (currentStructuredIds > 0
93
+ && nextStructuredIds === 0
94
+ && nextPlanState.items.length < currentPlanState.items.length) {
95
+ return false;
96
+ }
97
+ return true;
98
+ }
99
+ function extractTodosArray(value) {
100
+ if (typeof value !== "object" || value === null) {
101
+ return null;
102
+ }
103
+ const record = value;
104
+ if (Array.isArray(record.todos)) {
105
+ return record.todos;
106
+ }
107
+ if (typeof record.output === "object" && record.output !== null) {
108
+ const nested = record.output.todos;
109
+ if (Array.isArray(nested)) {
110
+ return nested;
111
+ }
112
+ }
113
+ return null;
114
+ }
115
+ function getPlanStateFromUpstreamEvent(input) {
116
+ if (typeof input.event !== "object" || input.event === null) {
117
+ return null;
118
+ }
119
+ const typed = input.event;
120
+ const todos = extractTodosArray(typed.data?.output)
121
+ ?? extractTodosArray(typed.data?.chunk);
122
+ if (!todos) {
123
+ return null;
124
+ }
125
+ return buildRequestPlanState({
126
+ sessionId: input.sessionId,
127
+ requestId: input.requestId,
128
+ updatedAt: input.updatedAt,
129
+ version: input.version,
130
+ snapshot: summarizeBuiltinWriteTodosArgs({ todos }),
131
+ });
132
+ }
133
+ function getLatestPlanStateFromExecutedToolResults(input) {
134
+ const executedToolResults = Array.isArray(input.metadata?.executedToolResults)
135
+ ? input.metadata.executedToolResults
136
+ : [];
137
+ for (const latest of [...executedToolResults].reverse()) {
138
+ const structured = getStructuredPlanStateFromToolResult({
139
+ sessionId: input.sessionId,
140
+ requestId: input.requestId,
141
+ output: latest.output,
142
+ version: input.version,
143
+ updatedAt: input.updatedAt,
144
+ });
145
+ if (structured) {
146
+ return structured;
147
+ }
148
+ if (latest.toolName === "write_todos") {
149
+ return getPlanStateFromToolResult({
150
+ sessionId: input.sessionId,
151
+ requestId: input.requestId,
152
+ output: latest.output,
153
+ version: input.version,
154
+ updatedAt: input.updatedAt,
155
+ });
156
+ }
157
+ }
158
+ return null;
159
+ }
7
160
  function normalizeStreamChunk(chunk) {
8
161
  if (typeof chunk === "string") {
9
162
  if (chunk.startsWith(AGENT_INTERRUPT_SENTINEL_PREFIX)) {
@@ -11,6 +164,9 @@ function normalizeStreamChunk(chunk) {
11
164
  }
12
165
  return { kind: "content", content: chunk };
13
166
  }
167
+ if (chunk.kind === "commentary") {
168
+ return { kind: "commentary", content: chunk.content ?? "" };
169
+ }
14
170
  if (chunk.kind === "upstream-event") {
15
171
  return { kind: "upstream-event", event: (chunk.event ?? {}) };
16
172
  }
@@ -28,8 +184,117 @@ function normalizeStreamChunk(chunk) {
28
184
  isError: chunk.isError,
29
185
  };
30
186
  }
187
+ if (chunk.kind === "profile") {
188
+ return {
189
+ kind: "profile",
190
+ step: chunk.step,
191
+ };
192
+ }
31
193
  return { kind: "content", content: chunk.content ?? "" };
32
194
  }
195
+ function normalizeCommentaryText(value) {
196
+ return value.replace(/\s+/g, " ").trim();
197
+ }
198
+ function ensureCommentarySentence(value) {
199
+ const normalized = normalizeCommentaryText(value);
200
+ if (!normalized) {
201
+ return normalized;
202
+ }
203
+ return /[.!?]$/.test(normalized) ? normalized : `${normalized}.`;
204
+ }
205
+ function summarizePlanState(planState) {
206
+ if (planState.summary.total <= 0) {
207
+ return null;
208
+ }
209
+ const counts = [
210
+ planState.summary.inProgress > 0 ? `${planState.summary.inProgress} in progress` : "",
211
+ planState.summary.pending > 0 ? `${planState.summary.pending} pending` : "",
212
+ planState.summary.completed > 0 ? `${planState.summary.completed} completed` : "",
213
+ planState.summary.blocked > 0 ? `${planState.summary.blocked} blocked` : "",
214
+ planState.summary.failed > 0 ? `${planState.summary.failed} failed` : "",
215
+ ].filter((value) => value.length > 0);
216
+ if (counts.length === 0) {
217
+ counts.push(`${planState.summary.total} total`);
218
+ }
219
+ return `Plan updated: ${counts.join(", ")}.`;
220
+ }
221
+ function createSurfaceCommentary(surfaceItem) {
222
+ const name = normalizeCommentaryText(surfaceItem.name);
223
+ if (!name) {
224
+ return null;
225
+ }
226
+ if (surfaceItem.kind === "tool") {
227
+ if (surfaceItem.status === "started") {
228
+ return `Running tool ${name}.`;
229
+ }
230
+ if (surfaceItem.status === "completed") {
231
+ return `Tool ${name} completed.`;
232
+ }
233
+ if (surfaceItem.status === "failed") {
234
+ return `Tool ${name} failed.`;
235
+ }
236
+ return null;
237
+ }
238
+ if (surfaceItem.kind === "skill") {
239
+ if (surfaceItem.status === "started") {
240
+ return `Applying skill ${name}.`;
241
+ }
242
+ if (surfaceItem.status === "completed") {
243
+ return `Skill ${name} applied.`;
244
+ }
245
+ if (surfaceItem.status === "failed") {
246
+ return `Skill ${name} failed.`;
247
+ }
248
+ return null;
249
+ }
250
+ if (surfaceItem.kind === "agent") {
251
+ if (surfaceItem.status === "started") {
252
+ return `Delegating work to ${name}.`;
253
+ }
254
+ if (surfaceItem.status === "completed") {
255
+ return `Delegation to ${name} completed.`;
256
+ }
257
+ if (surfaceItem.status === "failed") {
258
+ return `Delegation to ${name} failed.`;
259
+ }
260
+ return null;
261
+ }
262
+ if (surfaceItem.kind === "llm") {
263
+ if (surfaceItem.status === "started") {
264
+ return `Running model ${name}.`;
265
+ }
266
+ if (surfaceItem.status === "completed") {
267
+ return `Model ${name} completed.`;
268
+ }
269
+ if (surfaceItem.status === "failed") {
270
+ return `Model ${name} failed.`;
271
+ }
272
+ return null;
273
+ }
274
+ if (surfaceItem.kind === "memory") {
275
+ if (surfaceItem.status === "started") {
276
+ return `Checking memory ${name}.`;
277
+ }
278
+ if (surfaceItem.status === "completed") {
279
+ return ensureCommentarySentence(`Finished checking memory ${name}`);
280
+ }
281
+ if (surfaceItem.status === "failed") {
282
+ return `Memory ${name} failed.`;
283
+ }
284
+ return null;
285
+ }
286
+ return null;
287
+ }
288
+ function createProfileStepCommentary(step) {
289
+ const name = normalizeCommentaryText(step.name);
290
+ if (!name || step.status !== "started") {
291
+ return null;
292
+ }
293
+ if (step.kind === "memory") {
294
+ return `Checking memory ${name}.`;
295
+ }
296
+ return null;
297
+ }
33
298
  function isOpenAICompatibleStreamingCompatibilityError(binding, error) {
34
299
  const primaryModel = getBindingPrimaryModel(binding);
35
300
  if (primaryModel?.provider !== "openai-compatible") {
@@ -38,33 +303,107 @@ function isOpenAICompatibleStreamingCompatibilityError(binding, error) {
38
303
  const message = error instanceof Error ? error.message : String(error);
39
304
  return message.toLowerCase().includes("received empty response from chat model call");
40
305
  }
306
+ function createRuntimeMemoryRecallSteps(sessionId, requestId, items) {
307
+ if (items.length === 0) {
308
+ return [];
309
+ }
310
+ const timestamp = new Date().toISOString();
311
+ const scopes = Array.from(new Set(items.map((item) => item.scope)));
312
+ const primaryScope = scopes.length === 1 ? scopes[0] : "mixed";
313
+ const primarySummary = items[0]?.summary;
314
+ const name = scopes.length === 1 ? `durable ${primaryScope} memory` : "durable memory";
315
+ const detail = {
316
+ source: "runtime-durable-memory",
317
+ scope: primaryScope,
318
+ scopes,
319
+ count: items.length,
320
+ summaries: items.map((item) => item.summary).slice(0, 5),
321
+ ...(primarySummary ? { summary: primarySummary } : {}),
322
+ };
323
+ const startedStep = {
324
+ id: `runtime-memory-recall:${requestId}:started`,
325
+ kind: "memory",
326
+ name,
327
+ action: "recall",
328
+ status: "started",
329
+ occurredAt: timestamp,
330
+ detail,
331
+ };
332
+ const completedStep = {
333
+ ...startedStep,
334
+ id: `runtime-memory-recall:${requestId}:completed`,
335
+ status: "completed",
336
+ };
337
+ return [
338
+ {
339
+ type: "profile-step",
340
+ sessionId,
341
+ requestId,
342
+ step: startedStep,
343
+ },
344
+ {
345
+ type: "profile-step",
346
+ sessionId,
347
+ requestId,
348
+ step: completedStep,
349
+ },
350
+ ];
351
+ }
41
352
  export async function* streamHarnessRun(options) {
42
353
  const priorHistoryPromise = Promise.resolve(options.isNewSession ? [] : undefined).then((historyHint) => historyHint ?? options.loadPriorHistory(options.sessionId, options.requestId));
43
354
  yield { type: "event", event: await options.requestCreatedEventPromise };
355
+ let planStateVersion = 0;
356
+ let lastPlanStateSignature;
357
+ let currentPlanState = null;
44
358
  let releaseRunSlot = async () => undefined;
45
359
  let emitted = false;
46
360
  let streamActivityObserved = false;
47
361
  let nonUpstreamStreamActivityObserved = false;
362
+ let assistantOutput = "";
48
363
  let currentAgentId = options.selectedAgentId;
49
364
  let currentAgentName = formatAgentName(options.selectedAgentId);
50
365
  let delegationChain = [options.selectedAgentId];
51
366
  let upstreamEventOrdinal = 0;
52
367
  let syntheticFallback;
368
+ const emittedCommentary = new Set();
369
+ const emitCommentary = function* (content) {
370
+ const normalized = normalizeCommentaryText(content);
371
+ if (!normalized || emittedCommentary.has(normalized)) {
372
+ return;
373
+ }
374
+ emittedCommentary.add(normalized);
375
+ yield {
376
+ type: "commentary",
377
+ sessionId: options.sessionId,
378
+ requestId: options.requestId,
379
+ agentId: currentAgentId,
380
+ content: normalized,
381
+ };
382
+ };
53
383
  try {
54
384
  const [priorHistory, acquiredReleaseRunSlot] = await Promise.all([
55
385
  priorHistoryPromise,
56
386
  options.releaseRequestSlotPromise,
57
387
  ]).then(([loadedPriorHistory, resolvedReleaseRunSlot]) => [loadedPriorHistory, resolvedReleaseRunSlot]);
58
388
  releaseRunSlot = acquiredReleaseRunSlot;
59
- let assistantOutput = "";
60
389
  const toolErrors = [];
61
390
  let lastToolResultKey = null;
391
+ const recalledMemories = options.invocation.memoryRecall?.items ?? [];
392
+ for (const item of createRuntimeMemoryRecallSteps(options.sessionId, options.requestId, recalledMemories)) {
393
+ yield item;
394
+ if (item.type === "profile-step") {
395
+ const commentary = createProfileStepCommentary(item.step);
396
+ if (commentary) {
397
+ yield* emitCommentary(commentary);
398
+ }
399
+ }
400
+ }
62
401
  for await (const rawChunk of options.stream(options.binding, options.input, options.sessionId, priorHistory, {
63
402
  context: options.invocation.context,
64
403
  state: options.invocation.state,
65
404
  files: options.invocation.files,
66
405
  requestId: options.requestId,
67
- memoryContext: options.invocation.memoryContext,
406
+ memoryContext: options.invocation.memoryRecall?.prompt,
68
407
  })) {
69
408
  if (!rawChunk) {
70
409
  continue;
@@ -72,6 +411,32 @@ export async function* streamHarnessRun(options) {
72
411
  streamActivityObserved = true;
73
412
  const normalizedChunk = normalizeStreamChunk(rawChunk);
74
413
  if (normalizedChunk.kind === "upstream-event") {
414
+ const upstreamPlanState = getPlanStateFromUpstreamEvent({
415
+ sessionId: options.sessionId,
416
+ requestId: options.requestId,
417
+ event: normalizedChunk.event,
418
+ version: planStateVersion + 1,
419
+ updatedAt: new Date().toISOString(),
420
+ });
421
+ if (upstreamPlanState) {
422
+ const signature = buildPlanStateSignature(upstreamPlanState);
423
+ if (signature !== lastPlanStateSignature && shouldEmitPlanState(currentPlanState, upstreamPlanState)) {
424
+ planStateVersion = upstreamPlanState.version;
425
+ lastPlanStateSignature = signature;
426
+ currentPlanState = upstreamPlanState;
427
+ yield {
428
+ type: "plan-state",
429
+ sessionId: options.sessionId,
430
+ requestId: options.requestId,
431
+ agentId: currentAgentId,
432
+ planState: upstreamPlanState,
433
+ };
434
+ const commentary = summarizePlanState(upstreamPlanState);
435
+ if (commentary) {
436
+ yield* emitCommentary(commentary);
437
+ }
438
+ }
439
+ }
75
440
  upstreamEventOrdinal += 1;
76
441
  const projectionBinding = options.getBinding(currentAgentId) ?? options.binding;
77
442
  const surfaceProjection = projectRuntimeSurfaceFromSingleUpstreamEvent({
@@ -121,6 +486,10 @@ export async function* streamHarnessRun(options) {
121
486
  surfaceItem,
122
487
  event: normalizedChunk.event,
123
488
  };
489
+ const commentary = createSurfaceCommentary(surfaceItem);
490
+ if (commentary) {
491
+ yield* emitCommentary(commentary);
492
+ }
124
493
  }
125
494
  continue;
126
495
  }
@@ -150,9 +519,26 @@ export async function* streamHarnessRun(options) {
150
519
  };
151
520
  return;
152
521
  }
522
+ if (normalizedChunk.kind === "commentary") {
523
+ yield* emitCommentary(normalizedChunk.content);
524
+ continue;
525
+ }
153
526
  if (normalizedChunk.kind === "reasoning") {
154
527
  continue;
155
528
  }
529
+ if (normalizedChunk.kind === "profile") {
530
+ yield {
531
+ type: "profile-step",
532
+ sessionId: options.sessionId,
533
+ requestId: options.requestId,
534
+ step: normalizedChunk.step,
535
+ };
536
+ const commentary = createProfileStepCommentary(normalizedChunk.step);
537
+ if (commentary) {
538
+ yield* emitCommentary(commentary);
539
+ }
540
+ continue;
541
+ }
156
542
  if (normalizedChunk.kind === "tool-result") {
157
543
  const toolResultKey = createToolResultKey(normalizedChunk.toolName, normalizedChunk.output, normalizedChunk.isError);
158
544
  if (toolResultKey === lastToolResultKey) {
@@ -171,6 +557,39 @@ export async function* streamHarnessRun(options) {
171
557
  output: normalizedChunk.output,
172
558
  isError: normalizedChunk.isError,
173
559
  };
560
+ const planState = normalizedChunk.toolName === "write_todos"
561
+ ? getPlanStateFromToolResult({
562
+ sessionId: options.sessionId,
563
+ requestId: options.requestId,
564
+ output: normalizedChunk.output,
565
+ version: ++planStateVersion,
566
+ updatedAt: new Date().toISOString(),
567
+ })
568
+ : getStructuredPlanStateFromToolResult({
569
+ sessionId: options.sessionId,
570
+ requestId: options.requestId,
571
+ output: normalizedChunk.output,
572
+ version: ++planStateVersion,
573
+ updatedAt: new Date().toISOString(),
574
+ });
575
+ if (planState) {
576
+ const signature = buildPlanStateSignature(planState);
577
+ if (signature !== lastPlanStateSignature && shouldEmitPlanState(currentPlanState, planState)) {
578
+ lastPlanStateSignature = signature;
579
+ currentPlanState = planState;
580
+ yield {
581
+ type: "plan-state",
582
+ sessionId: options.sessionId,
583
+ requestId: options.requestId,
584
+ agentId: currentAgentId,
585
+ planState,
586
+ };
587
+ const commentary = summarizePlanState(planState);
588
+ if (commentary) {
589
+ yield* emitCommentary(commentary);
590
+ }
591
+ }
592
+ }
174
593
  continue;
175
594
  }
176
595
  emitted = true;
@@ -200,6 +619,32 @@ export async function* streamHarnessRun(options) {
200
619
  assistantOutput = actual.output;
201
620
  emitted = true;
202
621
  }
622
+ const finalPlanState = getLatestPlanStateFromExecutedToolResults({
623
+ sessionId: options.sessionId,
624
+ requestId: options.requestId,
625
+ metadata: actual.metadata,
626
+ version: planStateVersion + 1,
627
+ updatedAt: new Date().toISOString(),
628
+ });
629
+ if (finalPlanState) {
630
+ const signature = buildPlanStateSignature(finalPlanState);
631
+ if (signature !== lastPlanStateSignature && shouldEmitPlanState(currentPlanState, finalPlanState)) {
632
+ planStateVersion = finalPlanState.version;
633
+ lastPlanStateSignature = signature;
634
+ currentPlanState = finalPlanState;
635
+ yield {
636
+ type: "plan-state",
637
+ sessionId: options.sessionId,
638
+ requestId: options.requestId,
639
+ agentId: currentAgentId,
640
+ planState: finalPlanState,
641
+ };
642
+ const commentary = summarizePlanState(finalPlanState);
643
+ if (commentary) {
644
+ yield* emitCommentary(commentary);
645
+ }
646
+ }
647
+ }
203
648
  }
204
649
  await options.appendAssistantMessage(options.sessionId, options.requestId, assistantOutput);
205
650
  const completedEvent = await options.setRequestStateAndEmit(options.sessionId, options.requestId, 6, "completed", {
@@ -222,8 +667,7 @@ export async function* streamHarnessRun(options) {
222
667
  };
223
668
  }
224
669
  catch (error) {
225
- const shouldRetryAfterStreamingCompatibilityError = streamActivityObserved &&
226
- !nonUpstreamStreamActivityObserved &&
670
+ const shouldRetryAfterStreamingCompatibilityError = !assistantOutput &&
227
671
  isOpenAICompatibleStreamingCompatibilityError(options.binding, error);
228
672
  if ((emitted || streamActivityObserved) && !shouldRetryAfterStreamingCompatibilityError) {
229
673
  const runtimeFailure = renderRuntimeFailure(error);
@@ -34,24 +34,18 @@ export function stripStepPrefix(label) {
34
34
  .replace(/^Accessing memory\s+/i, "")
35
35
  .replace(/^Completed memory\s+/i, "");
36
36
  }
37
- function isGenericMemoryMiddlewareName(value) {
38
- return /^(memorymiddleware\.before[_\s]?agent|memory middleware before agent)$/i.test(normalizeLabel(value));
39
- }
40
37
  function canonicalMemoryName(memorySource) {
41
38
  const normalized = normalizeLabel(memorySource.replace(/^memory\//i, ""));
42
39
  const segments = normalized.split(/[\\/]/).filter(Boolean);
43
40
  return (segments.at(-1) ?? normalized).toLowerCase() || "memory";
44
41
  }
45
- function isGenericSkillMiddlewareName(value) {
46
- return /^(skillsmiddleware\.before[_\s]?agent|skills middleware before agent)$/i.test(normalizeLabel(value));
47
- }
48
42
  export function resolveSurfaceDisplayName(input) {
49
43
  const baseName = stripStepPrefix(input.step) || formatAgentName(input.kind);
50
- if (input.kind === "memory" && input.binding && isGenericMemoryMiddlewareName(baseName)) {
44
+ if (input.kind === "memory" && input.binding && baseName.length === 0) {
51
45
  const memorySources = getBindingMemorySources(input.binding).filter((name) => name.trim().length > 0);
52
46
  return memorySources.length === 1 ? canonicalMemoryName(memorySources[0]) : baseName;
53
47
  }
54
- if (input.kind !== "skill" || !input.binding || !isGenericSkillMiddlewareName(baseName)) {
48
+ if (input.kind !== "skill" || !input.binding || baseName.length > 0) {
55
49
  return baseName;
56
50
  }
57
51
  const skillNames = getBindingSkills(input.binding)
@@ -59,32 +53,11 @@ export function resolveSurfaceDisplayName(input) {
59
53
  .filter((name) => typeof name === "string" && name.trim().length > 0);
60
54
  return skillNames.length === 1 ? skillNames[0] : baseName;
61
55
  }
62
- function normalizeActionHint(value) {
63
- return value
64
- .replace(/([a-z0-9])([A-Z])/g, "$1 $2")
65
- .replace(/[.:/]+/g, " ")
66
- .replace(/[_-]+/g, " ")
67
- .replace(/\s+/g, " ")
68
- .trim()
69
- .toLowerCase();
70
- }
71
- function resolveMemoryAction(event, step) {
56
+ function resolveMemoryAction(event) {
72
57
  const typed = asObject(event);
73
- const hints = [
74
- typeof typed?.event === "string" ? typed.event : "",
75
- typeof typed?.name === "string" ? typed.name : "",
76
- typeof typed?.run_type === "string" ? typed.run_type : "",
77
- ...readStringArray(typed?.tags),
78
- ...readStringArray(typed?.ns),
79
- step,
80
- ].map(normalizeActionHint);
81
- if (hints.some((value) => /\b(store|memorize|sync|formation|ingestion|archive|write)\b/.test(value))) {
82
- return "memorize";
83
- }
84
- if (hints.some((value) => /\b(recall|retrieve|memorymiddleware|before agent|checkpoint|context)\b/.test(value)
85
- || value.includes("accessing memory")
86
- || value.includes("access memory"))) {
87
- return "recall";
58
+ const runType = typeof typed?.run_type === "string" ? typed.run_type.trim().toLowerCase() : "";
59
+ if (runType === "memory") {
60
+ return "access";
88
61
  }
89
62
  return "access";
90
63
  }
@@ -99,7 +72,7 @@ export function resolveSurfaceAction(input) {
99
72
  case "skill":
100
73
  return "apply";
101
74
  case "memory":
102
- return resolveMemoryAction(input.event, input.step ?? "");
75
+ return resolveMemoryAction(input.event);
103
76
  default:
104
77
  return "run";
105
78
  }
@@ -10,6 +10,7 @@ export type ResolvedRuntimeMemoryFormationConfig = {
10
10
  enabled: boolean;
11
11
  strategy: "rules" | "model";
12
12
  modelRef?: string;
13
+ prompt?: string;
13
14
  maxContextRecords: number;
14
15
  };
15
16
  background: {
@@ -64,6 +65,8 @@ export declare function runModelMemoryManager(input: {
64
65
  requestId: string;
65
66
  recordedAt: string;
66
67
  existingRecords: MemoryRecord[];
68
+ maxContextRecords?: number;
69
+ promptTemplate?: string;
67
70
  modelResolver?: (modelId: string) => unknown;
68
71
  }): Promise<MemoryCandidate[]>;
69
72
  export declare function createRuntimeMemoryManager(input: {