@botbotgo/agent-harness 0.0.323 → 0.0.325

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 (39) hide show
  1. package/README.md +2 -1
  2. package/README.zh.md +2 -1
  3. package/dist/cli/chat-ui.js +3 -2
  4. package/dist/cli/main.js +84 -2
  5. package/dist/cli/managed-service.d.ts +2 -1
  6. package/dist/cli/managed-service.js +78 -2
  7. package/dist/cli/options-serve.d.ts +13 -0
  8. package/dist/cli/options-serve.js +116 -0
  9. package/dist/cli/options.d.ts +1 -1
  10. package/dist/cli/options.js +7 -1
  11. package/dist/cli/server-commands.d.ts +1 -1
  12. package/dist/cli/server-commands.js +28 -8
  13. package/dist/config/knowledge/knowledge-runtime.yaml +3 -2
  14. package/dist/config/prompts/orchestra-system.md +4 -0
  15. package/dist/config/runtime/runtime-memory.yaml +3 -2
  16. package/dist/knowledge/module.js +2 -1
  17. package/dist/package-version.d.ts +2 -1
  18. package/dist/package-version.js +2 -1
  19. package/dist/resource/isolation.js +28 -0
  20. package/dist/resources/prompts/runtime/autonomous-investigation-recovery.md +1 -1
  21. package/dist/resources/prompts/runtime/durable-memory-context.md +2 -0
  22. package/dist/resources/prompts/runtime/execution-with-tool-evidence-retry.md +1 -1
  23. package/dist/resources/prompts/runtime/write-todos-required-plan.md +1 -0
  24. package/dist/runtime/adapter/flow/stream-runtime.js +9 -141
  25. package/dist/runtime/adapter/model/invocation-request.js +1 -1
  26. package/dist/runtime/adapter/tool/builtin-middleware-tools.js +22 -8
  27. package/dist/runtime/harness/run/stream-run.js +17 -0
  28. package/dist/runtime/harness/system/runtime-memory-manager.js +4 -0
  29. package/dist/runtime/harness/system/runtime-memory-policy.d.ts +14 -0
  30. package/dist/runtime/harness/system/runtime-memory-policy.js +19 -0
  31. package/dist/runtime/parsing/output-parsing.d.ts +2 -1
  32. package/dist/runtime/parsing/output-parsing.js +2 -1
  33. package/dist/runtime/parsing/output-recovery.d.ts +4 -2
  34. package/dist/runtime/parsing/output-recovery.js +30 -264
  35. package/dist/runtime/prompts/runtime-prompts.d.ts +1 -0
  36. package/dist/runtime/prompts/runtime-prompts.js +1 -0
  37. package/dist/scaffold/init-project.js +6 -4
  38. package/dist/tools.js +25 -2
  39. package/package.json +1 -1
@@ -6,6 +6,10 @@ import { existsSync } from "node:fs";
6
6
  import { cp, mkdir, readFile, stat, symlink } from "node:fs/promises";
7
7
  const HARNESS_PACKAGE_NAME = "@botbotgo/agent-harness";
8
8
  const HARNESS_PACKAGE_ROOT = path.resolve(import.meta.dirname, "..", "..");
9
+ const HARNESS_TOOL_AUTHORING_DEPENDENCIES = [
10
+ "@langchain/core",
11
+ "zod",
12
+ ];
9
13
  const isolatedResourceRootCache = new Map();
10
14
  const isolatedResourceRootBuilds = new Map();
