@noetic-tools/core 0.2.1 → 1.0.0

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 (207) hide show
  1. package/dist/adapters/in-memory-fs-adapter.d.ts +1 -1
  2. package/dist/adapters/in-memory-fs-adapter.js +1 -1
  3. package/dist/adapters/in-memory-shell-adapter.d.ts +1 -1
  4. package/dist/adapters/in-memory-subprocess/manifest-persistence.d.ts +2 -2
  5. package/dist/adapters/in-memory-subprocess/metadata.d.ts +1 -1
  6. package/dist/adapters/in-memory-subprocess/types.d.ts +2 -2
  7. package/dist/adapters/in-memory-subprocess-adapter.d.ts +1 -1
  8. package/dist/adapters/openrouter.d.ts +2 -6
  9. package/dist/adapters/openrouter.js +1 -4
  10. package/dist/builders/channel-builder.d.ts +1 -1
  11. package/dist/builders/control-flow-builders.d.ts +2 -3
  12. package/dist/builders/control-flow-builders.js +1 -2
  13. package/dist/builders/every.d.ts +2 -3
  14. package/dist/builders/every.js +1 -1
  15. package/dist/builders/layer-provides-builders.d.ts +1 -1
  16. package/dist/builders/layer-provides-builders.js +1 -1
  17. package/dist/builders/loop-builder.d.ts +2 -2
  18. package/dist/builders/loop-builder.js +1 -1
  19. package/dist/builders/memory-builder.d.ts +1 -1
  20. package/dist/builders/memory-builder.js +1 -1
  21. package/dist/builders/provide-builder.d.ts +2 -2
  22. package/dist/builders/provide-builder.js +1 -1
  23. package/dist/builders/spawn-builder.d.ts +2 -3
  24. package/dist/builders/spawn-builder.js +1 -1
  25. package/dist/builders/step-builders.d.ts +2 -6
  26. package/dist/builders/step-builders.js +1 -1
  27. package/dist/builders/tool-builder.d.ts +1 -3
  28. package/dist/builders/tool-builder.js +1 -1
  29. package/dist/builders/workflow-hydrator.d.ts +2 -3
  30. package/dist/builders/workflow-hydrator.js +1 -2
  31. package/dist/conditions/conditions.d.ts +2 -3
  32. package/dist/conditions/conditions.js +1 -1
  33. package/dist/harness/agent-harness.d.ts +15 -5
  34. package/dist/harness/agent-harness.js +65 -10
  35. package/dist/harness/deps/memory.d.ts +2 -5
  36. package/dist/harness/deps/memory.js +1 -4
  37. package/dist/harness/deps/types.d.ts +3 -16
  38. package/dist/harness/deps/types.js +1 -1
  39. package/dist/harness/model-call.d.ts +1 -3
  40. package/dist/harness/model-call.js +10 -10
  41. package/dist/harness/model-schema.d.ts +10 -4
  42. package/dist/harness/model-schema.js +9 -1
  43. package/dist/index.d.ts +28 -49
  44. package/dist/index.js +9 -27
  45. package/dist/interpreter/action-deps.d.ts +4 -8
  46. package/dist/interpreter/action-deps.js +2 -6
  47. package/dist/interpreter/action-types.d.ts +3 -8
  48. package/dist/interpreter/action-types.js +1 -1
  49. package/dist/interpreter/collect-tools.d.ts +1 -2
  50. package/dist/interpreter/collect-tools.js +1 -1
  51. package/dist/interpreter/execute-action.js +122 -27
  52. package/dist/interpreter/execute-control.d.ts +1 -2
  53. package/dist/interpreter/execute-control.js +60 -7
  54. package/dist/interpreter/execute.d.ts +2 -3
  55. package/dist/interpreter/execute.js +1 -2
  56. package/dist/interpreter/message-helpers.d.ts +1 -1
  57. package/dist/interpreter/message-helpers.js +1 -1
  58. package/dist/interpreter/step-dispatcher.d.ts +2 -5
  59. package/dist/interpreter/typeguards.d.ts +3 -4
  60. package/dist/interpreter/typeguards.js +1 -1
  61. package/dist/observability/span-impl.d.ts +1 -1
  62. package/dist/observability/trace-exporter.d.ts +1 -1
  63. package/dist/patterns/dynamic-workflow.d.ts +2 -5
  64. package/dist/patterns/dynamic-workflow.js +1 -2
  65. package/dist/patterns/flow.d.ts +2 -2
  66. package/dist/patterns/flow.js +1 -1
  67. package/dist/patterns/interview.d.ts +2 -2
  68. package/dist/patterns/interview.js +1 -1
  69. package/dist/patterns/plans.d.ts +2 -3
  70. package/dist/patterns/plans.js +1 -1
  71. package/dist/patterns/ralph-wiggum.d.ts +2 -3
  72. package/dist/patterns/react.d.ts +2 -3
  73. package/dist/portable/memory-layers.d.ts +1 -7
  74. package/dist/portable/memory-layers.js +1 -7
  75. package/dist/portable.d.ts +2 -2
  76. package/dist/portable.js +2 -2
  77. package/dist/runtime/broadcaster-utils.d.ts +1 -1
  78. package/dist/runtime/channel-store.d.ts +43 -3
  79. package/dist/runtime/channel-store.js +233 -37
  80. package/dist/runtime/context-deps.d.ts +3 -3
  81. package/dist/runtime/context-deps.js +2 -2
  82. package/dist/runtime/context-impl.d.ts +17 -1
  83. package/dist/runtime/context-impl.js +30 -3
  84. package/dist/runtime/context-type-deps.d.ts +2 -11
  85. package/dist/runtime/cwd-helpers.d.ts +1 -1
  86. package/dist/runtime/detached-handle.d.ts +2 -3
  87. package/dist/runtime/detached-handle.js +1 -3
  88. package/dist/runtime/durable/checkpoint-store.d.ts +1 -1
  89. package/dist/runtime/durable/checkpoint-store.js +1 -1
  90. package/dist/runtime/durable/harness-checkpoints.d.ts +2 -5
  91. package/dist/runtime/durable/runnable-loop.d.ts +1 -3
  92. package/dist/runtime/durable/session-seed.d.ts +1 -1
  93. package/dist/runtime/durable/stall-nudge.d.ts +17 -10
  94. package/dist/runtime/durable/stall-nudge.js +29 -10
  95. package/dist/runtime/event-broadcaster.d.ts +10 -2
  96. package/dist/runtime/event-broadcaster.js +43 -19
  97. package/dist/runtime/in-memory-storage.d.ts +1 -1
  98. package/dist/runtime/in-memory-storage.js +1 -1
  99. package/dist/runtime/item-log-impl.d.ts +1 -3
  100. package/dist/runtime/item-log-impl.js +1 -1
  101. package/dist/runtime/message-queue.d.ts +1 -2
  102. package/dist/runtime/session-runner.d.ts +1 -4
  103. package/dist/runtime/session-streams.d.ts +1 -2
  104. package/dist/runtime/session-streams.js +1 -1
  105. package/dist/runtime/step-registry.d.ts +2 -2
  106. package/dist/runtime/step-registry.js +1 -2
  107. package/dist/runtime/tool-memory.d.ts +1 -3
  108. package/dist/types/mutable-context.d.ts +2 -3
  109. package/dist/types/step-registrar.d.ts +1 -1
  110. package/dist/unstable.d.ts +5 -9
  111. package/dist/unstable.js +3 -6
  112. package/dist/until/combinators.d.ts +1 -1
  113. package/dist/until/never.d.ts +1 -1
  114. package/dist/until/predicates.d.ts +2 -2
  115. package/package.json +4 -2
  116. package/dist/errors/noetic-config-error.d.ts +0 -41
  117. package/dist/errors/noetic-config-error.js +0 -44
  118. package/dist/errors/noetic-error.d.ts +0 -18
  119. package/dist/errors/noetic-error.js +0 -54
  120. package/dist/memory/budget.d.ts +0 -23
  121. package/dist/memory/budget.js +0 -117
  122. package/dist/memory/exec-context-factory.d.ts +0 -25
  123. package/dist/memory/exec-context-factory.js +0 -30
  124. package/dist/memory/flow-schema.d.ts +0 -52
  125. package/dist/memory/flow-schema.js +0 -102
  126. package/dist/memory/function-call-utils.d.ts +0 -6
  127. package/dist/memory/function-call-utils.js +0 -27
  128. package/dist/memory/layer-api.d.ts +0 -14
  129. package/dist/memory/layer-api.js +0 -91
  130. package/dist/memory/layer-lifecycle.d.ts +0 -160
  131. package/dist/memory/layer-lifecycle.js +0 -552
  132. package/dist/memory/layer-provides.d.ts +0 -32
  133. package/dist/memory/layer-provides.js +0 -33
  134. package/dist/memory/layer-usage.d.ts +0 -16
  135. package/dist/memory/layer-usage.js +0 -54
  136. package/dist/memory/layers/durable-task-state.d.ts +0 -79
  137. package/dist/memory/layers/durable-task-state.js +0 -118
  138. package/dist/memory/layers/file-reference.d.ts +0 -55
  139. package/dist/memory/layers/file-reference.js +0 -594
  140. package/dist/memory/layers/history-window.d.ts +0 -29
  141. package/dist/memory/layers/history-window.js +0 -114
  142. package/dist/memory/layers/observational-memory.d.ts +0 -53
  143. package/dist/memory/layers/observational-memory.js +0 -109
  144. package/dist/memory/layers/plan.d.ts +0 -55
  145. package/dist/memory/layers/plan.js +0 -374
  146. package/dist/memory/layers/static-content.d.ts +0 -27
  147. package/dist/memory/layers/static-content.js +0 -35
  148. package/dist/memory/layers/steering.d.ts +0 -51
  149. package/dist/memory/layers/steering.js +0 -258
  150. package/dist/memory/layers/temporal.d.ts +0 -91
  151. package/dist/memory/layers/temporal.js +0 -245
  152. package/dist/memory/layers/tool-memory-layer.d.ts +0 -16
  153. package/dist/memory/layers/tool-memory-layer.js +0 -43
  154. package/dist/memory/layers/working-memory.d.ts +0 -44
  155. package/dist/memory/layers/working-memory.js +0 -92
  156. package/dist/memory/projector.d.ts +0 -10
  157. package/dist/memory/projector.js +0 -19
  158. package/dist/memory/scope.d.ts +0 -3
  159. package/dist/memory/scope.js +0 -31
  160. package/dist/memory/strip-unresolved.d.ts +0 -13
  161. package/dist/memory/strip-unresolved.js +0 -35
  162. package/dist/schemas/item.d.ts +0 -35
  163. package/dist/schemas/item.js +0 -155
  164. package/dist/types/channel.d.ts +0 -29
  165. package/dist/types/channel.js +0 -1
  166. package/dist/types/common.d.ts +0 -68
  167. package/dist/types/common.js +0 -1
  168. package/dist/types/context-parts/item-log.d.ts +0 -6
  169. package/dist/types/context-parts/item-log.js +0 -1
  170. package/dist/types/context-parts/layer-usage.d.ts +0 -18
  171. package/dist/types/context-parts/layer-usage.js +0 -1
  172. package/dist/types/context.d.ts +0 -202
  173. package/dist/types/context.js +0 -1
  174. package/dist/types/detached.d.ts +0 -17
  175. package/dist/types/detached.js +0 -7
  176. package/dist/types/error.d.ts +0 -66
  177. package/dist/types/error.js +0 -1
  178. package/dist/types/fs-adapter.d.ts +0 -51
  179. package/dist/types/fs-adapter.js +0 -3
  180. package/dist/types/harness-result.d.ts +0 -43
  181. package/dist/types/harness-result.js +0 -2
  182. package/dist/types/items.d.ts +0 -131
  183. package/dist/types/items.js +0 -2
  184. package/dist/types/memory-context.d.ts +0 -39
  185. package/dist/types/memory-context.js +0 -1
  186. package/dist/types/memory.d.ts +0 -306
  187. package/dist/types/memory.js +0 -13
  188. package/dist/types/observability.d.ts +0 -30
  189. package/dist/types/observability.js +0 -1
  190. package/dist/types/runtime.d.ts +0 -256
  191. package/dist/types/runtime.js +0 -1
  192. package/dist/types/shell-adapter.d.ts +0 -34
  193. package/dist/types/shell-adapter.js +0 -10
  194. package/dist/types/steering.d.ts +0 -89
  195. package/dist/types/steering.js +0 -14
  196. package/dist/types/step.d.ts +0 -231
  197. package/dist/types/step.js +0 -1
  198. package/dist/types/subprocess-adapter.d.ts +0 -157
  199. package/dist/types/subprocess-adapter.js +0 -3
  200. package/dist/types/tool-context.d.ts +0 -34
  201. package/dist/types/tool-context.js +0 -1
  202. package/dist/types/tool.d.ts +0 -64
  203. package/dist/types/tool.js +0 -1
  204. package/dist/util/framework-cast.d.ts +0 -10
  205. package/dist/util/framework-cast.js +0 -16
  206. package/dist/util/message-helpers.d.ts +0 -17
  207. package/dist/util/message-helpers.js +0 -64