11
15
  function isolationCacheRoot() {
@@ -91,6 +95,29 @@ async function linkHarnessPackage(isolatedRoot) {
91
95
  await mkdir(path.dirname(targetPath), { recursive: true });
92
96
  await symlink(HARNESS_PACKAGE_ROOT, targetPath, "junction");
93
97
  }
98
+ function resolveHarnessOwnedDependency(dependencyName) {
99
+ try {
100
+ const requireFromHarness = createRequire(path.join(HARNESS_PACKAGE_ROOT, "package.json"));
101
+ return dependencyPackageRoot(requireFromHarness.resolve(`${dependencyName}/package.json`));
102
+ }
103
+ catch {
104
+ return null;
105
+ }
106
+ }
107
+ async function linkHarnessToolAuthoringDependencies(isolatedRoot) {
108
+ for (const dependencyName of HARNESS_TOOL_AUTHORING_DEPENDENCIES) {
109
+ const targetPath = dependencyLinkPath(isolatedRoot, dependencyName);
110
+ if (existsSync(targetPath)) {
111
+ continue;
112
+ }
113
+ const resolved = resolveHarnessOwnedDependency(dependencyName);
114
+ if (!resolved) {
115
+ continue;
116
+ }
117
+ await mkdir(path.dirname(targetPath), { recursive: true });
118
+ await symlink(resolved, targetPath, "junction");
119
+ }
120
+ }
94
121
  async function buildIsolatedResourceRoot(packageRoot) {
95
122
  const packageJsonPath = path.join(packageRoot, "package.json");
96
123
  const manifest = existsSync(packageJsonPath)
@@ -109,6 +136,7 @@ async function buildIsolatedResourceRoot(packageRoot) {
109
136
  await mkdir(path.join(isolatedRoot, "node_modules"), { recursive: true });
110
137
  await linkDeclaredDependencies(isolatedRoot, packageRoot, manifest);
111
138
  await linkHarnessPackage(isolatedRoot);
139
+ await linkHarnessToolAuthoringDependencies(isolatedRoot);
112
140
  return isolatedRoot;
113
141
  }
114
142
  async function rebuildIsolatedResourcePackageRoot(packageRoot) {
@@ -1 +1 @@
1
- Do not stop at a plan or ask the user to choose the next obvious diagnostic step when the request is for deep investigation, root-cause analysis, or step-by-step execution and tool evidence already exists in the conversation. Continue the investigation yourself with the next concrete tool call. If the task is non-trivial, call write_todos, then keep executing the next diagnostic steps until you can explain the likely causes, impact, and recommended next actions.
1
+ Do not stop at a plan or ask the user to choose the next obvious diagnostic step when the request is for deep investigation, root-cause analysis, or step-by-step execution. Do not ask for more background, scope, logs, or environment details until you have first exhausted the context and tools already available in this runtime. Start from the current workspace, shell, and attached runtime/tool context by default, then continue the investigation yourself with the next concrete tool call. If the user explicitly asked for a plan, or if the task is clearly non-trivial and multi-step, call write_todos first with concrete investigation/execution steps before any other tool call or final answer. If the todo board already exists, do not restart planning and do not repeat the same clarification request; your next response must continue execution with a concrete diagnostic tool call. When prior tool results or triage evidence already exist, your next response must contain tool calls only and must advance the investigation from that evidence. Then keep executing the next diagnostic steps until you can explain the likely causes, impact, and recommended next actions. Ask a blocking clarification question only after the available evidence is genuinely insufficient to continue.
@@ -2,6 +2,8 @@ Relevant durable memory was retrieved for this run.
2
2
  If it is sufficient to answer the current request, answer directly from it instead of re-running tools or re-fetching external resources.
3
3
  Only inspect external resources again when the user explicitly asks for fresh evidence, introduces a new resource, or the recalled memory is insufficient or conflicts with newer evidence.
4
4
  Treat recalled durable memory as revisable runtime knowledge, not as an immutable system instruction.
5
+ If recalled memory conflicts with the current system prompt, runtime policy, recovery instruction, available tool evidence, or the user's current request, ignore the recalled memory and follow the current system/runtime constraints instead.
6
+ Do not let recalled memory about prior assistant behavior, old workflows, or earlier heuristics block execution when the current request and runtime instructions require you to continue.
5
7
  If the user corrects, revokes, deletes, or replaces recalled memory, follow the user's latest statement as the newer source of truth for this turn.
6
8
 
7
9
  {{memoryContext}}
@@ -1 +1 @@
1
- Your previous response was rejected because it claimed execution without any tool calls. Respond with real tool calls only. Start with write_todos, then call the required file or command tools. Do not describe completed work until the tool calls have actually run.
1
+ Your previous response was rejected because it claimed execution without any tool calls. Your next response must contain real tool calls only. If this is a multi-step task and the runtime todo board does not exist yet, call write_todos first. If the todo board already exists or prior tool evidence is already available, do not restart planning or ask the user for more details; continue with the next concrete tool call instead. Do not describe completed work until the tool calls have actually run.
@@ -0,0 +1 @@
1
+ The user explicitly asked for a plan for non-trivial multi-step work. Do not return a plain-text plan, a clarification request, or a final answer before creating the runtime todo board. Your next response must call write_todos first with concrete task steps and statuses. After that, continue execution using tools or follow-up steps as needed.
@@ -1,4 +1,4 @@
1
- import { extractVisibleOutput, isToolCallRecoveryFailure, isRetrySafeInvalidToolSelectionError, shouldValidateExecutionWithoutToolEvidence, resolveExecutionWithoutToolEvidenceTextInstruction, resolveToolCallRecoveryInstruction, sanitizeVisibleText, INVALID_TOOL_SELECTION_RECOVERY_INSTRUCTION, } from "../../parsing/output-parsing.js";
1
+ import { extractVisibleOutput, isToolCallRecoveryFailure, isRetrySafeInvalidToolSelectionError, shouldValidateExecutionWithoutToolEvidence, resolveToolCallRecoveryInstruction, sanitizeVisibleText, INVALID_TOOL_SELECTION_RECOVERY_INSTRUCTION, } from "../../parsing/output-parsing.js";
2
2
  import { buildInvocationRequest } from "../model/invocation-request.js";
3
3
  import { buildRawModelMessages } from "../model/message-assembly.js";
4
4
  import { projectRuntimeStreamEvent, createStreamEventProjectionState } from "../stream-event-projection.js";
@@ -49,7 +49,6 @@ export async function* streamRuntimeExecution(options) {
49
49
  const shouldValidateStreamOutput = shouldValidateExecutionWithoutToolEvidence(request);
50
50
  const deferredStreamContent = [];
51
51
  let sawRetrySafeInvalidToolSelectionError = false;
52
- let sawNonRetrySafeToolSideEffects = false;
53
52
  const shouldDeferStreamContent = () => shouldValidateStreamOutput && !emittedUnsafeStreamSideEffects;
54
53
  const flushDeferredStreamContent = async function* () {
55
54
  while (deferredStreamContent.length > 0) {
@@ -248,7 +247,6 @@ export async function* streamRuntimeExecution(options) {
248
247
  }
249
248
  if (eventContainsNonTodoToolResult || eventContainsNonRetrySafeChunk) {
250
249
  emittedUnsafeStreamSideEffects = true;
251
- sawNonRetrySafeToolSideEffects = true;
252
250
  }
253
251
  if (chunk.kind === "content" && shouldDeferStreamContent()) {
254
252
  deferredStreamContent.push(chunk);
@@ -280,53 +278,10 @@ export async function* streamRuntimeExecution(options) {
280
278
  });
281
279
  throw error;
282
280
  }
283
- const streamRecoveryInstruction = resolveExecutionWithoutToolEvidenceTextInstruction(request, projectionState.emittedOutput, projectionState.emittedToolResult || (projectionState.emittedToolError && (sawNonRetrySafeToolSideEffects || !sawRetrySafeInvalidToolSelectionError)));
284
- const terminalRecoveryInstruction = streamRecoveryInstruction
285
- ?? (!emittedUnsafeStreamSideEffects && sawRetrySafeInvalidToolSelectionError ? INVALID_TOOL_SELECTION_RECOVERY_INSTRUCTION : null);
286
- if (!emittedUnsafeStreamSideEffects && terminalRecoveryInstruction) {
287
- const toolRecovery = startProfileStep({
288
- id: "profile:agent:stream-output-recovery-fallback",
289
- kind: "agent",
290
- name: "stream output recovery fallback",
291
- action: "invoke",
292
- detail: {
293
- recoveryInstruction: terminalRecoveryInstruction,
294
- },
295
- });
296
- if (shouldProfile)
297
- yield toolRecovery.chunk;
281
+ const terminalRecoveryInstruction = !emittedUnsafeStreamSideEffects && sawRetrySafeInvalidToolSelectionError ? INVALID_TOOL_SELECTION_RECOVERY_INSTRUCTION : null;
282
+ if (terminalRecoveryInstruction) {
298
283
  let retried;
299
- try {
300
- retried = await options.invoke(options.applyToolRecoveryInstruction(options.binding, terminalRecoveryInstruction), options.input, options.sessionId, options.runtimeOptions.requestId ?? options.sessionId, undefined, options.history, options.runtimeOptions);
301
- if (shouldProfile)
302
- yield finishProfileStep({
303
- id: "profile:agent:stream-output-recovery-fallback",
304
- kind: "agent",
305
- name: "stream output recovery fallback",
306
- action: "invoke",
307
- startedAt: toolRecovery.startedAt,
308
- status: "completed",
309
- detail: {
310
- recoveryInstruction: terminalRecoveryInstruction,
311
- },
312
- });
313
- }
314
- catch (retryError) {
315
- if (shouldProfile)
316
- yield finishProfileStep({
317
- id: "profile:agent:stream-output-recovery-fallback",
318
- kind: "agent",
319
- name: "stream output recovery fallback",
320
- action: "invoke",
321
- startedAt: toolRecovery.startedAt,
322
- status: "failed",
323
- detail: {
324
- recoveryInstruction: terminalRecoveryInstruction,
325
- },
326
- error: retryError,
327
- });
328
- throw retryError;
329
- }
284
+ retried = await options.invoke(options.applyToolRecoveryInstruction(options.binding, terminalRecoveryInstruction), options.input, options.sessionId, options.runtimeOptions.requestId ?? options.sessionId, undefined, options.history, options.runtimeOptions);
330
285
  const executedToolResults = Array.isArray(retried.metadata?.executedToolResults)
331
286
  ? retried.metadata.executedToolResults
332
287
  : [];
@@ -340,9 +295,8 @@ export async function* streamRuntimeExecution(options) {
340
295
  }
341
296
  if (retried.output) {
342
297
  const visible = toVisibleContent(retried.output);
343
- if (visible) {
298
+ if (visible)
344
299
  yield { kind: "content", content: visible };
345
- }
346
300
  }
347
301
  return;
348
302
  }
@@ -492,49 +446,7 @@ export async function* streamRuntimeExecution(options) {
492
446
  }
493
447
  catch (error) {
494
448
  if (!emittedUnsafeStreamSideEffects && options.isRetryableProviderError?.(options.binding, error)) {
495
- const providerRetry = startProfileStep({
496
- id: "profile:agent:provider-retry-fallback",
497
- kind: "agent",
498
- name: "provider retry fallback",
499
- action: "invoke",
500
- detail: {
501
- error: error instanceof Error ? error.message : String(error),
502
- },
503
- });
504
- if (shouldProfile)
505
- yield providerRetry.chunk;
506
- let recovered;
507
- try {
508
- recovered = await options.invoke(options.binding, options.input, options.sessionId, options.runtimeOptions.requestId ?? options.sessionId, undefined, options.history, options.runtimeOptions);
509
- if (shouldProfile)
510
- yield finishProfileStep({
511
- id: "profile:agent:provider-retry-fallback",
512
- kind: "agent",
513
- name: "provider retry fallback",
514
- action: "invoke",
515
- startedAt: providerRetry.startedAt,
516
- status: "completed",
517
- detail: {
518
- error: error instanceof Error ? error.message : String(error),
519
- },
520
- });
521
- }
522
- catch (retryError) {
523
- if (shouldProfile)
524
- yield finishProfileStep({
525
- id: "profile:agent:provider-retry-fallback",
526
- kind: "agent",
527
- name: "provider retry fallback",
528
- action: "invoke",
529
- startedAt: providerRetry.startedAt,
530
- status: "failed",
531
- detail: {
532
- error: error instanceof Error ? error.message : String(error),
533
- },
534
- error: retryError,
535
- });
536
- throw retryError;
537
- }
449
+ const recovered = await options.invoke(options.binding, options.input, options.sessionId, options.runtimeOptions.requestId ?? options.sessionId, undefined, options.history, options.runtimeOptions);
538
450
  const executedToolResults = Array.isArray(recovered.metadata?.executedToolResults)
539
451
  ? recovered.metadata.executedToolResults
540
452
  : [];
@@ -548,9 +460,8 @@ export async function* streamRuntimeExecution(options) {
548
460
  }
549
461
  if (recovered.output) {
550
462
  const visible = toVisibleContent(recovered.output);
551
- if (visible) {
463
+ if (visible)
552
464
  yield { kind: "content", content: visible };
553
- }
554
465
  }
555
466
  return;
556
467
  }
@@ -566,54 +477,11 @@ export async function* streamRuntimeExecution(options) {
566
477
  if (!recoveryInstruction) {
567
478
  throw error;
568
479
  }
569
- const toolRecovery = startProfileStep({
570
- id: "profile:agent:tool-recovery-fallback",
571
- kind: "agent",
572
- name: "tool recovery fallback",
573
- action: "invoke",
574
- detail: {
575
- recoveryInstruction,
576
- },
577
- });
578
- if (shouldProfile)
579
- yield toolRecovery.chunk;
580
- let retried;
581
- try {
582
- retried = await options.invoke(options.applyToolRecoveryInstruction(options.binding, recoveryInstruction), options.input, options.sessionId, options.runtimeOptions.requestId ?? options.sessionId, undefined, options.history, options.runtimeOptions);
583
- if (shouldProfile)
584
- yield finishProfileStep({
585
- id: "profile:agent:tool-recovery-fallback",
586
- kind: "agent",
587
- name: "tool recovery fallback",
588
- action: "invoke",
589
- startedAt: toolRecovery.startedAt,
590
- status: "completed",
591
- detail: {
592
- recoveryInstruction,
593
- },
594
- });
595
- }
596
- catch (retryError) {
597
- if (shouldProfile)
598
- yield finishProfileStep({
599
- id: "profile:agent:tool-recovery-fallback",
600
- kind: "agent",
601
- name: "tool recovery fallback",
602
- action: "invoke",
603
- startedAt: toolRecovery.startedAt,
604
- status: "failed",
605
- detail: {
606
- recoveryInstruction,
607
- },
608
- error: retryError,
609
- });
610
- throw retryError;
611
- }
480
+ const retried = await options.invoke(options.applyToolRecoveryInstruction(options.binding, recoveryInstruction), options.input, options.sessionId, options.runtimeOptions.requestId ?? options.sessionId, undefined, options.history, options.runtimeOptions);
612
481
  if (retried.output) {
613
482
  const visible = toVisibleContent(retried.output);
614
- if (visible) {
483
+ if (visible)
615
484
  yield { kind: "content", content: visible };
616
- }
617
485
  }
618
486
  }
619
487
  }
@@ -123,7 +123,7 @@ function buildContextualFollowUpInstruction(inputText, hasDurableMemory) {
123
123
  if (!hasDurableMemory || hasExplicitResourceReference(inputText)) {
124
124
  return undefined;
125
125
  }
126
- return "Answer the user's current follow-up directly from the recalled context. If the current user turn corrects, revokes, deletes, or replaces recalled memory, treat the user's latest statement as newer than the recalled memory for this turn. Do not frame the reply as a fresh URL or page summary unless the current user turn explicitly includes a new resource to inspect.";
126
+ return "Answer the user's current follow-up directly from the recalled context when it remains relevant. If recalled memory conflicts with the current system prompt, runtime policy, recovery instruction, available tool evidence, or the user's current request, ignore the recalled memory for this turn. If the current user turn corrects, revokes, deletes, or replaces recalled memory, treat the user's latest statement as newer than the recalled memory for this turn. Do not frame the reply as a fresh URL or page summary unless the current user turn explicitly includes a new resource to inspect.";
127
127
  }
128
128
  export function buildSlashCommandSkillInstruction(binding, input) {
129
129
  const inputText = extractMessageText(input).trim();
@@ -121,6 +121,27 @@ function formatHttpResponse(result) {
121
121
  ];
122
122
  return lines.length > 0 ? lines.join("\n") : "Request completed.";
123
123
  }
124
+ async function fetchUrlWithRuntimeFallback(backend, url) {
125
+ if (typeof backend.fetchUrl === "function") {
126
+ try {
127
+ const result = await Promise.resolve(backend.fetchUrl(url));
128
+ if (typeof result === "string") {
129
+ return result;
130
+ }
131
+ return formatHttpResponse(result);
132
+ }
133
+ catch {
134
+ // Fall through to the runtime-owned network fetch below.
135
+ }
136
+ }
137
+ const response = await fetch(url);
138
+ return formatHttpResponse({
139
+ status: response.status,
140
+ statusText: response.statusText,
141
+ headers: Object.fromEntries(response.headers.entries()),
142
+ body: await response.text(),
143
+ });
144
+ }
124
145
  function parseScheduleWhen(value) {
125
146
  const normalized = value.trim().toLowerCase();
126
147
  if (!normalized) {
@@ -388,15 +409,8 @@ export async function createBuiltinMiddlewareTools(backend, options) {
388
409
  description: "Fetch a URL and return the response body.",
389
410
  schema: z.object({ url: z.string() }).passthrough(),
390
411
  invoke: async (input, toolConfig) => {
391
- if (typeof backend.fetchUrl !== "function") {
392
- return notAvailable("fetch_url", "URL fetching");
393
- }
394
412
  const typed = isRecord(input) ? input : {};
395
- const result = await Promise.resolve(backend.fetchUrl(typeof typed.url === "string" ? typed.url : ""));
396
- if (typeof result === "string") {
397
- return finalizeOutput("fetch_url", result, toolConfig);
398
- }
399
- return finalizeOutput("fetch_url", formatHttpResponse(result), toolConfig);
413
+ return finalizeOutput("fetch_url", await fetchUrlWithRuntimeFallback(backend, typeof typed.url === "string" ? typed.url : ""), toolConfig);
400
414
  },
401
415
  });
402
416
  tools.set("http_request", {
@@ -360,6 +360,7 @@ export async function* streamHarnessRun(options) {
360
360
  let streamActivityObserved = false;
361
361
  let nonUpstreamStreamActivityObserved = false;
362
362
  let assistantOutput = "";
363
+ const bufferAssistantTextUntilCompletion = true;
363
364
  let currentAgentId = options.selectedAgentId;
364
365
  let currentAgentName = formatAgentName(options.selectedAgentId);
365
366
  let delegationChain = [options.selectedAgentId];
@@ -594,6 +595,9 @@ export async function* streamHarnessRun(options) {
594
595
  }
595
596
  emitted = true;
596
597
  assistantOutput += normalizedChunk.content;
598
+ if (bufferAssistantTextUntilCompletion) {
599
+ continue;
600
+ }
597
601
  yield {
598
602
  type: "event",
599
603
  event: await options.emit(options.sessionId, options.requestId, 3, "output.delta", { content: normalizedChunk.content }),
@@ -646,6 +650,19 @@ export async function* streamHarnessRun(options) {
646
650
  }
647
651
  }
648
652
  }
653
+ if (assistantOutput && bufferAssistantTextUntilCompletion) {
654
+ yield {
655
+ type: "event",
656
+ event: await options.emit(options.sessionId, options.requestId, 3, "output.delta", { content: assistantOutput }),
657
+ };
658
+ yield {
659
+ type: "content",
660
+ sessionId: options.sessionId,
661
+ requestId: options.requestId,
662
+ agentId: currentAgentId,
663
+ content: assistantOutput,
664
+ };
665
+ }
649
666
  await options.appendAssistantMessage(options.sessionId, options.requestId, assistantOutput);
650
667
  const completedEvent = await options.setRequestStateAndEmit(options.sessionId, options.requestId, 6, "completed", {
651
668
  previousState: "running",
@@ -5,6 +5,7 @@ import { FileBackedStore } from "./store.js";
5
5
  import { compileModel } from "../../../workspace/resource-compilers.js";
6
6
  import { resolvePromptValue, resolveRefId } from "../../../workspace/support/workspace-ref-utils.js";
7
7
  import { renderRuntimeMemoryManagerPrompt, renderRuntimeMemoryMutationReconciliationPrompt } from "../../prompts/runtime-prompts.js";
8
+ import { isNonDurableTranscriptWorkflowMemory } from "./runtime-memory-policy.js";
8
9
  const FORMATION_EVENT_TYPES = new Set([
9
10
  "request.state.changed",
10
11
  "approval.resolved",
@@ -536,6 +537,9 @@ export async function runModelMemoryManager(input) {
536
537
  }
537
538
  const refinedCandidates = asCandidateOutputs(parsed, candidate, allowedScopes, input.recordedAt);
538
539
  for (const refinedCandidate of refinedCandidates) {
540
+ if (isNonDurableTranscriptWorkflowMemory(refinedCandidate, candidate)) {
541
+ continue;
542
+ }
539
543
  const reconciledCandidate = await reconcileKnowledgeMutation({
540
544
  invoker: callableInvoker,
541
545
  candidate: refinedCandidate,
@@ -29,6 +29,20 @@ export declare function resolveMemoryNamespace(template: string, values: Record<
29
29
  export declare function hasExplicitResourceReference(text: string): boolean;
30
30
  export declare function extractExplicitResourceReferences(text: string): string[];
31
31
  export declare function shouldRecallDurableMemory(text: string): boolean;
32
+ export declare function isNonDurableTranscriptWorkflowMemory(input: {
33
+ content: string;
34
+ summary?: string;
35
+ kind?: string;
36
+ scope?: string;
37
+ sourceType?: string;
38
+ tags?: string[];
39
+ }, sourceCandidate?: {
40
+ content?: string;
41
+ summary?: string;
42
+ scope?: string;
43
+ sourceType?: string;
44
+ tags?: string[];
45
+ }): boolean;
32
46
  export declare function collectMemoryCandidateLabels(candidate: {
33
47
  kind?: string;
34
48
  scope?: string;
@@ -110,6 +110,25 @@ export function shouldRecallDurableMemory(text) {
110
110
  function normalizePolicyLabel(value) {
111
111
  return value.trim().toLowerCase().replace(/[\s-]+/g, "_");
112
112
  }
113
+ function normalizeMemoryText(value) {
114
+ return typeof value === "string" ? value.trim().toLowerCase() : "";
115
+ }
116
+ function hasTranscriptReflectionSource(input) {
117
+ const sourceType = normalizeMemoryText(input.sourceType);
118
+ void input.tags;
119
+ return sourceType === "runtime-transcript" || sourceType === "runtime-reflection";
120
+ }
121
+ export function isNonDurableTranscriptWorkflowMemory(input, sourceCandidate) {
122
+ if (!hasTranscriptReflectionSource({
123
+ sourceType: input.sourceType ?? sourceCandidate?.sourceType,
124
+ tags: [...(input.tags ?? []), ...(sourceCandidate?.tags ?? [])],
125
+ })) {
126
+ return false;
127
+ }
128
+ const kind = normalizeMemoryText(input.kind);
129
+ const scope = normalizeMemoryText(input.scope ?? sourceCandidate?.scope);
130
+ return kind === "procedural" || scope === "user" || scope === "workspace" || scope === "project";
131
+ }
113
132
  export function collectMemoryCandidateLabels(candidate) {
114
133
  return Array.from(new Set([
115
134
  ...(candidate.kind ? [normalizePolicyLabel(candidate.kind)] : []),
@@ -1,3 +1,4 @@
1
- export { BROWSER_CAPABILITY_DISCLAIMER_RECOVERY_INSTRUCTION, EXECUTION_WITH_TOOL_EVIDENCE_INSTRUCTION, EXECUTION_WITH_TOOL_EVIDENCE_RETRY_INSTRUCTION, INVALID_TOOL_SELECTION_RECOVERY_INSTRUCTION, STRICT_TOOL_JSON_INSTRUCTION, WORKSPACE_RELATIVE_PATH_INSTRUCTION, WRITE_TODOS_DESCRIPTIVE_CONTENT_INSTRUCTION, WRITE_TODOS_FULL_ENTRY_INSTRUCTION, WRITE_TODOS_NON_EMPTY_INITIAL_LIST_INSTRUCTION, appendToolRecoveryInstruction, isRepairableWriteTodosContentFailure, isRepairableWriteTodosEmptyFailure, isRepairableWriteTodosPlaceholderFailure, isRetrySafeInvalidToolSelectionError, isToolCallRecoveryFailure, isToolCallValidationFailure, isWorkspacePathScopeFailure, resolveExecutionWithoutToolEvidenceInstruction, resolveExecutionWithoutToolEvidenceTextInstruction, resolveToolCallRecoveryInstruction, shouldValidateExecutionWithoutToolEvidence, wrapResolvedModel, } from "./output-recovery.js";
1
+ export { appendToolRecoveryInstruction, isRepairableWriteTodosContentFailure, isRepairableWriteTodosEmptyFailure, isRepairableWriteTodosPlaceholderFailure, isRetrySafeInvalidToolSelectionError, isToolCallRecoveryFailure, isToolCallValidationFailure, isWorkspacePathScopeFailure, resolveExecutionWithoutToolEvidenceInstruction, resolveExecutionWithoutToolEvidenceTextInstruction, resolveToolCallRecoveryInstruction, shouldValidateExecutionWithoutToolEvidence, wrapResolvedModel, } from "./output-recovery.js";
2
+ export { BROWSER_CAPABILITY_DISCLAIMER_RECOVERY_INSTRUCTION, EXECUTION_WITH_TOOL_EVIDENCE_INSTRUCTION, EXECUTION_WITH_TOOL_EVIDENCE_RETRY_INSTRUCTION, INVALID_TOOL_SELECTION_RECOVERY_INSTRUCTION, STRICT_TOOL_JSON_INSTRUCTION, WORKSPACE_RELATIVE_PATH_INSTRUCTION, WRITE_TODOS_DESCRIPTIVE_CONTENT_INSTRUCTION, WRITE_TODOS_FULL_ENTRY_INSTRUCTION, WRITE_TODOS_NON_EMPTY_INITIAL_LIST_INSTRUCTION, } from "../prompts/runtime-prompts.js";
2
3
  export { containsLikelySkillDocument, extractContentBlocks, extractEmptyAssistantMessageFailure, extractOutputContent, extractReasoningText, extractToolFallbackContext, extractVisibleOutput, hasToolCalls, readTextContent, sanitizeVisibleText, } from "./output-content.js";
3
4
  export { isLikelyToolArgsObject, salvageToolArgs, tryParseJson, } from "./output-tool-args.js";
@@ -1,3 +1,4 @@
1
- export { BROWSER_CAPABILITY_DISCLAIMER_RECOVERY_INSTRUCTION, EXECUTION_WITH_TOOL_EVIDENCE_INSTRUCTION, EXECUTION_WITH_TOOL_EVIDENCE_RETRY_INSTRUCTION, INVALID_TOOL_SELECTION_RECOVERY_INSTRUCTION, STRICT_TOOL_JSON_INSTRUCTION, WORKSPACE_RELATIVE_PATH_INSTRUCTION, WRITE_TODOS_DESCRIPTIVE_CONTENT_INSTRUCTION, WRITE_TODOS_FULL_ENTRY_INSTRUCTION, WRITE_TODOS_NON_EMPTY_INITIAL_LIST_INSTRUCTION, appendToolRecoveryInstruction, isRepairableWriteTodosContentFailure, isRepairableWriteTodosEmptyFailure, isRepairableWriteTodosPlaceholderFailure, isRetrySafeInvalidToolSelectionError, isToolCallRecoveryFailure, isToolCallValidationFailure, isWorkspacePathScopeFailure, resolveExecutionWithoutToolEvidenceInstruction, resolveExecutionWithoutToolEvidenceTextInstruction, resolveToolCallRecoveryInstruction, shouldValidateExecutionWithoutToolEvidence, wrapResolvedModel, } from "./output-recovery.js";
1
+ export { appendToolRecoveryInstruction, isRepairableWriteTodosContentFailure, isRepairableWriteTodosEmptyFailure, isRepairableWriteTodosPlaceholderFailure, isRetrySafeInvalidToolSelectionError, isToolCallRecoveryFailure, isToolCallValidationFailure, isWorkspacePathScopeFailure, resolveExecutionWithoutToolEvidenceInstruction, resolveExecutionWithoutToolEvidenceTextInstruction, resolveToolCallRecoveryInstruction, shouldValidateExecutionWithoutToolEvidence, wrapResolvedModel, } from "./output-recovery.js";
2
+ export { BROWSER_CAPABILITY_DISCLAIMER_RECOVERY_INSTRUCTION, EXECUTION_WITH_TOOL_EVIDENCE_INSTRUCTION, EXECUTION_WITH_TOOL_EVIDENCE_RETRY_INSTRUCTION, INVALID_TOOL_SELECTION_RECOVERY_INSTRUCTION, STRICT_TOOL_JSON_INSTRUCTION, WORKSPACE_RELATIVE_PATH_INSTRUCTION, WRITE_TODOS_DESCRIPTIVE_CONTENT_INSTRUCTION, WRITE_TODOS_FULL_ENTRY_INSTRUCTION, WRITE_TODOS_NON_EMPTY_INITIAL_LIST_INSTRUCTION, } from "../prompts/runtime-prompts.js";
2
3
  export { containsLikelySkillDocument, extractContentBlocks, extractEmptyAssistantMessageFailure, extractOutputContent, extractReasoningText, extractToolFallbackContext, extractVisibleOutput, hasToolCalls, readTextContent, sanitizeVisibleText, } from "./output-content.js";
3
4
  export { isLikelyToolArgsObject, salvageToolArgs, tryParseJson, } from "./output-tool-args.js";
@@ -8,8 +8,10 @@ export declare function isToolCallRecoveryFailure(error: unknown): boolean;
8
8
  export declare function isRetrySafeInvalidToolSelectionError(value: unknown): boolean;
9
9
  export declare function shouldValidateExecutionWithoutToolEvidence(request: unknown): boolean;
10
10
  export declare function resolveExecutionWithoutToolEvidenceInstruction(request: unknown, result: unknown): string | null;
11
- export declare function resolveExecutionWithoutToolEvidenceTextInstruction(request: unknown, assistantText: string, toolCallEvidence?: boolean): string | null;
11
+ export declare function resolveExecutionWithoutToolEvidenceTextInstruction(request: unknown, assistantText: string, toolCallEvidence?: boolean, resultEvidence?: {
12
+ hasWriteTodosEvidence?: boolean;
13
+ hasToolResultEvidence?: boolean;
14
+ }): string | null;
12
15
  export declare function resolveToolCallRecoveryInstruction(error: unknown): string | null;
13
16
  export declare function appendToolRecoveryInstruction(input: unknown, instruction: string): unknown;
14
17
  export declare function wrapResolvedModel<T>(value: T): T;
15
- export { AUTONOMOUS_INVESTIGATION_RECOVERY_INSTRUCTION, BROWSER_CAPABILITY_DISCLAIMER_RECOVERY_INSTRUCTION, EXECUTION_WITH_TOOL_EVIDENCE_INSTRUCTION, EXECUTION_WITH_TOOL_EVIDENCE_RETRY_INSTRUCTION, INTERNAL_RUNTIME_SPILL_PATH_INSTRUCTION, INVALID_TOOL_SELECTION_RECOVERY_INSTRUCTION, STRICT_TOOL_JSON_INSTRUCTION, WORKSPACE_RELATIVE_PATH_INSTRUCTION, WRITE_TODOS_DESCRIPTIVE_CONTENT_INSTRUCTION, WRITE_TODOS_FULL_ENTRY_INSTRUCTION, WRITE_TODOS_NON_EMPTY_INITIAL_LIST_INSTRUCTION } from "../prompts/runtime-prompts.js";