@@ -1,3 +1,3 @@
1
- import type { FsAdapter } from '../types/fs-adapter.js';
1
+ import type { FsAdapter } from '@noetic-tools/types';
2
2
  /** @public Create a process-local, POSIX-like in-memory filesystem adapter. */
3
3
  export declare function createInMemoryFsAdapter(seed?: Record<string, string | Uint8Array>): FsAdapter;
@@ -1,4 +1,4 @@
1
- import { frameworkCast } from '../util/framework-cast.js';
1
+ import { frameworkCast } from '@noetic-tools/types';
2
2
  function normalizePath(path) {
3
3
  const raw = path.trim();
4
4
  if (raw.length === 0) {
@@ -1,4 +1,4 @@
1
- import type { ShellAdapter } from '../types/shell-adapter.js';
1
+ import type { ShellAdapter } from '@noetic-tools/types';
2
2
  /**
3
3
  * @public Create a portable shell adapter that does not execute host processes.
4
4
  *
@@ -1,5 +1,5 @@
1
- import type { StorageAdapter } from '../../types/memory.js';
2
- import type { StepSubprocessRequest, SubprocessHandle } from '../../types/subprocess-adapter.js';
1
+ import type { StorageAdapter } from '@noetic-tools/memory';
2
+ import type { StepSubprocessRequest, SubprocessHandle } from '@noetic-tools/types';
3
3
  import type { InMemoryStepManifest } from './types.js';
4
4
  export declare function isStepManifest(value: unknown): value is InMemoryStepManifest;
5
5
  export declare function persistStepManifest(storage: StorageAdapter, request: StepSubprocessRequest, handle: SubprocessHandle): Promise<void>;
@@ -1,4 +1,4 @@
1
- import type { ProcessSubprocessRequest, SerializedError, StepSubprocessRequest, SubprocessHandleMetadata, SubprocessRequest } from '../../types/subprocess-adapter.js';
1
+ import type { ProcessSubprocessRequest, SerializedError, StepSubprocessRequest, SubprocessHandleMetadata, SubprocessRequest } from '@noetic-tools/types';
2
2
  export declare function nowIso(): string;
3
3
  export declare function isStepRequest(request: SubprocessRequest): request is StepSubprocessRequest;
4
4
  export declare function isProcessRequest(request: SubprocessRequest): request is ProcessSubprocessRequest;
@@ -1,5 +1,5 @@
1
- import type { StorageAdapter } from '../../types/memory.js';
2
- import type { ProcessSubprocessRequest, StepSubprocessRequest, SubprocessHandle, SubprocessHandleMetadata, SubprocessRequest } from '../../types/subprocess-adapter.js';
1
+ import type { StorageAdapter } from '@noetic-tools/memory';
2
+ import type { ProcessSubprocessRequest, StepSubprocessRequest, SubprocessHandle, SubprocessHandleMetadata, SubprocessRequest } from '@noetic-tools/types';
3
3
  /**
4
4
  * @public
5
5
  * Options for `createInMemorySubprocessAdapter`. All hooks are optional;
@@ -1,4 +1,4 @@
1
- import type { SubprocessAdapter } from '../types/subprocess-adapter.js';
1
+ import type { SubprocessAdapter } from '@noetic-tools/types';
2
2
  import type { CreateInMemorySubprocessAdapterOptions } from './in-memory-subprocess/types.js';
3
3
  export type { CreateInMemorySubprocessAdapterOptions } from './in-memory-subprocess/types.js';
4
4
  /**
@@ -1,11 +1,7 @@
1
+ import type { MemoryLayer } from '@noetic-tools/memory';
2
+ import type { AgentHarnessContract, Context, Item, LLMResponse, Tool } from '@noetic-tools/types';
1
3
  import type * as OpenRouterAgent from '@openrouter/agent';
2
- import type { LLMResponse } from '../types/common.js';
3
- import type { Context } from '../types/context.js';
4
4
  import type { EmbedFn } from '../types/embed.js';
5
- import type { Item } from '../types/items.js';
6
- import type { MemoryLayer } from '../types/memory.js';
7
- import type { AgentHarnessContract } from '../types/runtime.js';
8
- import type { Tool } from '../types/tool.js';
9
5
  type ProviderOutputItem = OpenRouterAgent.OpenResponsesResult['output'][number];
10
6
  type OpenRouterInputItem = OpenRouterAgent.EasyInputMessage | OpenRouterAgent.FunctionCallItem | OpenRouterAgent.FunctionCallOutputItem | ProviderOutputItem;
11
7
  /** @internal */
@@ -1,9 +1,6 @@
1
+ import { frameworkCast, isAssistantMessage, NoeticConfigError, SteeringAction, } from '@noetic-tools/types';
1
2
  import { z } from 'zod';
2
- import { NoeticConfigError } from '../errors/noetic-config-error.js';
3
3
  import { buildToolExecutionContext } from '../runtime/tool-memory.js';
4
- import { SteeringAction } from '../types/steering.js';
5
- import { frameworkCast } from '../util/framework-cast.js';
6
- import { isAssistantMessage } from '../util/message-helpers.js';
7
4
  const EmbeddingsResponseSchema = z.object({
8
5
  data: z.array(z.object({
9
6
  embedding: z.array(z.number()),
@@ -1,5 +1,5 @@
1
+ import type { Channel, ExternalChannel } from '@noetic-tools/types';
1
2
  import type { ZodType } from 'zod';
2
- import type { Channel, ExternalChannel } from '../types/channel.js';
3
3
  /**
4
4
  * Creates a typed communication channel writable from outside the execution tree.
5
5
  *
@@ -1,6 +1,5 @@
1
- import type { Context } from '../types/context.js';
2
- import type { ContextMemory } from '../types/memory.js';
3
- import type { SettleResult, Step, StepBranch, StepForkAll, StepForkRace, StepForkSettle } from '../types/step.js';
1
+ import type { ContextMemory } from '@noetic-tools/memory';
2
+ import type { Context, SettleResult, Step, StepBranch, StepForkAll, StepForkRace, StepForkSettle } from '@noetic-tools/types';
4
3
  /**
5
4
  * Creates a parallel execution step that races paths and returns the first result.
6
5
  *
@@ -1,6 +1,5 @@
1
- import { NoeticConfigError } from '../errors/noetic-config-error.js';
1
+ import { frameworkCast, NoeticConfigError } from '@noetic-tools/types';
2
2
  import { getDefaultRegistrar } from '../types/step-registrar.js';
3
- import { frameworkCast } from '../util/framework-cast.js';
4
3
  export function fork(opts) {
5
4
  if (!opts.id || opts.id.trim() === '') {
6
5
  throw new NoeticConfigError({
@@ -1,6 +1,5 @@
1
- import type { Channel } from '../types/channel.js';
2
- import type { ContextMemory } from '../types/memory.js';
3
- import type { EveryErrorPolicy, Step, StepEvery } from '../types/step.js';
1
+ import type { ContextMemory } from '@noetic-tools/memory';
2
+ import type { Channel, EveryErrorPolicy, Step, StepEvery } from '@noetic-tools/types';
4
3
  /**
5
4
  * Configuration options accepted by the `every()` builder, excluding the `kind`
6
5
  * discriminant. `every()` schedules a body step on a fixed-interval, optionally
@@ -1,4 +1,4 @@
1
- import { NoeticConfigError } from '../errors/noetic-config-error.js';
1
+ import { NoeticConfigError } from '@noetic-tools/types';
2
2
  import { getDefaultRegistrar } from '../types/step-registrar.js';
3
3
  /**
4
4
  * Creates an `every` step that runs a body step on a fixed-interval schedule.
@@ -1 +1 @@
1
- export { layerData, layerFn } from '../memory/layer-provides.js';
1
+ export { layerData, layerFn } from '@noetic-tools/memory';
@@ -1 +1 @@
1
- export { layerData, layerFn } from '../memory/layer-provides.js';
1
+ export { layerData, layerFn } from '@noetic-tools/memory';
@@ -1,5 +1,5 @@
1
- import type { ContextMemory } from '../types/memory.js';
2
- import type { StepLoop } from '../types/step.js';
1
+ import type { ContextMemory } from '@noetic-tools/memory';
2
+ import type { StepLoop } from '@noetic-tools/types';
3
3
  /** @public Configuration options accepted by the `loop()` builder, excluding the `kind` discriminant. */
4
4
  export type LoopConfig<TMemory = ContextMemory, I = unknown, O = unknown> = Omit<StepLoop<TMemory, I, O>, 'kind'>;
5
5
  /**
@@ -1,4 +1,4 @@
1
- import { NoeticConfigError } from '../errors/noetic-config-error.js';
1
+ import { NoeticConfigError } from '@noetic-tools/types';
2
2
  import { getDefaultRegistrar } from '../types/step-registrar.js';
3
3
  /**
4
4
  * Creates a loop step that iterates a body step until a termination predicate is satisfied.
@@ -1,4 +1,4 @@
1
- import type { MemoryConfig, MemoryLayer } from '../types/memory.js';
1
+ import type { MemoryConfig, MemoryLayer } from '@noetic-tools/memory';
2
2
  /**
3
3
  * Creates a type-safe memory configuration from a tuple of memory layers.
4
4
  * The returned config preserves literal layer types for compile-time inference
@@ -1,4 +1,4 @@
1
- import { frameworkCast } from '../util/framework-cast.js';
1
+ import { frameworkCast } from '@noetic-tools/types';
2
2
  /**
3
3
  * Creates a type-safe memory configuration from a tuple of memory layers.
4
4
  * The returned config preserves literal layer types for compile-time inference
@@ -1,5 +1,5 @@
1
- import type { ContextMemory, MemoryConfig, MemoryLayer } from '../types/memory.js';
2
- import type { Step, StepProvide } from '../types/step.js';
1
+ import type { ContextMemory, MemoryConfig, MemoryLayer } from '@noetic-tools/memory';
2
+ import type { Step, StepProvide } from '@noetic-tools/types';
3
3
  /**
4
4
  * Creates a provide step that attaches memory layers to its child without creating an isolated context.
5
5
  * Like React's Context.Provider — layers are available to all descendant steps.
@@ -1,4 +1,4 @@
1
- import { NoeticConfigError } from '../errors/noetic-config-error.js';
1
+ import { NoeticConfigError } from '@noetic-tools/types';
2
2
  import { getDefaultRegistrar } from '../types/step-registrar.js';
3
3
  /**
4
4
  * Creates a provide step that attaches memory layers to its child without creating an isolated context.
@@ -1,6 +1,5 @@
1
- import type { ContextMemory, MemoryConfig, MemoryLayer } from '../types/memory.js';
2
- import type { Step, StepSpawn } from '../types/step.js';
3
- import type { SubprocessAdapter } from '../types/subprocess-adapter.js';
1
+ import type { ContextMemory, MemoryConfig, MemoryLayer } from '@noetic-tools/memory';
2
+ import type { Step, StepSpawn, SubprocessAdapter } from '@noetic-tools/types';
4
3
  interface SpawnOpts<TMemory, I, O> {
5
4
  id: string;
6
5
  child: Step<TMemory, I, O>;
@@ -1,4 +1,4 @@
1
- import { NoeticConfigError } from '../errors/noetic-config-error.js';
1
+ import { NoeticConfigError } from '@noetic-tools/types';
2
2
  import { getDefaultRegistrar } from '../types/step-registrar.js';
3
3
  //#endregion
4
4
  //#region Public API
@@ -1,10 +1,6 @@
1
+ import type { ContextMemory } from '@noetic-tools/memory';
2
+ import type { Context, Lazy, ModelParams, RetryPolicy, StepLLM, StepRun, StepTool, SubprocessAdapter, Tool } from '@noetic-tools/types';
1
3
  import type { ZodType } from 'zod';
2
- import type { ModelParams, RetryPolicy } from '../types/common.js';
3
- import type { Context } from '../types/context.js';
4
- import type { ContextMemory } from '../types/memory.js';
5
- import type { Lazy, StepLLM, StepRun, StepTool } from '../types/step.js';
6
- import type { SubprocessAdapter } from '../types/subprocess-adapter.js';
7
- import type { Tool } from '../types/tool.js';
8
4
  interface StepRunOpts<TMemory, I, O> {
9
5
  id: string;
10
6
  execute: (input: I, ctx: Context<TMemory>) => Promise<O>;
@@ -1,4 +1,4 @@
1
- import { NoeticConfigError } from '../errors/noetic-config-error.js';
1
+ import { NoeticConfigError } from '@noetic-tools/types';
2
2
  import { getDefaultRegistrar } from '../types/step-registrar.js';
3
3
  //#endregion
4
4
  //#region Builders
@@ -1,7 +1,5 @@
1
+ import type { FunctionCallItem, FunctionCallOutputItem, Item, ItemSchemaExtensions, Tool, ToolExecutionContext, ToolMemoryDeclaration, ToolResultExtensionItem } from '@noetic-tools/types';
1
2
  import type { ZodTypeAny, z } from 'zod';
2
- import type { FunctionCallItem, FunctionCallOutputItem, Item, ItemSchemaExtensions, ToolResultExtensionItem } from '../types/items.js';
3
- import type { Tool, ToolMemoryDeclaration } from '../types/tool.js';
4
- import type { ToolExecutionContext } from '../types/tool-context.js';
5
3
  interface ToolConfig<I extends ZodTypeAny, O extends ZodTypeAny> {
6
4
  name: string;
7
5
  description: string;
@@ -1,4 +1,4 @@
1
- import { NoeticConfigError } from '../errors/noetic-config-error.js';
1
+ import { NoeticConfigError } from '@noetic-tools/types';
2
2
  //#endregion
3
3
  //#region Helpers
4
4
  function validateToolConfig(name, execute) {
@@ -5,10 +5,9 @@
5
5
  * `loop`, etc.) so hydrated steps are indistinguishable from programmatic
6
6
  * ones — they register in the step registry, carry retry policies, etc.
7
7
  */
8
+ import type { ContextMemory, MemoryLayer } from '@noetic-tools/memory';
9
+ import type { ExecuteStepFn, Step, Tool } from '@noetic-tools/types';
8
10
  import type { WorkflowDocument, WorkflowNode } from '../schemas/workflow.js';
9
- import type { ContextMemory, MemoryLayer } from '../types/memory.js';
10
- import type { ExecuteStepFn, Step } from '../types/step.js';
11
- import type { Tool } from '../types/tool.js';
12
11
  /** @public Context required to hydrate a JSON workflow into live steps. */
13
12
  export interface HydrationContext {
14
13
  tools: ReadonlyMap<string, Tool>;
@@ -5,10 +5,9 @@
5
5
  * `loop`, etc.) so hydrated steps are indistinguishable from programmatic
6
6
  * ones — they register in the step registry, carry retry policies, etc.
7
7
  */
8
- import { NoeticConfigError } from '../errors/noetic-config-error.js';
8
+ import { frameworkCast, NoeticConfigError } from '@noetic-tools/types';
9
9
  import { all, any } from '../until/combinators.js';
10
10
  import { until } from '../until/predicates.js';
11
- import { frameworkCast } from '../util/framework-cast.js';
12
11
  import { branch, fork } from './control-flow-builders.js';
13
12
  import { every } from './every.js';
14
13
  import { loop } from './loop-builder.js';
@@ -1,7 +1,6 @@
1
- import type { Context } from '../types/context.js';
1
+ import type { ContextMemory, StorageAdapter } from '@noetic-tools/memory';
2
+ import type { Context, Step } from '@noetic-tools/types';
2
3
  import type { EmbedFn } from '../types/embed.js';
3
- import type { ContextMemory, StorageAdapter } from '../types/memory.js';
4
- import type { Step } from '../types/step.js';
5
4
  export type Condition<I> = (input: I, ctx: Context) => Promise<boolean>;
6
5
  export interface WhenClause<TMemory = ContextMemory, I = unknown, O = unknown> {
7
6
  readonly kind: 'when';
@@ -1,5 +1,5 @@
1
+ import { createMessage, extractAssistantText, trackUsage } from '@noetic-tools/types';
1
2
  import { z } from 'zod';
2
- import { createMessage, extractAssistantText, trackUsage } from '../util/message-helpers.js';
3
3
  import { cosineSimilarity } from './cosine-similarity.js';
4
4
  //#endregion
5
5
  //#region Helpers
@@ -1,8 +1,8 @@
1
- import { ItemSchemaRegistry } from '../schemas/item.js';
1
+ import { ItemSchemaRegistry } from '@noetic-tools/types';
2
2
  import type { DetachedSpawnOverrides } from './deps/interpreter.js';
3
- import type { LayerStateStore } from './deps/memory.js';
3
+ import type { LayerStateStore, RecallCache } from './deps/memory.js';
4
4
  import type { CheckpointStore, EventBroadcaster } from './deps/runtime.js';
5
- import type { AgentConfig, AgentHarnessContract, AgentHooks, CallModelRequest, Channel, ChannelHandle, Context, ContextMemory, CwdState, DeliveryMode, DetachedHandle, ExecuteInput, ExecuteOptions, ExternalChannel, FsAdapter, HarnessResponse, HarnessStatus, Item, ItemSchemaExtensions, LLMResponse, LlmProviderConfig, MemoryLayer, RecallLayerOutput, SessionScope, ShellAdapter, Span, SteeringDecision, Step, StorageAdapter, StreamEvent, StreamingItem, SubprocessAdapter, Tool, TraceExporter, ZodType } from './deps/types.js';
5
+ import type { AgentConfig, AgentHarnessContract, AgentHooks, CallModelRequest, Channel, ChannelHandle, Context, ContextMemory, CwdState, DeliveryMode, DetachedHandle, ExecuteInput, ExecuteOptions, ExternalChannel, FsAdapter, HarnessResponse, HarnessStatus, Item, ItemSchemaExtensions, LLMResponse, LlmProviderConfig, MemoryLayer, ProjectionPolicy, RecallLayerOutput, SessionScope, ShellAdapter, Span, SteeringDecision, Step, StorageAdapter, StreamEvent, StreamingItem, SubprocessAdapter, Tool, TraceExporter, ZodType } from './deps/types.js';
6
6
  export { createStreamIdleWatchdog } from './model-call.js';
7
7
  interface AgentHarnessOpts<TParams extends Record<string, unknown> = Record<string, unknown>> {
8
8
  name: string;
@@ -38,6 +38,10 @@ interface AgentHarnessOpts<TParams extends Record<string, unknown> = Record<stri
38
38
  itemSchemas?: ItemSchemaExtensions;
39
39
  /** Whether unknown extension item types must match a registered schema. Defaults to true. */
40
40
  strictItemSchemas?: boolean;
41
+ /** Default projection policy for all LLM steps. Individual steps override via `step.projection`. */
42
+ projection?: ProjectionPolicy;
43
+ /** When true, every layer is recalled atomically regardless of its `recallMode`. */
44
+ forceAtomicRecall?: boolean;
41
45
  traceExporter?: TraceExporter;
42
46
  layerStateStore?: LayerStateStore;
43
47
  /** Default delivery mode for messages that don't specify one. Defaults to `next-turn`. */
@@ -92,6 +96,8 @@ export declare class AgentHarness<TParams extends Record<string, unknown> = Reco
92
96
  private readonly streamIdleTimeoutMs;
93
97
  private readonly sessions;
94
98
  readonly layerStateStore: LayerStateStore;
99
+ /** Per-harness memoization cache for `recallMode: 'eventual'` layers. */
100
+ readonly recallCache: RecallCache;
95
101
  readonly traceExporter: TraceExporter;
96
102
  /**
97
103
  * Long-lived shared cwd state. The same reference is seeded into every
@@ -146,8 +152,8 @@ export declare class AgentHarness<TParams extends Record<string, unknown> = Reco
146
152
  cwdInit?: string;
147
153
  _broadcaster?: EventBroadcaster;
148
154
  }): Context;
149
- send<T>(channel: Channel<T>, value: T, _ctx: Context): void;
150
- recv<T>(channel: Channel<T>, _ctx: Context, opts?: {
155
+ send<T>(channel: Channel<T>, value: T, ctx: Context): Promise<void>;
156
+ recv<T>(channel: Channel<T>, ctx: Context, opts?: {
151
157
  timeout?: number;
152
158
  }): Promise<T>;
153
159
  tryRecv<T>(channel: Channel<T>, _ctx: Context): T | null;
@@ -157,6 +163,10 @@ export declare class AgentHarness<TParams extends Record<string, unknown> = Reco
157
163
  private toExecCtx;
158
164
  initLayers(layers: MemoryLayer[], ctx: Context, storage: StorageAdapter): Promise<void>;
159
165
  recallLayers(layers: MemoryLayer[], input: string, ctx: Context): Promise<RecallLayerOutput[]>;
166
+ /** Allocate per-layer recall budgets from the harness projection policy. */
167
+ private layerBudgets;
168
+ recallLayersAtomic(layers: MemoryLayer[], input: string, ctx: Context, budgets: Map<string, number>): Promise<RecallLayerOutput[]>;
169
+ recallLayersEventual(layers: MemoryLayer[], input: string, ctx: Context, budgets: Map<string, number>): Promise<RecallLayerOutput[]>;
160
170
  /**
161
171
  * Compute the items array that would be sent to the model on the next turn —
162
172
  * the same arrangement `executeLLM` builds: harness-level memory layers'
@@ -1,11 +1,9 @@
1
- import { NoeticConfigError } from '../errors/noetic-config-error.js';
1
+ import { frameworkCast, ItemSchemaRegistry, NoeticConfigError } from '@noetic-tools/types';
2
2
  import { SpanImpl } from '../observability/span-impl.js';
3
3
  import { NoopExporter } from '../observability/trace-exporter.js';
4
- import { ItemSchemaRegistry } from '../schemas/item.js';
5
- import { frameworkCast } from '../util/framework-cast.js';
6
4
  import { createInMemoryFsAdapter, createInMemoryShellAdapter, createInMemorySubprocessAdapter, OpenRouter, } from './deps/adapters.js';
7
5
  import { collectAllTools, deduplicateTools, dispatchStepThroughAdapter, execute, } from './deps/interpreter.js';
8
- import { afterModelCallLayers, assembleView, beforeToolCallLayers, contextToExecCtx, createLayerStateStore, disposeLayers, executeRerender, initLayers, projectHistoryLayers, recallLayers, resolveLayerBudgets, resolveLayerTools, runAppendPipeline, storeLayers, } from './deps/memory.js';
6
+ import { afterModelCallLayers, allocateBudgets, assembleView, beforeToolCallLayers, contextToExecCtx, createLayerStateStore, createRecallCache, DEFAULT_PROJECTION, disposeLayers, executeRerender, initLayers, projectHistoryLayers, recallLayers, recallLayersAtomic, recallLayersEventual, resolveLayerTools, runAppendPipeline, storeLayers, } from './deps/memory.js';
9
7
  import { buildItemStream, ChannelStore, ContextImpl, captureCheckpoint, createInMemoryStorage, filterReasoningStream, filterTextStream, restoreFromCheckpoint, SessionRunner, snapshotCwdState, } from './deps/runtime.js';
10
8
  import { SteeringAction } from './deps/types.js';
11
9
  import { AgentHarnessModelCaller } from './model-call.js';
@@ -103,6 +101,8 @@ export class AgentHarness {
103
101
  streamIdleTimeoutMs;
104
102
  sessions = new Map();
105
103
  layerStateStore;
104
+ /** Per-harness memoization cache for `recallMode: 'eventual'` layers. */
105
+ recallCache;
106
106
  traceExporter;
107
107
  /**
108
108
  * Long-lived shared cwd state. The same reference is seeded into every
@@ -123,6 +123,8 @@ export class AgentHarness {
123
123
  params: validatedParams,
124
124
  itemSchemas: opts.itemSchemas,
125
125
  strictItemSchemas: opts.strictItemSchemas ?? true,
126
+ projection: opts.projection,
127
+ forceAtomicRecall: opts.forceAtomicRecall,
126
128
  };
127
129
  this.fs = opts.fs ?? createInMemoryFsAdapter();
128
130
  this.shell = opts.shell ?? createInMemoryShellAdapter();
@@ -135,7 +137,12 @@ export class AgentHarness {
135
137
  this.client = opts._testCallModel ? undefined : createClient(opts.llm);
136
138
  this.channelStore = new ChannelStore();
137
139
  this.traceExporter = opts.traceExporter ?? new NoopExporter();
138
- this.layerStateStore = opts.layerStateStore ?? createLayerStateStore();
140
+ this.layerStateStore =
141
+ opts.layerStateStore ??
142
+ createLayerStateStore((layerId, hook, error) => {
143
+ console.warn(`[noetic] memory layer '${layerId}' ${hook} error:`, error);
144
+ });
145
+ this.recallCache = createRecallCache();
139
146
  this.defaultDeliveryMode = opts.defaultDeliveryMode ?? 'next-turn';
140
147
  this.streamIdleTimeoutMs = opts.streamIdleTimeoutMs ?? DEFAULT_STREAM_IDLE_TIMEOUT_MS;
141
148
  this.itemSchemas = new ItemSchemaRegistry(opts.itemSchemas, {
@@ -363,11 +370,19 @@ export class AgentHarness {
363
370
  cwdState: resolveContextCwdState(this.rootCwdState, opts?.parent, cwdInit),
364
371
  });
365
372
  }
366
- send(channel, value, _ctx) {
367
- this.channelStore.send(channel, value);
373
+ send(channel, value, ctx) {
374
+ // Internal sender: back-pressured on full queue channels. The calling
375
+ // context's abort signal rejects a parked send with 'cancelled'.
376
+ const signal = ctx instanceof ContextImpl ? ctx.abortSignal : undefined;
377
+ return this.channelStore.send(channel, value, {
378
+ signal,
379
+ });
368
380
  }
369
- recv(channel, _ctx, opts) {
370
- return this.channelStore.recv(channel, opts?.timeout);
381
+ recv(channel, ctx, opts) {
382
+ // Wire the calling context's abort signal so ctx.abort() rejects a
383
+ // pending recv with { kind: 'cancelled' } instead of hanging.
384
+ const signal = ctx instanceof ContextImpl ? ctx.abortSignal : undefined;
385
+ return this.channelStore.recv(channel, opts?.timeout, signal);
371
386
  }
372
387
  tryRecv(channel, _ctx) {
373
388
  return this.channelStore.tryRecv(channel);
@@ -407,9 +422,48 @@ export class AgentHarness {
407
422
  query: input,
408
423
  ctx: this.toExecCtx(ctx),
409
424
  log: ctx.itemLog,
410
- budgets: resolveLayerBudgets(layers),
425
+ budgets: this.layerBudgets(layers),
426
+ store: this.layerStateStore,
427
+ itemSchemas: this.itemSchemas,
428
+ });
429
+ }
430
+ /** Allocate per-layer recall budgets from the harness projection policy. */
431
+ layerBudgets(layers) {
432
+ const policy = this.config.projection ?? DEFAULT_PROJECTION;
433
+ const { allocations } = allocateBudgets({
434
+ layers,
435
+ totalBudget: policy.tokenBudget,
436
+ systemPromptTokens: 0,
437
+ responseReserve: policy.responseReserve,
438
+ });
439
+ return new Map(allocations.map((a) => [
440
+ a.layerId,
441
+ a.allocated,
442
+ ]));
443
+ }
444
+ async recallLayersAtomic(layers, input, ctx, budgets) {
445
+ return recallLayersAtomic({
446
+ layers,
447
+ query: input,
448
+ ctx: this.toExecCtx(ctx),
449
+ log: ctx.itemLog,
450
+ budgets,
451
+ store: this.layerStateStore,
452
+ itemSchemas: this.itemSchemas,
453
+ forceAtomic: this.config.forceAtomicRecall,
454
+ });
455
+ }
456
+ async recallLayersEventual(layers, input, ctx, budgets) {
457
+ return recallLayersEventual({
458
+ layers,
459
+ query: input,
460
+ ctx: this.toExecCtx(ctx),
461
+ log: ctx.itemLog,
462
+ budgets,
411
463
  store: this.layerStateStore,
412
464
  itemSchemas: this.itemSchemas,
465
+ forceAtomic: this.config.forceAtomicRecall,
466
+ cache: this.recallCache,
413
467
  });
414
468
  }
415
469
  /**
@@ -463,6 +517,7 @@ export class AgentHarness {
463
517
  log: ctx.itemLog,
464
518
  store: this.layerStateStore,
465
519
  storage,
520
+ recallCache: this.recallCache,
466
521
  });
467
522
  }
468
523
  async disposeLayers(layers, ctx) {
@@ -1,5 +1,2 @@
1
- export { contextToExecCtx } from '../../memory/exec-context-factory.js';
2
- export { resolveLayerTools } from '../../memory/layer-api.js';
3
- export type { LayerStateStore } from '../../memory/layer-lifecycle.js';
4
- export { afterModelCallLayers, beforeToolCallLayers, createLayerStateStore, disposeLayers, executeRerender, initLayers, projectHistoryLayers, recallLayers, resolveLayerBudgets, runAppendPipeline, storeLayers, } from '../../memory/layer-lifecycle.js';
5
- export { assembleView } from '../../memory/projector.js';
1
+ export type { LayerStateStore, RecallCache } from '@noetic-tools/memory';
2
+ export { afterModelCallLayers, allocateBudgets, assembleView, beforeToolCallLayers, contextToExecCtx, createLayerStateStore, createRecallCache, DEFAULT_PROJECTION, disposeLayers, executeRerender, initLayers, projectHistoryLayers, recallLayers, recallLayersAtomic, recallLayersEventual, resolveLayerTools, runAppendPipeline, storeLayers, } from '@noetic-tools/memory';
@@ -1,4 +1 @@
1
- export { contextToExecCtx } from '../../memory/exec-context-factory.js';
2
- export { resolveLayerTools } from '../../memory/layer-api.js';
3
- export { afterModelCallLayers, beforeToolCallLayers, createLayerStateStore, disposeLayers, executeRerender, initLayers, projectHistoryLayers, recallLayers, resolveLayerBudgets, runAppendPipeline, storeLayers, } from '../../memory/layer-lifecycle.js';
4
- export { assembleView } from '../../memory/projector.js';
1
+ export { afterModelCallLayers, allocateBudgets, assembleView, beforeToolCallLayers, contextToExecCtx, createLayerStateStore, createRecallCache, DEFAULT_PROJECTION, disposeLayers, executeRerender, initLayers, projectHistoryLayers, recallLayers, recallLayersAtomic, recallLayersEventual, resolveLayerTools, runAppendPipeline, storeLayers, } from '@noetic-tools/memory';
@@ -1,17 +1,4 @@
1
+ export type { ContextMemory, ExecutionContext, MemoryLayer, ProjectionPolicy, StorageAdapter, } from '@noetic-tools/memory';
2
+ export type { AgentConfig, AgentHarnessContract, AgentHooks, CallModelRequest, Channel, ChannelHandle, Context, CwdState, DeliveryMode, DetachedHandle, ExecuteInput, ExecuteOptions, ExternalChannel, FsAdapter, HarnessResponse, HarnessStatus, Item, ItemSchemaExtensions, LLMResponse, LlmProviderConfig, RecallLayerOutput, SessionScope, ShellAdapter, Span, SteeringDecision, Step, StreamEvent, StreamingItem, SubprocessAdapter, Tool, TraceExporter, } from '@noetic-tools/types';
3
+ export { SteeringAction } from '@noetic-tools/types';
1
4
  export type { ZodType } from 'zod';
2
- export type { Channel, ChannelHandle, ExternalChannel } from '../../types/channel.js';
3
- export type { LLMResponse, LlmProviderConfig } from '../../types/common.js';
4
- export type { Context, CwdState } from '../../types/context.js';
5
- export type { DetachedHandle } from '../../types/detached.js';
6
- export type { FsAdapter } from '../../types/fs-adapter.js';
7
- export type { HarnessResponse, StreamEvent, StreamingItem } from '../../types/harness-result.js';
8
- export type { ExecuteInput, Item, ItemSchemaExtensions } from '../../types/items.js';
9
- export type { ContextMemory, ExecutionContext, MemoryLayer, StorageAdapter, } from '../../types/memory.js';
10
- export type { Span, TraceExporter } from '../../types/observability.js';
11
- export type { AgentConfig, AgentHarnessContract, AgentHooks, CallModelRequest, DeliveryMode, ExecuteOptions, HarnessStatus, RecallLayerOutput, SessionScope, } from '../../types/runtime.js';
12
- export type { ShellAdapter } from '../../types/shell-adapter.js';
13
- export type { SteeringDecision } from '../../types/steering.js';
14
- export { SteeringAction } from '../../types/steering.js';
15
- export type { Step } from '../../types/step.js';
16
- export type { SubprocessAdapter } from '../../types/subprocess-adapter.js';
17
- export type { Tool } from '../../types/tool.js';
@@ -1 +1 @@
1
- export { SteeringAction } from '../../types/steering.js';
1
+ export { SteeringAction } from '@noetic-tools/types';
@@ -1,8 +1,6 @@
1
+ import type { AgentHarnessContract, CallModelRequest, ItemSchemaRegistry, LLMResponse } from '@noetic-tools/types';
1
2
  import type { OpenRouter } from '@openrouter/agent';
2
3
  import type { MessageQueue } from '../runtime/message-queue.js';
3
- import type { ItemSchemaRegistry } from '../schemas/item.js';
4
- import type { LLMResponse } from '../types/common.js';
5
- import type { AgentHarnessContract, CallModelRequest } from '../types/runtime.js';
6
4
  interface StreamIdleWatchdog {
7
5
  /** Bump the deadline because a stream event just arrived. */
8
6
  reset: () => void;
@@ -1,9 +1,8 @@
1
+ import { frameworkCast, NoeticConfigError } from '@noetic-tools/types';
1
2
  import { z } from 'zod';
2
3
  import { convertTools, executeToolCall, extractOutputItems, extractSystemInstruction, extractUsage, itemsToInput, sanitizeToolNameForWire, } from '../adapters/openrouter.js';
3
- import { NoeticConfigError } from '../errors/noetic-config-error.js';
4
4
  import { isFunctionCall } from '../interpreter/typeguards.js';
5
5
  import { emitFrameworkEvent, getBroadcaster, shouldEmit } from '../runtime/broadcaster-utils.js';
6
- import { frameworkCast } from '../util/framework-cast.js';
7
6
  import { buildItemSchemaRegistry, createToolResultItem } from './model-schema.js';
8
7
  const MAX_TOOL_ROUNDS = 32;
9
8
  const MAX_RECOVERY_CONTINUATIONS = 3;
@@ -401,7 +400,6 @@ export class AgentHarnessModelCaller {
401
400
  await this.executeToolRound({
402
401
  functionCalls,
403
402
  request,
404
- roundItemSchemas,
405
403
  allItems,
406
404
  conversationInput,
407
405
  round,
@@ -518,7 +516,7 @@ export class AgentHarnessModelCaller {
518
516
  };
519
517
  }
520
518
  async executeToolRound(params) {
521
- const { functionCalls, request, roundItemSchemas, allItems, conversationInput } = params;
519
+ const { functionCalls, request, allItems, conversationInput } = params;
522
520
  params.emitIfAllowed('tool_round_started', {
523
521
  round: params.round,
524
522
  toolCount: functionCalls.length,
@@ -539,7 +537,6 @@ export class AgentHarnessModelCaller {
539
537
  await this.executeFunctionCall({
540
538
  fc,
541
539
  request,
542
- roundItemSchemas,
543
540
  allItems,
544
541
  conversationInput,
545
542
  emitIfAllowed: params.emitIfAllowed,
@@ -551,7 +548,7 @@ export class AgentHarnessModelCaller {
551
548
  });
552
549
  }
553
550
  async executeFunctionCall(params) {
554
- const { fc, request, roundItemSchemas, allItems, conversationInput } = params;
551
+ const { fc, request, allItems, conversationInput } = params;
555
552
  params.emitIfAllowed('tool_call_started', {
556
553
  name: fc.name,
557
554
  callId: fc.callId,
@@ -564,7 +561,6 @@ export class AgentHarnessModelCaller {
564
561
  this.recordMalformedToolCall({
565
562
  fc,
566
563
  request,
567
- roundItemSchemas,
568
564
  allItems,
569
565
  conversationInput,
570
566
  emitIfAllowed: params.emitIfAllowed,
@@ -583,10 +579,13 @@ export class AgentHarnessModelCaller {
583
579
  harness: this.opts.harness,
584
580
  layers: request.layers,
585
581
  });
582
+ // Owner-scoped result validation: a tool's `toolResults` schemas apply
583
+ // only to that tool's own result items. Harness-level `opts.itemSchemas`
584
+ // stay global by design; sibling tools' schemas never reject this item.
586
585
  const outputItem = createToolResultItem({
587
586
  output: toolResult.output,
588
587
  callId: fc.callId,
589
- roundItemSchemas,
588
+ roundItemSchemas: this.opts.itemSchemas.extend(toolForCall?.itemSchemas),
590
589
  tool: toolForCall,
591
590
  callItem: fc,
592
591
  args: parsedArgs,
@@ -606,13 +605,14 @@ export class AgentHarnessModelCaller {
606
605
  });
607
606
  }
608
607
  recordMalformedToolCall(params) {
609
- const { fc, request, roundItemSchemas, allItems, conversationInput } = params;
608
+ const { fc, request, allItems, conversationInput } = params;
610
609
  const errorOutput = `Error: malformed JSON in tool arguments: ${fc.arguments}`;
611
610
  const toolForCall = request.tools?.find((tool) => tool.name === fc.name);
611
+ // Owner-scoped result validation (see executeFunctionCall).
612
612
  const outputItem = createToolResultItem({
613
613
  output: errorOutput,
614
614
  callId: fc.callId,
615
- roundItemSchemas,
615
+ roundItemSchemas: this.opts.itemSchemas.extend(toolForCall?.itemSchemas),
616
616
  tool: toolForCall,
617
617
  callItem: fc,
618
618
  error: true,