@nhtio/adk 0.1.0-master-d3feb810 → 0.1.0-master-445a9ed0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +49 -0
- package/batteries/llm/openai_chat_completions/adapter.cjs +9 -10
- package/batteries/llm/openai_chat_completions/adapter.cjs.map +1 -1
- package/batteries/llm/openai_chat_completions/adapter.mjs +8 -8
- package/batteries/llm/openai_chat_completions/adapter.mjs.map +1 -1
- package/batteries/llm/openai_chat_completions/exceptions.cjs +1 -1
- package/batteries/llm/openai_chat_completions/helpers.cjs +16 -16
- package/batteries/llm/openai_chat_completions/helpers.cjs.map +1 -1
- package/batteries/llm/openai_chat_completions/helpers.d.ts +10 -10
- package/batteries/llm/openai_chat_completions/helpers.mjs +16 -16
- package/batteries/llm/openai_chat_completions/helpers.mjs.map +1 -1
- package/batteries/llm/openai_chat_completions/types.d.ts +26 -6
- package/batteries/llm/openai_chat_completions/validation.cjs +3 -1
- package/batteries/llm/openai_chat_completions/validation.cjs.map +1 -1
- package/batteries/llm/openai_chat_completions/validation.mjs +2 -0
- package/batteries/llm/openai_chat_completions/validation.mjs.map +1 -1
- package/batteries/llm/webllm_chat_completions/adapter.cjs +9 -10
- package/batteries/llm/webllm_chat_completions/adapter.cjs.map +1 -1
- package/batteries/llm/webllm_chat_completions/adapter.mjs +8 -8
- package/batteries/llm/webllm_chat_completions/adapter.mjs.map +1 -1
- package/batteries/llm/webllm_chat_completions/exceptions.cjs +1 -1
- package/batteries/llm/webllm_chat_completions/validation.cjs +3 -1
- package/batteries/llm/webllm_chat_completions/validation.cjs.map +1 -1
- package/batteries/llm/webllm_chat_completions/validation.mjs +2 -0
- package/batteries/llm/webllm_chat_completions/validation.mjs.map +1 -1
- package/batteries/storage/flydrive/index.d.ts +10 -4
- package/batteries/storage/flydrive.cjs +12 -3
- package/batteries/storage/flydrive.cjs.map +1 -1
- package/batteries/storage/flydrive.mjs +11 -2
- package/batteries/storage/flydrive.mjs.map +1 -1
- package/batteries/storage/in_memory/index.d.ts +31 -17
- package/batteries/storage/in_memory.cjs +89 -30
- package/batteries/storage/in_memory.cjs.map +1 -1
- package/batteries/storage/in_memory.mjs +89 -30
- package/batteries/storage/in_memory.mjs.map +1 -1
- package/batteries/storage/opfs/index.d.ts +10 -4
- package/batteries/storage/opfs.cjs +55 -5
- package/batteries/storage/opfs.cjs.map +1 -1
- package/batteries/storage/opfs.mjs +54 -4
- package/batteries/storage/opfs.mjs.map +1 -1
- package/batteries/tools/color.cjs +3 -3
- package/batteries/tools/color.mjs +2 -2
- package/batteries/tools/comparison.cjs +3 -4
- package/batteries/tools/comparison.cjs.map +1 -1
- package/batteries/tools/comparison.mjs +2 -2
- package/batteries/tools/data_structure.cjs +3 -4
- package/batteries/tools/data_structure.cjs.map +1 -1
- package/batteries/tools/data_structure.mjs +2 -2
- package/batteries/tools/datetime_extended.cjs +4 -4
- package/batteries/tools/datetime_extended.mjs +2 -2
- package/batteries/tools/datetime_math.cjs +3 -3
- package/batteries/tools/datetime_math.mjs +2 -2
- package/batteries/tools/encoding.cjs +3 -4
- package/batteries/tools/encoding.cjs.map +1 -1
- package/batteries/tools/encoding.mjs +2 -2
- package/batteries/tools/formatting.cjs +3 -4
- package/batteries/tools/formatting.cjs.map +1 -1
- package/batteries/tools/formatting.mjs +2 -2
- package/batteries/tools/geo_basics.cjs +3 -3
- package/batteries/tools/geo_basics.mjs +2 -2
- package/batteries/tools/math.cjs +3 -4
- package/batteries/tools/math.cjs.map +1 -1
- package/batteries/tools/math.mjs +2 -2
- package/batteries/tools/memory.cjs +6 -7
- package/batteries/tools/memory.cjs.map +1 -1
- package/batteries/tools/memory.mjs +5 -5
- package/batteries/tools/parsing.cjs +5 -6
- package/batteries/tools/parsing.cjs.map +1 -1
- package/batteries/tools/parsing.mjs +3 -3
- package/batteries/tools/retrievables.cjs +11 -11
- package/batteries/tools/retrievables.cjs.map +1 -1
- package/batteries/tools/retrievables.mjs +10 -9
- package/batteries/tools/retrievables.mjs.map +1 -1
- package/batteries/tools/standing_instructions.cjs +4 -5
- package/batteries/tools/standing_instructions.cjs.map +1 -1
- package/batteries/tools/standing_instructions.mjs +3 -3
- package/batteries/tools/statistics.cjs +4 -5
- package/batteries/tools/statistics.cjs.map +1 -1
- package/batteries/tools/statistics.mjs +3 -3
- package/batteries/tools/string_processing.cjs +3 -4
- package/batteries/tools/string_processing.cjs.map +1 -1
- package/batteries/tools/string_processing.mjs +2 -2
- package/batteries/tools/structured_data.cjs +3 -4
- package/batteries/tools/structured_data.cjs.map +1 -1
- package/batteries/tools/structured_data.mjs +2 -2
- package/batteries/tools/text_analysis.cjs +4 -4
- package/batteries/tools/text_analysis.mjs +3 -3
- package/batteries/tools/text_comparison.cjs +3 -3
- package/batteries/tools/text_comparison.mjs +2 -2
- package/batteries/tools/time.cjs +3 -3
- package/batteries/tools/time.mjs +2 -2
- package/batteries/tools/unit_conversion.cjs +3 -3
- package/batteries/tools/unit_conversion.mjs +2 -2
- package/batteries/tools.cjs +3 -3
- package/batteries/tools.mjs +3 -3
- package/batteries.cjs +3 -3
- package/batteries.mjs +3 -3
- package/{common-Od8edUXU.js → common-BJ6V6dsH.js} +89 -12
- package/common-BJ6V6dsH.js.map +1 -0
- package/{common-DeZaonK1.mjs → common-aFmr9Oqs.mjs} +76 -10
- package/common-aFmr9Oqs.mjs.map +1 -0
- package/common.cjs +9 -7
- package/common.d.ts +8 -0
- package/common.mjs +7 -7
- package/{dispatch_runner-CsoH0nld.js → dispatch_runner-BWYNxmnp.js} +37 -6
- package/dispatch_runner-BWYNxmnp.js.map +1 -0
- package/{dispatch_runner-9j6bXHL3.mjs → dispatch_runner-OimGCkk7.mjs} +34 -2
- package/dispatch_runner-OimGCkk7.mjs.map +1 -0
- package/dispatch_runner.cjs +1 -1
- package/dispatch_runner.mjs +1 -1
- package/{exceptions-D5YrO9Vm.js → exceptions-CSqzbL1N.js} +2 -2
- package/{exceptions-D5YrO9Vm.js.map → exceptions-CSqzbL1N.js.map} +1 -1
- package/exceptions.cjs +2 -2
- package/factories.cjs +1 -1
- package/forge.cjs +4 -4
- package/forge.mjs +3 -3
- package/guards.cjs +9 -9
- package/guards.mjs +7 -7
- package/index.cjs +12 -12
- package/index.cjs.map +1 -1
- package/index.d.ts +1 -1
- package/index.mjs +9 -9
- package/index.mjs.map +1 -1
- package/lib/classes/retrievable.d.ts +47 -4
- package/lib/contracts/byte_store.d.ts +93 -0
- package/lib/contracts/dispatch_context.d.ts +44 -0
- package/lib/contracts/turn_runner_config.d.ts +5 -1
- package/lib/contracts/turn_runner_context.d.ts +25 -0
- package/package.json +67 -67
- package/{runtime-BJVkrGQe.js → runtime-BUDWyd-R.js} +2 -2
- package/{runtime-BJVkrGQe.js.map → runtime-BUDWyd-R.js.map} +1 -1
- package/skills/adk-assembly/SKILL.md +2 -2
- package/{spooled_artifact-C5ZtGxuJ.mjs → spooled_artifact-B_tVDDdB.mjs} +2 -2
- package/{spooled_artifact-C5ZtGxuJ.mjs.map → spooled_artifact-B_tVDDdB.mjs.map} +1 -1
- package/{spooled_artifact-Cm9Te22K.js → spooled_artifact-CFstzlqX.js} +5 -6
- package/{spooled_artifact-Cm9Te22K.js.map → spooled_artifact-CFstzlqX.js.map} +1 -1
- package/spooled_artifact.cjs +2 -2
- package/spooled_artifact.mjs +2 -2
- package/{spooled_markdown_artifact-RRB113sy.js → spooled_markdown_artifact-DK-T8Hy6.js} +6 -7
- package/{spooled_markdown_artifact-RRB113sy.js.map → spooled_markdown_artifact-DK-T8Hy6.js.map} +1 -1
- package/{spooled_markdown_artifact-BpUJol0W.mjs → spooled_markdown_artifact-DWWak35I.mjs} +2 -2
- package/{spooled_markdown_artifact-BpUJol0W.mjs.map → spooled_markdown_artifact-DWWak35I.mjs.map} +1 -1
- package/{thought-CDb457b4.mjs → thought-DDqjQu3m.mjs} +2 -2
- package/{thought-CDb457b4.mjs.map → thought-DDqjQu3m.mjs.map} +1 -1
- package/{thought-DuN2PgdO.js → thought-DTsFRGdE.js} +5 -6
- package/{thought-DuN2PgdO.js.map → thought-DTsFRGdE.js.map} +1 -1
- package/{tool-COSeH8I6.js → tool-cwJyEHI9.js} +4 -5
- package/{tool-COSeH8I6.js.map → tool-cwJyEHI9.js.map} +1 -1
- package/{tool-D2WB1EA1.mjs → tool-q4LskG7K.mjs} +1 -1
- package/{tool-D2WB1EA1.mjs.map → tool-q4LskG7K.mjs.map} +1 -1
- package/{tool_call-DFgzcVcU.js → tool_call-3T0xTXlD.js} +5 -6
- package/{tool_call-DFgzcVcU.js.map → tool_call-3T0xTXlD.js.map} +1 -1
- package/{tool_call-BKyyxGaZ.mjs → tool_call-BKIdAAoY.mjs} +2 -2
- package/{tool_call-BKyyxGaZ.mjs.map → tool_call-BKIdAAoY.mjs.map} +1 -1
- package/{tool_registry-Dkfprsck.js → tool_registry-snPjF0zJ.js} +39 -5
- package/{tool_registry-Dkfprsck.js.map → tool_registry-snPjF0zJ.js.map} +1 -1
- package/{turn_runner-CMm2BHdX.js → turn_runner-BScT8OgA.js} +10 -7
- package/turn_runner-BScT8OgA.js.map +1 -0
- package/{turn_runner-y7eyEcJH.mjs → turn_runner-DRBLN2Y_.mjs} +7 -3
- package/turn_runner-DRBLN2Y_.mjs.map +1 -0
- package/turn_runner.cjs +1 -1
- package/turn_runner.mjs +1 -1
- package/types.d.ts +2 -2
- package/chunk-KmRHZBOW.js +0 -35
- package/common-DeZaonK1.mjs.map +0 -1
- package/common-Od8edUXU.js.map +0 -1
- package/dispatch_runner-9j6bXHL3.mjs.map +0 -1
- package/dispatch_runner-CsoH0nld.js.map +0 -1
- package/turn_runner-CMm2BHdX.js.map +0 -1
- package/turn_runner-y7eyEcJH.mjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool_registry-Dkfprsck.js","names":["#value","#cache","#store","#tools"],"sources":["../src/lib/utils/guards.ts","../src/lib/classes/tokenizable.ts","../src/lib/classes/registry.ts","../src/lib/utils/canonical_json.ts","../src/lib/classes/tool_registry.ts"],"sourcesContent":["import { passesSchema } from './validation'\nimport { validator } from '@nhtio/validation'\n\n/**\n * Returns `true` if `value` is an instance of the class identified by `type` (and optionally `ctor`).\n *\n * @remarks\n * Performs three checks in order: `instanceof ctor`, `Symbol.hasInstance`, then constructor-name\n * comparison. The constructor-name fallback handles cross-realm cases where `instanceof` fails.\n *\n * @typeParam T - The expected instance type.\n * @param value - The value to test.\n * @param type - The constructor name to compare against when `instanceof` is unavailable.\n * @param ctor - Optional constructor to use for `instanceof` and `Symbol.hasInstance` checks.\n * @returns `true` when `value` is an instance of the class described by `type`/`ctor`.\n */\nexport const isInstanceOf = <T>(\n value: unknown,\n type: string,\n ctor?: new (...args: any[]) => T\n): value is T => {\n // eslint-disable-next-line adk/use-is-instance-of -- this IS the implementation of isInstanceOf\n if ('undefined' !== typeof ctor && value instanceof ctor) return true\n /* istanbul ignore next 4 */\n if (\n 'undefined' !== typeof ctor &&\n typeof ctor[Symbol.hasInstance] === 'function' &&\n ctor[Symbol.hasInstance](value)\n )\n /* istanbul ignore next */\n return true\n // eslint-disable-next-line adk/prefer-is-object -- this guard is the building block isObject depends on (no circular usage)\n if ('object' === typeof value && null !== value) {\n const valueWithConstructor = value as { constructor?: Function }\n const constructorName = valueWithConstructor.constructor?.name\n return constructorName === type\n }\n return false\n}\n\nconst errorSchema = validator\n .any()\n .custom((value, helpers) => {\n if (isInstanceOf(value, 'Error', Error)) {\n return value\n }\n return helpers.error('any.invalid')\n })\n .required()\n\n/**\n * Returns `true` if `value` is an `Error` instance or satisfies the `Error` duck-type shape.\n *\n * @remarks\n * Returns `false` for `undefined` and `null` — the `Error` contract requires an actual instance.\n *\n * @param value - The value to test.\n * @returns `true` when `value` conforms to the `Error` shape.\n */\nexport const isError = (value: unknown): value is Error => {\n return passesSchema(errorSchema, value)\n}\n\n/**\n * Type guard to check if a value is a plain object (not null, not array)\n * @param value - The value to check\n * @returns True if the value is a plain object, false otherwise\n */\nexport const isObject = (value: unknown): value is { [key: string]: unknown } => {\n // eslint-disable-next-line adk/prefer-is-object -- this IS the implementation of isObject\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n","import { getEncoding } from 'js-tiktoken'\nimport { validator } from '@nhtio/validation'\nimport { isInstanceOf } from '../utils/guards'\nimport { LlamaTokenizer } from 'llama-tokenizer-js'\nimport { fromPreTrained as geminiFromPreTrained } from '@lenml/tokenizer-gemini'\nimport type { Tiktoken } from 'js-tiktoken'\n\n/**\n * The set of supported token encoding identifiers.\n *\n * @remarks\n * Each value maps to a specific estimation backend:\n * - `gpt2`, `r50k_base`, `p50k_base`, `p50k_edit`, `cl100k_base`, `o200k_base` — exact counts\n * via `js-tiktoken` (OpenAI / tiktoken-compatible models).\n * - `gemini` — exact counts via `@lenml/tokenizer-gemini`, which embeds Gemini's actual\n * SentencePiece vocabulary locally with no API call required.\n * - `llama2` — exact counts via `llama-tokenizer-js` (Llama 1 and 2). Llama 3+ uses a\n * different vocabulary and should use the `llama3` identifier once a suitable sync backend\n * is available.\n * - `claude` — heuristic approximation using Anthropic's published ~3.5 chars/token ratio.\n * No local tokenizer is available for Claude 3+ models; the Anthropic SDK's\n * `messages.countTokens()` API is the only exact path but requires a network call.\n *\n * When adding a new encoding, add a case to {@link Tokenizable.estimateTokens}.\n */\nexport const TokenEncoding = [\n 'gpt2',\n 'r50k_base',\n 'p50k_base',\n 'p50k_edit',\n 'cl100k_base',\n 'o200k_base',\n 'gemini',\n 'llama2',\n 'claude',\n] as const\n\n/**\n * Union of all recognised token encoding identifier strings.\n *\n * @remarks\n * Derived from {@link TokenEncoding} so the type and the runtime array stay in sync\n * automatically when new encodings are added.\n */\nexport type TokenEncoding = (typeof TokenEncoding)[number]\n\n/**\n * Backing schema for {@link Tokenizable.schema}.\n *\n * @remarks\n * Accepts a plain `string` or an existing {@link Tokenizable} instance. Strings pass through\n * unchanged; {@link Tokenizable} instances are accepted via {@link Tokenizable.isTokenizable}\n * to remain cross-realm safe.\n */\nconst stringOrTokenizableSchema = validator.alternatives(\n validator.string(),\n validator.custom((value, helpers) => {\n if (Tokenizable.isTokenizable(value)) {\n return value\n }\n return helpers.error('any.invalid')\n })\n)\n\n// Lazily-initialised singletons — tokenizers are expensive to load so we defer\n// until first use and reuse across all Tokenizable instances thereafter.\nlet geminiTokenizerInstance: ReturnType<typeof geminiFromPreTrained> | undefined\nlet llamaTokenizerInstance: InstanceType<typeof LlamaTokenizer> | undefined\n\nconst getGeminiTokenizer = () => {\n if (!geminiTokenizerInstance) {\n geminiTokenizerInstance = geminiFromPreTrained()\n }\n return geminiTokenizerInstance\n}\n\nconst getLlamaTokenizer = () => {\n if (!llamaTokenizerInstance) {\n llamaTokenizerInstance = new LlamaTokenizer()\n }\n return llamaTokenizerInstance\n}\n\n/**\n * A mutable string with a built-in token counter.\n *\n * @remarks\n * The wrapped string can be read via the standard coercion protocol and updated at any time via\n * {@link Tokenizable.set}. Token counts are computed lazily on first access per encoding and\n * cached until the value changes, avoiding redundant encoder invocations when the same content\n * is measured multiple times across a pipeline.\n *\n * Estimation is dispatched by encoding identifier — see {@link TokenEncoding} for the full list\n * of supported backends and their accuracy characteristics. Unrecognised encodings fall back to\n * a `ceil(length / 4)` character heuristic.\n *\n * The class implements the standard JS value-coercion protocol (`toString`, `valueOf`,\n * `toJSON`, `toLocaleString`, `Symbol.for('nodejs.util.inspect.custom')`) so instances behave\n * transparently as strings in most contexts.\n */\nexport class Tokenizable {\n public static TokenEncoding = TokenEncoding\n\n /**\n * Validator schema that accepts a plain `string` or a {@link Tokenizable} instance.\n *\n * @remarks\n * Reusable fragment for any schema that wants to accept either form — for example,\n * `systemPrompt` and each item in `standingInstructions` in `turnContextSchema`.\n */\n public static schema = stringOrTokenizableSchema\n\n declare toJSON: () => string\n declare toString: () => string\n declare valueOf: () => string\n declare toLocaleString: () => string\n declare set: (value: string) => void\n declare estimateTokens: (encoding: TokenEncoding) => number\n\n #value: string\n #cache: Map<TokenEncoding, number> = new Map()\n\n /**\n * @param value - The initial string value to wrap.\n */\n constructor(value: string) {\n this.#value = value\n\n const estimateTokensWithTiktoken = (encoding: TokenEncoding): number => {\n try {\n const enc: Tiktoken = getEncoding(encoding as any)\n return enc.encode(this.#value, []).length\n } catch {\n return Number.POSITIVE_INFINITY\n }\n }\n\n const estimateTokensWithGemini = (): number => {\n try {\n return getGeminiTokenizer().encode(this.#value).length\n } catch {\n return Number.POSITIVE_INFINITY\n }\n }\n\n const estimateTokensWithLlama2 = (): number => {\n try {\n return getLlamaTokenizer().encode(this.#value, false).length\n } catch {\n return Number.POSITIVE_INFINITY\n }\n }\n\n const estimateTokensWithClaudeHeuristic = (): number => {\n try {\n return Math.ceil(this.#value.length / 3.5)\n } catch {\n return Number.POSITIVE_INFINITY\n }\n }\n\n Object.defineProperties(this, {\n toJSON: {\n value: () => this.#value,\n enumerable: false,\n configurable: false,\n writable: false,\n },\n toString: {\n value: () => this.#value,\n enumerable: false,\n configurable: false,\n writable: false,\n },\n valueOf: {\n value: () => this.#value,\n enumerable: false,\n configurable: false,\n writable: false,\n },\n toLocaleString: {\n value: () => this.#value,\n enumerable: false,\n configurable: false,\n writable: false,\n },\n [Symbol.for('nodejs.util.inspect.custom')]: {\n value: () => this.#value,\n enumerable: false,\n configurable: false,\n writable: false,\n },\n set: {\n value: (next: string) => {\n this.#value = next\n this.#cache.clear()\n },\n enumerable: false,\n configurable: false,\n writable: false,\n },\n estimateTokens: {\n value: (encoding: TokenEncoding): number => {\n if (this.#cache.has(encoding)) {\n return this.#cache.get(encoding)!\n }\n\n let estimate: number\n switch (encoding) {\n case 'gpt2':\n case 'r50k_base':\n case 'p50k_base':\n case 'p50k_edit':\n case 'cl100k_base':\n case 'o200k_base':\n estimate = estimateTokensWithTiktoken(encoding)\n break\n case 'gemini':\n estimate = estimateTokensWithGemini()\n break\n case 'llama2':\n estimate = estimateTokensWithLlama2()\n break\n case 'claude':\n estimate = estimateTokensWithClaudeHeuristic()\n break\n }\n if (estimate === Number.POSITIVE_INFINITY) {\n estimate = Math.ceil(this.#value.length / 4)\n } else {\n this.#cache.set(encoding, estimate)\n }\n return estimate\n },\n enumerable: false,\n configurable: false,\n writable: false,\n },\n })\n }\n\n /**\n * Convenience overload for one-off token counting without managing a {@link Tokenizable} instance.\n *\n * @remarks\n * Creates a temporary instance and immediately discards it — no caching benefit. Use the\n * instance method when you need to count the same value under multiple encodings or when the\n * value may change over time.\n *\n * @param value - The string to count tokens for.\n * @param encoding - The encoding identifier to use for counting.\n * @returns The estimated number of tokens.\n */\n public static estimateTokens(value: string, encoding: TokenEncoding): number {\n const temp = new Tokenizable(value)\n return temp.estimateTokens(encoding)\n }\n\n /**\n * Returns `true` if `value` is a {@link Tokenizable} instance.\n *\n * @remarks\n * Uses {@link @nhtio/adk!isInstanceOf} for cross-realm safety — `instanceof` would fail for instances\n * created in a different module copy or VM context.\n *\n * @param value - The value to test.\n * @returns `true` when `value` is a {@link Tokenizable} instance.\n */\n public static isTokenizable(value: unknown): value is Tokenizable {\n return isInstanceOf(value, 'Tokenizable', Tokenizable)\n }\n}\n\n/**\n * Returns `true` if `value` is a {@link Tokenizable} instance.\n *\n * @remarks\n * Module-level convenience alias for {@link Tokenizable.isTokenizable}. Prefer this form when\n * you need a standalone type guard without importing the full class.\n *\n * Uses {@link @nhtio/adk!isInstanceOf} for cross-realm safety — `instanceof` would fail for instances\n * created in a different module copy or VM context.\n *\n * @param value - The value to test.\n * @returns `true` when `value` is a {@link Tokenizable} instance.\n */\nexport const isTokenizable = (value: unknown): value is Tokenizable => {\n return isInstanceOf(value, 'Tokenizable', Tokenizable)\n}\n","import { dset } from 'dset'\nimport { klona } from 'klona'\nimport { default as delve } from 'dlv'\nimport { isInstanceOf, isObject } from '../utils/guards'\nimport { E_INVALID_INITIAL_REGISTRY_VALUE } from '../exceptions/runtime'\n\n/**\n * A controlled-mutation key-value store with dot-path access and deep-clone isolation.\n *\n * @remarks\n * The registry enforces a safe read/write contract: callers never hold a live reference into\n * the internal store. Every value that enters (`set`) or leaves (`get`, `all`) is deep-cloned\n * via `klona`, so mutations to a retrieved value cannot affect stored state and vice versa.\n *\n * Keys are dot-delimited paths (e.g. `\"user.profile.name\"`), resolved via `dlv` for reads and\n * `dset` for writes; intermediate objects are created automatically on write.\n */\nexport class Registry {\n #store: Record<string, unknown>\n\n /**\n * @param initial - Optional plain object to seed the registry. Deep-cloned on construction.\n * @throws {@link @nhtio/adk!E_INVALID_INITIAL_REGISTRY_VALUE} when `initial` is defined but not a plain object.\n */\n constructor(initial?: Record<string, unknown>) {\n if ('undefined' !== typeof initial && !isObject(initial)) {\n throw new E_INVALID_INITIAL_REGISTRY_VALUE()\n }\n this.#store = initial ? klona(initial) : {}\n }\n\n /**\n * Returns `true` if `value` is a {@link Registry} instance.\n *\n * @remarks\n * Uses {@link @nhtio/adk!isInstanceOf} for cross-realm safety.\n *\n * @param value - The value to test.\n * @returns `true` when `value` is a {@link Registry} instance.\n */\n public static isRegistry(value: unknown): value is Registry {\n return isInstanceOf(value, 'Registry', Registry)\n }\n\n /**\n * Retrieves the value at `key`, returning `defaultValue` if the path is absent.\n *\n * @remarks\n * The returned value is a deep clone — mutating it will not affect the stored state.\n *\n * @typeParam T - Expected type of the value at `key`.\n * @param key - Dot-delimited path into the store (e.g. `\"user.name\"`).\n * @param defaultValue - Fallback returned when the path resolves to `undefined`.\n * @returns A deep clone of the stored value cast to `T`, or `defaultValue` when the path is absent.\n */\n get<T = unknown>(key: string, defaultValue?: T): T {\n const cloned = klona(this.#store)\n const value = delve(cloned, key)\n return 'undefined' === typeof value ? (defaultValue as T) : (value as T)\n }\n\n /**\n * Sets the value at `key`, creating intermediate objects as needed.\n *\n * @remarks\n * The stored value is isolated from the caller — mutating `value` after this call will not\n * affect what is held in the registry.\n *\n * @param key - Dot-delimited path into the store (e.g. `\"user.name\"`).\n * @param value - Value to store at the path.\n */\n set(key: string, value: unknown): void {\n dset(this.#store, key, value)\n }\n\n /**\n * Returns `true` if the registry has a value at `key`, `false` otherwise.\n *\n * @remarks\n * A key resolving to `undefined` is treated as absent — same convention as {@link Registry.get}'s\n * `defaultValue` fallback. No clone is performed; this is a pure existence check.\n *\n * @param key - Dot-delimited path into the store (e.g. `\"user.name\"`).\n * @returns `true` when the path resolves to a value other than `undefined`.\n */\n has(key: string): boolean {\n return 'undefined' !== typeof delve(this.#store, key)\n }\n\n /**\n * Returns all leaf dot-paths present in the registry.\n *\n * @remarks\n * The store is deep-cloned before traversal. Plain objects are walked recursively with path\n * segments joined by dots; arrays, primitives, `null`, and class instances are treated as leaves.\n *\n * @returns A string array of dot-delimited paths to leaf values in the store.\n */\n keys(): string[] {\n const store = klona(this.#store)\n const keys: string[] = []\n\n const isPlainRecord = (value: unknown): value is Record<string, unknown> => {\n if (!isObject(value)) return false\n const prototype = Object.getPrototypeOf(value)\n return prototype === Object.prototype || prototype === null\n }\n\n const walk = (value: unknown, segments: string[]): void => {\n if (!isPlainRecord(value)) {\n if (segments.length > 0) keys.push(segments.join('.'))\n return\n }\n\n for (const [segment, child] of Object.entries(value)) {\n walk(child, [...segments, segment])\n }\n }\n\n walk(store, [])\n return keys\n }\n\n /**\n * Returns a deep clone of the entire store contents.\n *\n * @returns A plain object snapshot of all stored key-value pairs.\n */\n all(): Record<string, unknown> {\n return klona(this.#store)\n }\n}\n","/**\n * Canonical `JSON.stringify` that sorts object keys recursively so that semantically-equal\n * objects produce identical strings.\n *\n * @remarks\n * Used wherever the ADK derives a stable identity from a structured value — for example,\n * `Tool.executor` computing the `callId` for `ToolExecutionStart`/`End` events, and the\n * `reportToolCall` executor helper computing the `checksum` field on `TurnToolCallContent`.\n * Both code paths hash `canonicalStringify({ tool, args })` so that argument key order does not\n * affect the resulting identifier.\n *\n * Arrays are serialised in their declared order (order is meaningful for an array). Object keys\n * are sorted with `Array.prototype.sort()`'s default lexicographic comparator.\n *\n * @param value - The value to serialise.\n * @returns A canonical JSON string representation of `value`.\n */\nexport function canonicalStringify(value: unknown): string {\n if (value === null || typeof value !== 'object') return JSON.stringify(value)\n if (Array.isArray(value)) return '[' + value.map((v) => canonicalStringify(v)).join(',') + ']'\n const obj = value as Record<string, unknown>\n const keys = Object.keys(obj).sort()\n return '{' + keys.map((k) => JSON.stringify(k) + ':' + canonicalStringify(obj[k])).join(',') + '}'\n}\n","import { isInstanceOf } from '../utils/guards'\nimport { E_TOOL_ALREADY_REGISTERED } from '../exceptions/runtime'\nimport type { Tool } from './tool'\nimport type { DispatchContext } from '../contracts/dispatch_context'\n\n/**\n * Options accepted by {@link ToolRegistry.merge}.\n */\nexport interface MergeOptions {\n /**\n * What to do when two registries contain a tool with the same name AND neither tool's own\n * `onCollision` resolves the collision.\n *\n * @remarks\n * - `'throw'` (default): raise {@link @nhtio/adk!E_TOOL_ALREADY_REGISTERED} on the first unresolved\n * collision. Mirrors the default behaviour of {@link ToolRegistry.register} and surfaces\n * accidental name shadowing immediately.\n * - `'replace'`: the later registry's tool wins.\n * - `'keep'`: the earlier registry's tool wins; later occurrences are dropped.\n *\n * Per-tool {@link @nhtio/adk!Tool.onCollision} takes precedence: if the incoming tool declares\n * `'replace'` or `'keep'`, that policy wins regardless of this option. Only when the incoming\n * tool's policy is `'throw'` (the default) does this fallback apply.\n *\n * @defaultValue `'throw'`\n */\n onCollision?: 'throw' | 'replace' | 'keep'\n}\n\n/**\n * A mutable, turn-scoped collection of {@link @nhtio/adk!Tool} instances.\n *\n * @remarks\n * Each `TurnRunner.run()` call constructs a fresh `ToolRegistry` from the runner's configured\n * baseline tools, so middleware edits are isolated to the current turn and cannot bleed across\n * concurrent or subsequent turns.\n *\n * `Tool` instances are immutable, so `all()` returns a fresh array without deep-cloning.\n *\n * `register()` throws {@link @nhtio/adk!E_TOOL_ALREADY_REGISTERED} if a tool with the same name is already\n * present — pass `overwrite: true` to replace it explicitly.\n */\nexport class ToolRegistry {\n #tools: Map<string, Tool>\n\n /**\n * Returns `true` if `value` is a {@link ToolRegistry} instance.\n *\n * @param value - The value to test.\n * @returns `true` when `value` is a {@link ToolRegistry} instance.\n */\n public static isToolRegistry(value: unknown): value is ToolRegistry {\n return isInstanceOf(value, 'ToolRegistry', ToolRegistry)\n }\n\n /**\n * @param tools - Optional initial tools. Insertion order is preserved. Duplicate names throw\n * {@link @nhtio/adk!E_TOOL_ALREADY_REGISTERED} — ensure each tool has a unique name.\n * @throws {@link @nhtio/adk!E_TOOL_ALREADY_REGISTERED} when two tools in `tools` share a name.\n */\n constructor(tools?: Tool[]) {\n this.#tools = new Map()\n for (const tool of tools ?? []) {\n this.register(tool)\n }\n }\n\n /**\n * Adds a tool to the registry.\n *\n * @param tool - The tool to register.\n * @param overwrite - When `true`, silently replaces an existing tool with the same name.\n * Defaults to `false`.\n * @throws {@link @nhtio/adk!E_TOOL_ALREADY_REGISTERED} when a tool with the same name is already registered\n * and `overwrite` is not `true`.\n */\n register(tool: Tool, overwrite?: boolean): void {\n if (this.#tools.has(tool.name) && !overwrite) {\n throw new E_TOOL_ALREADY_REGISTERED()\n }\n this.#tools.set(tool.name, tool)\n }\n\n /**\n * Removes the tool with the given name from the registry.\n *\n * @remarks\n * No-ops if no tool with that name is registered.\n *\n * @param name - The name of the tool to remove.\n */\n unregister(name: string): void {\n this.#tools.delete(name)\n }\n\n /**\n * Returns the tool registered under `name`, or `undefined` if not present.\n *\n * @param name - The tool name to look up.\n */\n get(name: string): Tool | undefined {\n return this.#tools.get(name)\n }\n\n /**\n * Returns `true` if a tool with the given name is registered.\n *\n * @param name - The tool name to test.\n */\n has(name: string): boolean {\n return this.#tools.has(name)\n }\n\n /**\n * Returns a fresh array of all registered tools in insertion order.\n *\n * @remarks\n * Since {@link @nhtio/adk!Tool} instances are immutable, no deep-cloning is needed.\n */\n all(): Tool[] {\n return Array.from(this.#tools.values())\n }\n\n /**\n * Removes every tool whose {@link @nhtio/adk!Tool.ephemeral} flag is `true`.\n *\n * @remarks\n * Synchronous and idempotent — calling it twice in a row is a no-op the second time. The\n * canonical caller is {@link ToolRegistry.bindContext}, which schedules this method to run\n * at {@link @nhtio/adk!DispatchContext.ack}. Non-ephemeral tools are left untouched.\n */\n pruneEphemeral(): void {\n for (const [name, tool] of this.#tools) {\n if (tool.ephemeral) {\n this.#tools.delete(name)\n }\n }\n }\n\n /**\n * Binds this registry to a {@link @nhtio/adk!DispatchContext} so that {@link pruneEphemeral} runs\n * automatically when the context is acked.\n *\n * @remarks\n * The handler does NOT fire on {@link @nhtio/adk!DispatchContext.nack} — failed executor runs leave\n * any forged tools in place so the consumer can inspect what was registered when debugging the\n * failure. Subscriptions are short-lived and die with the context regardless.\n *\n * Forgetting this call after merging in `Subclass.forgeTools(ctx)` output means ephemeral tools\n * accumulate across executor invocations, and subsequent `forgeTools(ctx)` calls in later\n * iterations will see a stale `callId` enum that excludes new tool calls. The plan-documented\n * pattern is:\n *\n * ```ts\n * const executor: DispatchExecutorFn = async (ctx) => {\n * const forged = SpooledArtifact.forgeTools(ctx)\n * const merged = ToolRegistry.merge([main, forged])\n * main.bindContext(ctx)\n * const result = await llm.invoke({ tools: merged.all(), ... })\n * ctx.ack()\n * }\n * ```\n *\n * @param ctx - The execution context whose `ack` event should trigger pruning.\n * @returns An unsubscribe function — calling it before `ctx.ack()` prevents pruning. Rarely\n * useful outside of tests.\n *\n * @see {@link @nhtio/adk!SpooledArtifact.forgeTools}\n * @see {@link @nhtio/adk!DispatchContext.onAck}\n */\n bindContext(ctx: DispatchContext): () => void {\n return ctx.onAck(() => this.pruneEphemeral())\n }\n\n /**\n * Combines multiple {@link ToolRegistry} instances into a fresh registry without mutating any\n * input.\n *\n * @remarks\n * Iteration is left-to-right across `registries` and then in each registry's insertion order.\n * Collisions are resolved by consulting the **incoming** tool's {@link @nhtio/adk!Tool.onCollision} first:\n *\n * - `'replace'` (per-tool): the incoming tool wins, replacing the existing entry.\n * - `'keep'` (per-tool): the existing entry wins; the incoming tool is dropped.\n * - `'throw'` (per-tool, the default): fall back to the merge-level `options.onCollision`.\n *\n * The merge-level `options.onCollision` defaults to `'throw'`, which mirrors {@link register}.\n *\n * The result is a brand-new registry; no input is mutated and no event subscription is\n * propagated. Each `Tool`'s `ephemeral` flag carries through unchanged — the flag lives on the\n * tool, not the registry, so `bindContext(ctx)` on the merged registry will prune the forged\n * tools as expected.\n *\n * @param registries - Registries to merge, in priority order (left-to-right insertion).\n * @param options - Merge-level collision policy. Defaults to `{ onCollision: 'throw' }`.\n * @returns A fresh {@link ToolRegistry} containing the resolved union of all inputs.\n * @throws {@link @nhtio/adk!E_TOOL_ALREADY_REGISTERED} when the resolved collision policy is `'throw'`\n * and a collision occurs.\n */\n static merge(registries: ToolRegistry[], options?: MergeOptions): ToolRegistry {\n const policy = options?.onCollision ?? 'throw'\n const merged = new ToolRegistry()\n for (const registry of registries) {\n for (const tool of registry.all()) {\n const existing = merged.get(tool.name)\n if (!existing) {\n merged.register(tool)\n continue\n }\n const incomingPolicy = tool.onCollision\n if (incomingPolicy === 'replace') {\n merged.register(tool, true)\n continue\n }\n if (incomingPolicy === 'keep') {\n continue\n }\n // Incoming policy is 'throw' — fall back to the merge-level option.\n if (policy === 'replace') {\n merged.register(tool, true)\n continue\n }\n if (policy === 'keep') {\n continue\n }\n throw new E_TOOL_ALREADY_REGISTERED()\n }\n }\n return merged\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"tool_registry-snPjF0zJ.js","names":["#value","#cache","#store","#tools"],"sources":["../src/lib/utils/guards.ts","../src/lib/classes/tokenizable.ts","../src/lib/classes/registry.ts","../src/lib/utils/canonical_json.ts","../src/lib/classes/tool_registry.ts"],"sourcesContent":["import { passesSchema } from './validation'\nimport { validator } from '@nhtio/validation'\n\n/**\n * Returns `true` if `value` is an instance of the class identified by `type` (and optionally `ctor`).\n *\n * @remarks\n * Performs three checks in order: `instanceof ctor`, `Symbol.hasInstance`, then constructor-name\n * comparison. The constructor-name fallback handles cross-realm cases where `instanceof` fails.\n *\n * @typeParam T - The expected instance type.\n * @param value - The value to test.\n * @param type - The constructor name to compare against when `instanceof` is unavailable.\n * @param ctor - Optional constructor to use for `instanceof` and `Symbol.hasInstance` checks.\n * @returns `true` when `value` is an instance of the class described by `type`/`ctor`.\n */\nexport const isInstanceOf = <T>(\n value: unknown,\n type: string,\n ctor?: new (...args: any[]) => T\n): value is T => {\n // eslint-disable-next-line adk/use-is-instance-of -- this IS the implementation of isInstanceOf\n if ('undefined' !== typeof ctor && value instanceof ctor) return true\n /* istanbul ignore next 4 */\n if (\n 'undefined' !== typeof ctor &&\n typeof ctor[Symbol.hasInstance] === 'function' &&\n ctor[Symbol.hasInstance](value)\n )\n /* istanbul ignore next */\n return true\n // eslint-disable-next-line adk/prefer-is-object -- this guard is the building block isObject depends on (no circular usage)\n if ('object' === typeof value && null !== value) {\n const valueWithConstructor = value as { constructor?: Function }\n const constructorName = valueWithConstructor.constructor?.name\n return constructorName === type\n }\n return false\n}\n\nconst errorSchema = validator\n .any()\n .custom((value, helpers) => {\n if (isInstanceOf(value, 'Error', Error)) {\n return value\n }\n return helpers.error('any.invalid')\n })\n .required()\n\n/**\n * Returns `true` if `value` is an `Error` instance or satisfies the `Error` duck-type shape.\n *\n * @remarks\n * Returns `false` for `undefined` and `null` — the `Error` contract requires an actual instance.\n *\n * @param value - The value to test.\n * @returns `true` when `value` conforms to the `Error` shape.\n */\nexport const isError = (value: unknown): value is Error => {\n return passesSchema(errorSchema, value)\n}\n\n/**\n * Type guard to check if a value is a plain object (not null, not array)\n * @param value - The value to check\n * @returns True if the value is a plain object, false otherwise\n */\nexport const isObject = (value: unknown): value is { [key: string]: unknown } => {\n // eslint-disable-next-line adk/prefer-is-object -- this IS the implementation of isObject\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n","import { getEncoding } from 'js-tiktoken'\nimport { validator } from '@nhtio/validation'\nimport { isInstanceOf } from '../utils/guards'\nimport { LlamaTokenizer } from 'llama-tokenizer-js'\nimport { fromPreTrained as geminiFromPreTrained } from '@lenml/tokenizer-gemini'\nimport type { Tiktoken } from 'js-tiktoken'\n\n/**\n * The set of supported token encoding identifiers.\n *\n * @remarks\n * Each value maps to a specific estimation backend:\n * - `gpt2`, `r50k_base`, `p50k_base`, `p50k_edit`, `cl100k_base`, `o200k_base` — exact counts\n * via `js-tiktoken` (OpenAI / tiktoken-compatible models).\n * - `gemini` — exact counts via `@lenml/tokenizer-gemini`, which embeds Gemini's actual\n * SentencePiece vocabulary locally with no API call required.\n * - `llama2` — exact counts via `llama-tokenizer-js` (Llama 1 and 2). Llama 3+ uses a\n * different vocabulary and should use the `llama3` identifier once a suitable sync backend\n * is available.\n * - `claude` — heuristic approximation using Anthropic's published ~3.5 chars/token ratio.\n * No local tokenizer is available for Claude 3+ models; the Anthropic SDK's\n * `messages.countTokens()` API is the only exact path but requires a network call.\n *\n * When adding a new encoding, add a case to {@link Tokenizable.estimateTokens}.\n */\nexport const TokenEncoding = [\n 'gpt2',\n 'r50k_base',\n 'p50k_base',\n 'p50k_edit',\n 'cl100k_base',\n 'o200k_base',\n 'gemini',\n 'llama2',\n 'claude',\n] as const\n\n/**\n * Union of all recognised token encoding identifier strings.\n *\n * @remarks\n * Derived from {@link TokenEncoding} so the type and the runtime array stay in sync\n * automatically when new encodings are added.\n */\nexport type TokenEncoding = (typeof TokenEncoding)[number]\n\n/**\n * Backing schema for {@link Tokenizable.schema}.\n *\n * @remarks\n * Accepts a plain `string` or an existing {@link Tokenizable} instance. Strings pass through\n * unchanged; {@link Tokenizable} instances are accepted via {@link Tokenizable.isTokenizable}\n * to remain cross-realm safe.\n */\nconst stringOrTokenizableSchema = validator.alternatives(\n validator.string(),\n validator.custom((value, helpers) => {\n if (Tokenizable.isTokenizable(value)) {\n return value\n }\n return helpers.error('any.invalid')\n })\n)\n\n// Lazily-initialised singletons — tokenizers are expensive to load so we defer\n// until first use and reuse across all Tokenizable instances thereafter.\nlet geminiTokenizerInstance: ReturnType<typeof geminiFromPreTrained> | undefined\nlet llamaTokenizerInstance: InstanceType<typeof LlamaTokenizer> | undefined\n\nconst getGeminiTokenizer = () => {\n if (!geminiTokenizerInstance) {\n geminiTokenizerInstance = geminiFromPreTrained()\n }\n return geminiTokenizerInstance\n}\n\nconst getLlamaTokenizer = () => {\n if (!llamaTokenizerInstance) {\n llamaTokenizerInstance = new LlamaTokenizer()\n }\n return llamaTokenizerInstance\n}\n\n/**\n * A mutable string with a built-in token counter.\n *\n * @remarks\n * The wrapped string can be read via the standard coercion protocol and updated at any time via\n * {@link Tokenizable.set}. Token counts are computed lazily on first access per encoding and\n * cached until the value changes, avoiding redundant encoder invocations when the same content\n * is measured multiple times across a pipeline.\n *\n * Estimation is dispatched by encoding identifier — see {@link TokenEncoding} for the full list\n * of supported backends and their accuracy characteristics. Unrecognised encodings fall back to\n * a `ceil(length / 4)` character heuristic.\n *\n * The class implements the standard JS value-coercion protocol (`toString`, `valueOf`,\n * `toJSON`, `toLocaleString`, `Symbol.for('nodejs.util.inspect.custom')`) so instances behave\n * transparently as strings in most contexts.\n */\nexport class Tokenizable {\n public static TokenEncoding = TokenEncoding\n\n /**\n * Validator schema that accepts a plain `string` or a {@link Tokenizable} instance.\n *\n * @remarks\n * Reusable fragment for any schema that wants to accept either form — for example,\n * `systemPrompt` and each item in `standingInstructions` in `turnContextSchema`.\n */\n public static schema = stringOrTokenizableSchema\n\n declare toJSON: () => string\n declare toString: () => string\n declare valueOf: () => string\n declare toLocaleString: () => string\n declare set: (value: string) => void\n declare estimateTokens: (encoding: TokenEncoding) => number\n\n #value: string\n #cache: Map<TokenEncoding, number> = new Map()\n\n /**\n * @param value - The initial string value to wrap.\n */\n constructor(value: string) {\n this.#value = value\n\n const estimateTokensWithTiktoken = (encoding: TokenEncoding): number => {\n try {\n const enc: Tiktoken = getEncoding(encoding as any)\n return enc.encode(this.#value, []).length\n } catch {\n return Number.POSITIVE_INFINITY\n }\n }\n\n const estimateTokensWithGemini = (): number => {\n try {\n return getGeminiTokenizer().encode(this.#value).length\n } catch {\n return Number.POSITIVE_INFINITY\n }\n }\n\n const estimateTokensWithLlama2 = (): number => {\n try {\n return getLlamaTokenizer().encode(this.#value, false).length\n } catch {\n return Number.POSITIVE_INFINITY\n }\n }\n\n const estimateTokensWithClaudeHeuristic = (): number => {\n try {\n return Math.ceil(this.#value.length / 3.5)\n } catch {\n return Number.POSITIVE_INFINITY\n }\n }\n\n Object.defineProperties(this, {\n toJSON: {\n value: () => this.#value,\n enumerable: false,\n configurable: false,\n writable: false,\n },\n toString: {\n value: () => this.#value,\n enumerable: false,\n configurable: false,\n writable: false,\n },\n valueOf: {\n value: () => this.#value,\n enumerable: false,\n configurable: false,\n writable: false,\n },\n toLocaleString: {\n value: () => this.#value,\n enumerable: false,\n configurable: false,\n writable: false,\n },\n [Symbol.for('nodejs.util.inspect.custom')]: {\n value: () => this.#value,\n enumerable: false,\n configurable: false,\n writable: false,\n },\n set: {\n value: (next: string) => {\n this.#value = next\n this.#cache.clear()\n },\n enumerable: false,\n configurable: false,\n writable: false,\n },\n estimateTokens: {\n value: (encoding: TokenEncoding): number => {\n if (this.#cache.has(encoding)) {\n return this.#cache.get(encoding)!\n }\n\n let estimate: number\n switch (encoding) {\n case 'gpt2':\n case 'r50k_base':\n case 'p50k_base':\n case 'p50k_edit':\n case 'cl100k_base':\n case 'o200k_base':\n estimate = estimateTokensWithTiktoken(encoding)\n break\n case 'gemini':\n estimate = estimateTokensWithGemini()\n break\n case 'llama2':\n estimate = estimateTokensWithLlama2()\n break\n case 'claude':\n estimate = estimateTokensWithClaudeHeuristic()\n break\n }\n if (estimate === Number.POSITIVE_INFINITY) {\n estimate = Math.ceil(this.#value.length / 4)\n } else {\n this.#cache.set(encoding, estimate)\n }\n return estimate\n },\n enumerable: false,\n configurable: false,\n writable: false,\n },\n })\n }\n\n /**\n * Convenience overload for one-off token counting without managing a {@link Tokenizable} instance.\n *\n * @remarks\n * Creates a temporary instance and immediately discards it — no caching benefit. Use the\n * instance method when you need to count the same value under multiple encodings or when the\n * value may change over time.\n *\n * @param value - The string to count tokens for.\n * @param encoding - The encoding identifier to use for counting.\n * @returns The estimated number of tokens.\n */\n public static estimateTokens(value: string, encoding: TokenEncoding): number {\n const temp = new Tokenizable(value)\n return temp.estimateTokens(encoding)\n }\n\n /**\n * Returns `true` if `value` is a {@link Tokenizable} instance.\n *\n * @remarks\n * Uses {@link @nhtio/adk!isInstanceOf} for cross-realm safety — `instanceof` would fail for instances\n * created in a different module copy or VM context.\n *\n * @param value - The value to test.\n * @returns `true` when `value` is a {@link Tokenizable} instance.\n */\n public static isTokenizable(value: unknown): value is Tokenizable {\n return isInstanceOf(value, 'Tokenizable', Tokenizable)\n }\n}\n\n/**\n * Returns `true` if `value` is a {@link Tokenizable} instance.\n *\n * @remarks\n * Module-level convenience alias for {@link Tokenizable.isTokenizable}. Prefer this form when\n * you need a standalone type guard without importing the full class.\n *\n * Uses {@link @nhtio/adk!isInstanceOf} for cross-realm safety — `instanceof` would fail for instances\n * created in a different module copy or VM context.\n *\n * @param value - The value to test.\n * @returns `true` when `value` is a {@link Tokenizable} instance.\n */\nexport const isTokenizable = (value: unknown): value is Tokenizable => {\n return isInstanceOf(value, 'Tokenizable', Tokenizable)\n}\n","import { dset } from 'dset'\nimport { klona } from 'klona'\nimport { default as delve } from 'dlv'\nimport { isInstanceOf, isObject } from '../utils/guards'\nimport { E_INVALID_INITIAL_REGISTRY_VALUE } from '../exceptions/runtime'\n\n/**\n * A controlled-mutation key-value store with dot-path access and deep-clone isolation.\n *\n * @remarks\n * The registry enforces a safe read/write contract: callers never hold a live reference into\n * the internal store. Every value that enters (`set`) or leaves (`get`, `all`) is deep-cloned\n * via `klona`, so mutations to a retrieved value cannot affect stored state and vice versa.\n *\n * Keys are dot-delimited paths (e.g. `\"user.profile.name\"`), resolved via `dlv` for reads and\n * `dset` for writes; intermediate objects are created automatically on write.\n */\nexport class Registry {\n #store: Record<string, unknown>\n\n /**\n * @param initial - Optional plain object to seed the registry. Deep-cloned on construction.\n * @throws {@link @nhtio/adk!E_INVALID_INITIAL_REGISTRY_VALUE} when `initial` is defined but not a plain object.\n */\n constructor(initial?: Record<string, unknown>) {\n if ('undefined' !== typeof initial && !isObject(initial)) {\n throw new E_INVALID_INITIAL_REGISTRY_VALUE()\n }\n this.#store = initial ? klona(initial) : {}\n }\n\n /**\n * Returns `true` if `value` is a {@link Registry} instance.\n *\n * @remarks\n * Uses {@link @nhtio/adk!isInstanceOf} for cross-realm safety.\n *\n * @param value - The value to test.\n * @returns `true` when `value` is a {@link Registry} instance.\n */\n public static isRegistry(value: unknown): value is Registry {\n return isInstanceOf(value, 'Registry', Registry)\n }\n\n /**\n * Retrieves the value at `key`, returning `defaultValue` if the path is absent.\n *\n * @remarks\n * The returned value is a deep clone — mutating it will not affect the stored state.\n *\n * @typeParam T - Expected type of the value at `key`.\n * @param key - Dot-delimited path into the store (e.g. `\"user.name\"`).\n * @param defaultValue - Fallback returned when the path resolves to `undefined`.\n * @returns A deep clone of the stored value cast to `T`, or `defaultValue` when the path is absent.\n */\n get<T = unknown>(key: string, defaultValue?: T): T {\n const cloned = klona(this.#store)\n const value = delve(cloned, key)\n return 'undefined' === typeof value ? (defaultValue as T) : (value as T)\n }\n\n /**\n * Sets the value at `key`, creating intermediate objects as needed.\n *\n * @remarks\n * The stored value is isolated from the caller — mutating `value` after this call will not\n * affect what is held in the registry.\n *\n * @param key - Dot-delimited path into the store (e.g. `\"user.name\"`).\n * @param value - Value to store at the path.\n */\n set(key: string, value: unknown): void {\n dset(this.#store, key, value)\n }\n\n /**\n * Returns `true` if the registry has a value at `key`, `false` otherwise.\n *\n * @remarks\n * A key resolving to `undefined` is treated as absent — same convention as {@link Registry.get}'s\n * `defaultValue` fallback. No clone is performed; this is a pure existence check.\n *\n * @param key - Dot-delimited path into the store (e.g. `\"user.name\"`).\n * @returns `true` when the path resolves to a value other than `undefined`.\n */\n has(key: string): boolean {\n return 'undefined' !== typeof delve(this.#store, key)\n }\n\n /**\n * Returns all leaf dot-paths present in the registry.\n *\n * @remarks\n * The store is deep-cloned before traversal. Plain objects are walked recursively with path\n * segments joined by dots; arrays, primitives, `null`, and class instances are treated as leaves.\n *\n * @returns A string array of dot-delimited paths to leaf values in the store.\n */\n keys(): string[] {\n const store = klona(this.#store)\n const keys: string[] = []\n\n const isPlainRecord = (value: unknown): value is Record<string, unknown> => {\n if (!isObject(value)) return false\n const prototype = Object.getPrototypeOf(value)\n return prototype === Object.prototype || prototype === null\n }\n\n const walk = (value: unknown, segments: string[]): void => {\n if (!isPlainRecord(value)) {\n if (segments.length > 0) keys.push(segments.join('.'))\n return\n }\n\n for (const [segment, child] of Object.entries(value)) {\n walk(child, [...segments, segment])\n }\n }\n\n walk(store, [])\n return keys\n }\n\n /**\n * Returns a deep clone of the entire store contents.\n *\n * @returns A plain object snapshot of all stored key-value pairs.\n */\n all(): Record<string, unknown> {\n return klona(this.#store)\n }\n}\n","/**\n * Canonical `JSON.stringify` that sorts object keys recursively so that semantically-equal\n * objects produce identical strings.\n *\n * @remarks\n * Used wherever the ADK derives a stable identity from a structured value — for example,\n * `Tool.executor` computing the `callId` for `ToolExecutionStart`/`End` events, and the\n * `reportToolCall` executor helper computing the `checksum` field on `TurnToolCallContent`.\n * Both code paths hash `canonicalStringify({ tool, args })` so that argument key order does not\n * affect the resulting identifier.\n *\n * Arrays are serialised in their declared order (order is meaningful for an array). Object keys\n * are sorted with `Array.prototype.sort()`'s default lexicographic comparator.\n *\n * @param value - The value to serialise.\n * @returns A canonical JSON string representation of `value`.\n */\nexport function canonicalStringify(value: unknown): string {\n if (value === null || typeof value !== 'object') return JSON.stringify(value)\n if (Array.isArray(value)) return '[' + value.map((v) => canonicalStringify(v)).join(',') + ']'\n const obj = value as Record<string, unknown>\n const keys = Object.keys(obj).sort()\n return '{' + keys.map((k) => JSON.stringify(k) + ':' + canonicalStringify(obj[k])).join(',') + '}'\n}\n","import { isInstanceOf } from '../utils/guards'\nimport { E_TOOL_ALREADY_REGISTERED } from '../exceptions/runtime'\nimport type { Tool } from './tool'\nimport type { DispatchContext } from '../contracts/dispatch_context'\n\n/**\n * Options accepted by {@link ToolRegistry.merge}.\n */\nexport interface MergeOptions {\n /**\n * What to do when two registries contain a tool with the same name AND neither tool's own\n * `onCollision` resolves the collision.\n *\n * @remarks\n * - `'throw'` (default): raise {@link @nhtio/adk!E_TOOL_ALREADY_REGISTERED} on the first unresolved\n * collision. Mirrors the default behaviour of {@link ToolRegistry.register} and surfaces\n * accidental name shadowing immediately.\n * - `'replace'`: the later registry's tool wins.\n * - `'keep'`: the earlier registry's tool wins; later occurrences are dropped.\n *\n * Per-tool {@link @nhtio/adk!Tool.onCollision} takes precedence: if the incoming tool declares\n * `'replace'` or `'keep'`, that policy wins regardless of this option. Only when the incoming\n * tool's policy is `'throw'` (the default) does this fallback apply.\n *\n * @defaultValue `'throw'`\n */\n onCollision?: 'throw' | 'replace' | 'keep'\n}\n\n/**\n * A mutable, turn-scoped collection of {@link @nhtio/adk!Tool} instances.\n *\n * @remarks\n * Each `TurnRunner.run()` call constructs a fresh `ToolRegistry` from the runner's configured\n * baseline tools, so middleware edits are isolated to the current turn and cannot bleed across\n * concurrent or subsequent turns.\n *\n * `Tool` instances are immutable, so `all()` returns a fresh array without deep-cloning.\n *\n * `register()` throws {@link @nhtio/adk!E_TOOL_ALREADY_REGISTERED} if a tool with the same name is already\n * present — pass `overwrite: true` to replace it explicitly.\n */\nexport class ToolRegistry {\n #tools: Map<string, Tool>\n\n /**\n * Returns `true` if `value` is a {@link ToolRegistry} instance.\n *\n * @param value - The value to test.\n * @returns `true` when `value` is a {@link ToolRegistry} instance.\n */\n public static isToolRegistry(value: unknown): value is ToolRegistry {\n return isInstanceOf(value, 'ToolRegistry', ToolRegistry)\n }\n\n /**\n * @param tools - Optional initial tools. Insertion order is preserved. Duplicate names throw\n * {@link @nhtio/adk!E_TOOL_ALREADY_REGISTERED} — ensure each tool has a unique name.\n * @throws {@link @nhtio/adk!E_TOOL_ALREADY_REGISTERED} when two tools in `tools` share a name.\n */\n constructor(tools?: Tool[]) {\n this.#tools = new Map()\n for (const tool of tools ?? []) {\n this.register(tool)\n }\n }\n\n /**\n * Adds a tool to the registry.\n *\n * @param tool - The tool to register.\n * @param overwrite - When `true`, silently replaces an existing tool with the same name.\n * Defaults to `false`.\n * @throws {@link @nhtio/adk!E_TOOL_ALREADY_REGISTERED} when a tool with the same name is already registered\n * and `overwrite` is not `true`.\n */\n register(tool: Tool, overwrite?: boolean): void {\n if (this.#tools.has(tool.name) && !overwrite) {\n throw new E_TOOL_ALREADY_REGISTERED()\n }\n this.#tools.set(tool.name, tool)\n }\n\n /**\n * Removes the tool with the given name from the registry.\n *\n * @remarks\n * No-ops if no tool with that name is registered.\n *\n * @param name - The name of the tool to remove.\n */\n unregister(name: string): void {\n this.#tools.delete(name)\n }\n\n /**\n * Returns the tool registered under `name`, or `undefined` if not present.\n *\n * @param name - The tool name to look up.\n */\n get(name: string): Tool | undefined {\n return this.#tools.get(name)\n }\n\n /**\n * Returns `true` if a tool with the given name is registered.\n *\n * @param name - The tool name to test.\n */\n has(name: string): boolean {\n return this.#tools.has(name)\n }\n\n /**\n * Returns a fresh array of all registered tools in insertion order.\n *\n * @remarks\n * Since {@link @nhtio/adk!Tool} instances are immutable, no deep-cloning is needed.\n */\n all(): Tool[] {\n return Array.from(this.#tools.values())\n }\n\n /**\n * Removes every tool whose {@link @nhtio/adk!Tool.ephemeral} flag is `true`.\n *\n * @remarks\n * Synchronous and idempotent — calling it twice in a row is a no-op the second time. The\n * canonical caller is {@link ToolRegistry.bindContext}, which schedules this method to run\n * at {@link @nhtio/adk!DispatchContext.ack}. Non-ephemeral tools are left untouched.\n */\n pruneEphemeral(): void {\n for (const [name, tool] of this.#tools) {\n if (tool.ephemeral) {\n this.#tools.delete(name)\n }\n }\n }\n\n /**\n * Binds this registry to a {@link @nhtio/adk!DispatchContext} so that {@link pruneEphemeral} runs\n * automatically when the context is acked.\n *\n * @remarks\n * The handler does NOT fire on {@link @nhtio/adk!DispatchContext.nack} — failed executor runs leave\n * any forged tools in place so the consumer can inspect what was registered when debugging the\n * failure. Subscriptions are short-lived and die with the context regardless.\n *\n * Forgetting this call after merging in `Subclass.forgeTools(ctx)` output means ephemeral tools\n * accumulate across executor invocations, and subsequent `forgeTools(ctx)` calls in later\n * iterations will see a stale `callId` enum that excludes new tool calls. The plan-documented\n * pattern is:\n *\n * ```ts\n * const executor: DispatchExecutorFn = async (ctx) => {\n * const forged = SpooledArtifact.forgeTools(ctx)\n * const merged = ToolRegistry.merge([main, forged])\n * main.bindContext(ctx)\n * const result = await llm.invoke({ tools: merged.all(), ... })\n * ctx.ack()\n * }\n * ```\n *\n * @param ctx - The execution context whose `ack` event should trigger pruning.\n * @returns An unsubscribe function — calling it before `ctx.ack()` prevents pruning. Rarely\n * useful outside of tests.\n *\n * @see {@link @nhtio/adk!SpooledArtifact.forgeTools}\n * @see {@link @nhtio/adk!DispatchContext.onAck}\n */\n bindContext(ctx: DispatchContext): () => void {\n return ctx.onAck(() => this.pruneEphemeral())\n }\n\n /**\n * Combines multiple {@link ToolRegistry} instances into a fresh registry without mutating any\n * input.\n *\n * @remarks\n * Iteration is left-to-right across `registries` and then in each registry's insertion order.\n * Collisions are resolved by consulting the **incoming** tool's {@link @nhtio/adk!Tool.onCollision} first:\n *\n * - `'replace'` (per-tool): the incoming tool wins, replacing the existing entry.\n * - `'keep'` (per-tool): the existing entry wins; the incoming tool is dropped.\n * - `'throw'` (per-tool, the default): fall back to the merge-level `options.onCollision`.\n *\n * The merge-level `options.onCollision` defaults to `'throw'`, which mirrors {@link register}.\n *\n * The result is a brand-new registry; no input is mutated and no event subscription is\n * propagated. Each `Tool`'s `ephemeral` flag carries through unchanged — the flag lives on the\n * tool, not the registry, so `bindContext(ctx)` on the merged registry will prune the forged\n * tools as expected.\n *\n * @param registries - Registries to merge, in priority order (left-to-right insertion).\n * @param options - Merge-level collision policy. Defaults to `{ onCollision: 'throw' }`.\n * @returns A fresh {@link ToolRegistry} containing the resolved union of all inputs.\n * @throws {@link @nhtio/adk!E_TOOL_ALREADY_REGISTERED} when the resolved collision policy is `'throw'`\n * and a collision occurs.\n */\n static merge(registries: ToolRegistry[], options?: MergeOptions): ToolRegistry {\n const policy = options?.onCollision ?? 'throw'\n const merged = new ToolRegistry()\n for (const registry of registries) {\n for (const tool of registry.all()) {\n const existing = merged.get(tool.name)\n if (!existing) {\n merged.register(tool)\n continue\n }\n const incomingPolicy = tool.onCollision\n if (incomingPolicy === 'replace') {\n merged.register(tool, true)\n continue\n }\n if (incomingPolicy === 'keep') {\n continue\n }\n // Incoming policy is 'throw' — fall back to the merge-level option.\n if (policy === 'replace') {\n merged.register(tool, true)\n continue\n }\n if (policy === 'keep') {\n continue\n }\n throw new E_TOOL_ALREADY_REGISTERED()\n }\n }\n return merged\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
require("./
|
|
2
|
-
const require_exceptions = require("./exceptions-
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const require_dispatch_runner = require("./dispatch_runner-CsoH0nld.js");
|
|
1
|
+
const require_tool_registry = require("./tool_registry-snPjF0zJ.js");
|
|
2
|
+
const require_exceptions = require("./exceptions-CSqzbL1N.js");
|
|
3
|
+
const require_runtime = require("./runtime-BUDWyd-R.js");
|
|
4
|
+
const require_tool = require("./tool-cwJyEHI9.js");
|
|
5
|
+
const require_dispatch_runner = require("./dispatch_runner-BWYNxmnp.js");
|
|
7
6
|
let _nhtio_validation = require("@nhtio/validation");
|
|
8
7
|
let luxon = require("luxon");
|
|
9
8
|
let _nhtio_middleware = require("@nhtio/middleware");
|
|
@@ -254,6 +253,8 @@ var turnRunnerConfigSchema = _nhtio_validation.validator.object({
|
|
|
254
253
|
storeToolCallCallback: _nhtio_validation.validator.function().arity(2).required(),
|
|
255
254
|
mutateToolCallCallback: _nhtio_validation.validator.function().arity(2).required(),
|
|
256
255
|
deleteToolCallCallback: _nhtio_validation.validator.function().arity(2).required(),
|
|
256
|
+
storeMediaBytesCallback: _nhtio_validation.validator.function().arity(3).required(),
|
|
257
|
+
storeRetrievableBytesCallback: _nhtio_validation.validator.function().arity(3).required(),
|
|
257
258
|
tools: _nhtio_validation.validator.array().items(_nhtio_validation.validator.any().custom((value, helpers) => {
|
|
258
259
|
if (require_tool.Tool.isTool(value)) return value;
|
|
259
260
|
return helpers.error("any.invalid");
|
|
@@ -503,6 +504,8 @@ var TurnRunner = class TurnRunner {
|
|
|
503
504
|
storeToolCall: this.#config.storeToolCallCallback,
|
|
504
505
|
mutateToolCall: this.#config.mutateToolCallCallback,
|
|
505
506
|
deleteToolCall: this.#config.deleteToolCallCallback,
|
|
507
|
+
storeMediaBytes: this.#config.storeMediaBytesCallback,
|
|
508
|
+
storeRetrievableBytes: this.#config.storeRetrievableBytesCallback,
|
|
506
509
|
emitMessage: (content) => this.#functionalEmitter.emit("message", content),
|
|
507
510
|
emitThought: (content) => this.#functionalEmitter.emit("thought", content),
|
|
508
511
|
emitToolCall: (content) => this.#functionalEmitter.emit("toolCall", content),
|
|
@@ -612,4 +615,4 @@ Object.defineProperty(exports, "TurnRunner", {
|
|
|
612
615
|
}
|
|
613
616
|
});
|
|
614
617
|
|
|
615
|
-
//# sourceMappingURL=turn_runner-
|
|
618
|
+
//# sourceMappingURL=turn_runner-BScT8OgA.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"turn_runner-BScT8OgA.js","names":["#id","#turnId","#reason","#payload","#createdAt","#settled","#schema","#controller","#promise","#resolve","#reject","#config","#inputRunner","#outputRunner","#functionalEmitter","#observabilityEmitter"],"sources":["../src/lib/classes/turn_gate.ts","../src/lib/contracts/turn_runner_config.ts","../src/lib/turn_runner.ts"],"sourcesContent":["import { DateTime } from 'luxon'\nimport { validator } from '@nhtio/validation'\nimport { validateOrThrow } from '../utils/validation'\nimport { isInstanceOf, isError, isObject } from '../utils/guards'\nimport {\n E_TURN_GATE_ABORTED,\n E_TURN_GATE_TIMEOUT,\n E_INVALID_TURN_GATE_RESOLUTION,\n E_INVALID_INITIAL_TURN_GATE_VALUE,\n} from '../exceptions/runtime'\nimport type { Schema } from '@nhtio/validation'\n\n/**\n * Plain input object supplied to {@link TurnGate} at construction time.\n *\n * @remarks\n * `turnId` and `abortSignal` are injected by the runner — callers constructing a gate via\n * `ctx.waitFor()` never supply them directly.\n *\n * `abortSignal` is `AbortSignal` (not `AbortController`) because the gate reacts to turn-level\n * cancellation but cannot trigger it. The gate owns its own internal `AbortController` for\n * `gate.abort()`.\n */\nexport interface RawTurnGate {\n /** Stable unique identifier for this gate. */\n id: string\n /** The ID of the turn that opened this gate. */\n turnId: string\n /** Human-readable label describing why this gate was opened (e.g. `'tool_approval'`). */\n reason: string\n /** Arbitrary data supplied to the gate opener; passed through to `turnGateOpen` listeners. */\n payload: unknown\n /** Optional validator schema for the resolution value. When present, `resolve()` validates before settling. */\n schema?: Schema\n /** Optional timeout in milliseconds. When elapsed the gate self-rejects with {@link @nhtio/adk!E_TURN_GATE_TIMEOUT}. */\n timeout?: number\n /** The turn's abort signal. When fired the gate self-rejects with {@link @nhtio/adk!E_TURN_GATE_ABORTED}. */\n abortSignal?: AbortSignal\n /** When this gate was created. */\n createdAt: string | number | Date | DateTime\n}\n\n/**\n * Fully-resolved {@link RawTurnGate} after schema validation.\n *\n * @internal\n */\ninterface ResolvedTurnGate {\n id: string\n turnId: string\n reason: string\n payload: unknown\n schema?: Schema\n timeout?: number\n abortSignal?: AbortSignal\n createdAt: DateTime\n}\n\n/**\n * Validator schema used to validate a {@link RawTurnGate} before constructing a {@link TurnGate}.\n *\n * @remarks\n * - `schema` and `abortSignal` are validated as opaque passthrough values.\n * - `timeout` must be a positive integer when provided.\n */\nconst rawTurnGateSchema = validator.object<RawTurnGate>({\n id: validator.string().required(),\n turnId: validator.string().required(),\n reason: validator.string().required(),\n payload: validator.any().required(),\n schema: validator\n .any()\n .custom((value, helpers) => {\n if (value === undefined || value === null) return undefined\n if (typeof (value as any).validate === 'function') return value\n return helpers.error('any.invalid')\n })\n .optional(),\n timeout: validator.number().integer().min(1).optional(),\n abortSignal: validator\n .any()\n .custom((value, helpers) => {\n if (value === undefined || value === null) return undefined\n // eslint-disable-next-line adk/use-is-instance-of -- native built-in; AbortSignal cross-realm is handled by the duck-type fallback below\n if (typeof AbortSignal !== 'undefined' && value instanceof AbortSignal) return value\n if (\n isObject(value) &&\n typeof (value as any).aborted === 'boolean' &&\n typeof (value as any).addEventListener === 'function'\n ) {\n return value\n }\n return helpers.error('any.invalid')\n })\n .optional(),\n createdAt: validator.datetime().required(),\n})\n\n/**\n * A cooperative suspension gate that blocks a turn's middleware pipeline until resolved, rejected,\n * aborted, or timed out.\n *\n * @typeParam T - The expected type of the resolution value.\n *\n * @remarks\n * Created exclusively via `ctx.waitFor()` — middleware never constructs a gate directly.\n * The gate emits `turnGateOpen` on the runner's observability bus at creation time and\n * `turnGateClosed` when it settles.\n *\n * Resolution is validated against an optional schema before the internal promise is settled.\n * A validation failure throws {@link @nhtio/adk!E_INVALID_TURN_GATE_RESOLUTION} **synchronously in the\n * caller's context** — the promise is NOT settled and the gate remains open.\n */\nexport class TurnGate<T = unknown> {\n /**\n * Validator schema that accepts a {@link RawTurnGate} object.\n *\n * @remarks\n * Reusable fragment for any schema that needs to validate or nest a gate entry.\n */\n public static schema = rawTurnGateSchema\n\n /**\n * Returns `true` if `value` is a {@link TurnGate} instance.\n *\n * @remarks\n * Uses {@link @nhtio/adk!isInstanceOf} for cross-realm safety.\n *\n * @param value - The value to test.\n * @returns `true` when `value` is a {@link TurnGate} instance.\n */\n public static isTurnGate(value: unknown): value is TurnGate {\n return isInstanceOf(value, 'TurnGate', TurnGate)\n }\n\n declare readonly id: string\n declare readonly turnId: string\n declare readonly reason: string\n declare readonly payload: unknown\n declare readonly createdAt: DateTime\n declare readonly isSettled: boolean\n\n #id: string\n #turnId: string\n #reason: string\n #payload: unknown\n #createdAt: DateTime\n #settled: boolean\n #schema: Schema | undefined\n #controller: AbortController\n #resolve!: (value: T) => void\n #reject!: (reason: unknown) => void\n #promise: Promise<T>\n\n /**\n * @param raw - The raw gate input validated against `rawTurnGateSchema`.\n * @throws {@link @nhtio/adk!E_INVALID_INITIAL_TURN_GATE_VALUE} when `raw` does not satisfy the schema.\n */\n constructor(raw: RawTurnGate) {\n let resolved: ResolvedTurnGate\n try {\n resolved = validateOrThrow<ResolvedTurnGate>(rawTurnGateSchema, raw, true)\n } catch (err) {\n throw new E_INVALID_INITIAL_TURN_GATE_VALUE({ cause: isError(err) ? err : undefined })\n }\n\n this.#id = resolved.id\n this.#turnId = resolved.turnId\n this.#reason = resolved.reason\n this.#payload = resolved.payload\n this.#createdAt = resolved.createdAt\n this.#settled = false\n this.#schema = resolved.schema\n this.#controller = new AbortController()\n\n this.#promise = new Promise<T>((resolve, reject) => {\n this.#resolve = resolve\n this.#reject = reject\n })\n\n // Wire the internal abort controller\n const onAbort = () => {\n if (!this.#settled) {\n this.#settled = true\n this.#reject(new E_TURN_GATE_ABORTED())\n }\n }\n\n this.#controller.signal.addEventListener('abort', onAbort, { once: true })\n\n // Wire the external turn abort signal\n if (resolved.abortSignal) {\n if (resolved.abortSignal.aborted) {\n // Already aborted — reject immediately after construction\n queueMicrotask(() => onAbort())\n } else {\n resolved.abortSignal.addEventListener('abort', onAbort, { once: true })\n // Clean up the external listener once the gate settles via another path\n this.#promise.then(\n () => resolved.abortSignal!.removeEventListener('abort', onAbort),\n () => resolved.abortSignal!.removeEventListener('abort', onAbort)\n )\n }\n }\n\n // Wire the timeout\n if (resolved.timeout !== undefined) {\n const timer = setTimeout(() => {\n if (!this.#settled) {\n this.#settled = true\n this.#reject(new E_TURN_GATE_TIMEOUT())\n }\n }, resolved.timeout)\n\n this.#promise.then(\n () => clearTimeout(timer),\n () => clearTimeout(timer)\n )\n }\n\n Object.defineProperties(this, {\n id: {\n get: () => this.#id,\n enumerable: true,\n configurable: false,\n },\n turnId: {\n get: () => this.#turnId,\n enumerable: true,\n configurable: false,\n },\n reason: {\n get: () => this.#reason,\n enumerable: true,\n configurable: false,\n },\n payload: {\n get: () => this.#payload,\n enumerable: true,\n configurable: false,\n },\n createdAt: {\n get: () => this.#createdAt,\n enumerable: true,\n configurable: false,\n },\n isSettled: {\n get: () => this.#settled,\n enumerable: true,\n configurable: false,\n },\n })\n }\n\n /**\n * Resolves the gate with `value`, unblocking the awaiting middleware.\n *\n * @remarks\n * If a schema was provided at construction, `value` is validated synchronously before the\n * promise is settled. A validation failure throws {@link @nhtio/adk!E_INVALID_TURN_GATE_RESOLUTION}\n * in the caller's context — the promise is NOT settled and the gate remains open.\n *\n * No-ops if the gate is already settled.\n *\n * @param value - The resolution value. Must satisfy the gate's schema when one was provided.\n * @throws {@link @nhtio/adk!E_INVALID_TURN_GATE_RESOLUTION} when `value` fails schema validation.\n */\n resolve(value: unknown): void {\n if (this.#settled) return\n if (this.#schema !== undefined) {\n try {\n value = validateOrThrow(this.#schema, value, true)\n } catch (err) {\n throw new E_INVALID_TURN_GATE_RESOLUTION({\n cause: isError(err) ? err : undefined,\n })\n }\n }\n this.#settled = true\n this.#resolve(value as T)\n }\n\n /**\n * Rejects the gate with `error`, unblocking the awaiting middleware with a rejection.\n *\n * @remarks\n * No-ops if the gate is already settled.\n *\n * @param error - The rejection reason.\n */\n reject(error: Error): void {\n if (this.#settled) return\n this.#settled = true\n this.#reject(error)\n }\n\n /**\n * Aborts the gate by firing the internal `AbortController`, which rejects the promise with\n * {@link @nhtio/adk!E_TURN_GATE_ABORTED}.\n *\n * @remarks\n * No-ops if the gate is already settled. Distinct from the turn-level abort signal — this\n * allows callers to cancel a specific gate without aborting the whole turn.\n */\n abort(): void {\n if (this.#settled) return\n this.#controller.abort()\n }\n\n /**\n * Returns the internal promise. Called by `ctx.waitFor()` to block the middleware pipeline.\n *\n * @internal\n */\n _promise(): Promise<T> {\n return this.#promise\n }\n}\n","import { Tool } from '../classes/tool'\nimport { validator } from '@nhtio/validation'\nimport type { TurnPipelineMiddlewareFn } from '../types/turn_runner'\nimport type { DispatchPipelineMiddlewareFn, DispatchExecutorFn } from '../types/dispatch_runner'\nimport type {\n MemoryRetrievalFn,\n MessageRetrievalFn,\n ThoughtRetrievalFn,\n ToolCallRetrievalFn,\n ToolsRetrievalFn,\n StandingInstructionsRefreshFn,\n StandingInstructionStoreFn,\n StandingInstructionMutateFn,\n StandingInstructionDeleteFn,\n MemoryStoreFn,\n MemoryMutateFn,\n MemoryDeleteFn,\n RetrievableRetrievalFn,\n RetrievableStoreFn,\n RetrievableMutateFn,\n RetrievableDeleteFn,\n MessageStoreFn,\n MessageMutateFn,\n MessageDeleteFn,\n ThoughtStoreFn,\n ThoughtMutateFn,\n ThoughtDeleteFn,\n ToolCallStoreFn,\n ToolCallMutateFn,\n ToolCallDeleteFn,\n MediaBytesStoreFn,\n RetrievableBytesStoreFn,\n} from './turn_runner_context'\n\n/**\n * Configuration supplied to {@link @nhtio/adk!TurnRunner} at construction time.\n *\n * @remarks\n * Validated against `turnRunnerConfigSchema` at construction — a misconfigured runner throws\n * immediately rather than failing on the first turn.\n *\n * All fetch and mutation callbacks are required: they are injected into each {@link @nhtio/adk!TurnContext}\n * so middleware can call fetch, refresh, and persistence methods directly on the context without\n * coupling to the runner.\n *\n * `tools` is optional at the caller level and defaults to `[]` after schema resolution — a runner\n * with no baseline tools is valid.\n */\nexport interface TurnRunnerConfig {\n /** Performs the LLM API/SDK call for each iteration of the dispatch loop; receives the active {@link @nhtio/adk!DispatchContext} and an {@link @nhtio/adk!DispatchExecutorHelpers} object for managing per-id stream state. */\n executorCallback: DispatchExecutorFn\n /** Called once per turn to supply memories; receives the active {@link @nhtio/adk!TurnContext}. */\n fetchMemoriesCallback: MemoryRetrievalFn\n /** Called once per turn to supply conversation history; receives the active {@link @nhtio/adk!TurnContext}. */\n fetchMessagesCallback: MessageRetrievalFn\n /** Called once per turn to supply thought traces; receives the active {@link @nhtio/adk!TurnContext}. */\n fetchThoughtsCallback: ThoughtRetrievalFn\n /** Called once per turn to supply tool call records; receives the active {@link @nhtio/adk!TurnContext}. */\n fetchToolCallsCallback: ToolCallRetrievalFn\n /** Called to supply available tools; receives the active {@link @nhtio/adk!TurnContext}. */\n fetchToolsCallback: ToolsRetrievalFn\n /** Called to refresh and return standing instructions; receives the active {@link @nhtio/adk!TurnContext}. */\n refreshStandingInstructionsCallback: StandingInstructionsRefreshFn\n /** Persists a new standing instruction. */\n storeStandingInstructionCallback: StandingInstructionStoreFn\n /** Updates an existing standing instruction in the persistence layer. */\n mutateStandingInstructionCallback: StandingInstructionMutateFn\n /** Removes a standing instruction from the persistence layer. */\n deleteStandingInstructionCallback: StandingInstructionDeleteFn\n /** Persists a new memory. */\n storeMemoryCallback: MemoryStoreFn\n /** Updates an existing memory in the persistence layer. */\n mutateMemoryCallback: MemoryMutateFn\n /** Removes a memory from the persistence layer by ID. */\n deleteMemoryCallback: MemoryDeleteFn\n /** Called once per turn to supply retrievable (RAG) records; receives the active {@link @nhtio/adk!TurnContext}. */\n fetchRetrievablesCallback: RetrievableRetrievalFn\n /** Persists a new retrievable record. */\n storeRetrievableCallback: RetrievableStoreFn\n /** Updates an existing retrievable record in the persistence layer. */\n mutateRetrievableCallback: RetrievableMutateFn\n /** Removes a retrievable record from the persistence layer by ID. */\n deleteRetrievableCallback: RetrievableDeleteFn\n /** Persists a new message. */\n storeMessageCallback: MessageStoreFn\n /** Updates an existing message in the persistence layer. */\n mutateMessageCallback: MessageMutateFn\n /** Removes a message from the persistence layer by ID. */\n deleteMessageCallback: MessageDeleteFn\n /** Persists a new thought. */\n storeThoughtCallback: ThoughtStoreFn\n /** Updates an existing thought in the persistence layer. */\n mutateThoughtCallback: ThoughtMutateFn\n /** Removes a thought from the persistence layer by ID. */\n deleteThoughtCallback: ThoughtDeleteFn\n /** Persists a new tool call. */\n storeToolCallCallback: ToolCallStoreFn\n /** Updates an existing tool call in the persistence layer. */\n mutateToolCallCallback: ToolCallMutateFn\n /** Removes a tool call from the persistence layer by ID. */\n deleteToolCallCallback: ToolCallDeleteFn\n /** Persists tool-generated media bytes into consumer storage; returns a `MediaReader`. */\n storeMediaBytesCallback: MediaBytesStoreFn\n /** Persists extracted retrievable text bytes into consumer storage; returns a `SpoolReader`. */\n storeRetrievableBytesCallback: RetrievableBytesStoreFn\n /** Baseline tools available on every turn. Middleware may trim or extend this per-turn via `ctx.tools`. Defaults to `[]`. */\n tools?: Tool[]\n /** Turn-level input middleware, executed in order against the {@link @nhtio/adk!TurnContext} before the LLM dispatch. Defaults to `[]`. */\n turnInputPipeline?: TurnPipelineMiddlewareFn[]\n /** Turn-level output middleware, executed in order against the {@link @nhtio/adk!TurnContext} after the LLM dispatch resolves successfully. Defaults to `[]`. */\n turnOutputPipeline?: TurnPipelineMiddlewareFn[]\n /** LLM-iteration input middleware, executed in order against the {@link @nhtio/adk!DispatchContext} before the executor on each iteration. Defaults to `[]`. */\n dispatchInputPipeline?: DispatchPipelineMiddlewareFn[]\n /** LLM-iteration output middleware, executed in order against the {@link @nhtio/adk!DispatchContext} after the executor on each iteration. Defaults to `[]`. */\n dispatchOutputPipeline?: DispatchPipelineMiddlewareFn[]\n}\n\n/**\n * Fully-resolved {@link TurnRunnerConfig} after schema validation.\n *\n * @remarks\n * All optional fields are guaranteed present (e.g. `tools` defaults to `[]`). The runner stores\n * this type internally so field access never needs to guard for undefined.\n */\nexport type ResolvedTurnRunnerConfig = Required<TurnRunnerConfig>\n\n/**\n * Validator schema used to validate a {@link TurnRunnerConfig} at {@link @nhtio/adk!TurnRunner} construction time.\n *\n * @remarks\n * Validates that all callbacks are functions of the correct arity, and that `tools` — when\n * provided — is an array of valid {@link @nhtio/adk!Tool} instances. Defaults `tools` to `[]`.\n *\n * Throws {@link @nhtio/adk!E_INVALID_TURN_RUNNER_CONFIG} (via the {@link @nhtio/adk!TurnRunner} constructor) when\n * validation fails.\n */\nexport const turnRunnerConfigSchema = validator.object<TurnRunnerConfig>({\n executorCallback: validator.function().required(),\n fetchMemoriesCallback: validator.function().arity(1).required(),\n fetchMessagesCallback: validator.function().arity(1).required(),\n fetchThoughtsCallback: validator.function().arity(1).required(),\n fetchToolCallsCallback: validator.function().arity(1).required(),\n fetchToolsCallback: validator.function().arity(1).required(),\n refreshStandingInstructionsCallback: validator.function().arity(1).required(),\n storeStandingInstructionCallback: validator.function().arity(2).required(),\n mutateStandingInstructionCallback: validator.function().arity(2).required(),\n deleteStandingInstructionCallback: validator.function().arity(2).required(),\n storeMemoryCallback: validator.function().arity(2).required(),\n mutateMemoryCallback: validator.function().arity(2).required(),\n deleteMemoryCallback: validator.function().arity(2).required(),\n fetchRetrievablesCallback: validator.function().arity(1).required(),\n storeRetrievableCallback: validator.function().arity(2).required(),\n mutateRetrievableCallback: validator.function().arity(2).required(),\n deleteRetrievableCallback: validator.function().arity(2).required(),\n storeMessageCallback: validator.function().arity(2).required(),\n mutateMessageCallback: validator.function().arity(2).required(),\n deleteMessageCallback: validator.function().arity(2).required(),\n storeThoughtCallback: validator.function().arity(2).required(),\n mutateThoughtCallback: validator.function().arity(2).required(),\n deleteThoughtCallback: validator.function().arity(2).required(),\n storeToolCallCallback: validator.function().arity(2).required(),\n mutateToolCallCallback: validator.function().arity(2).required(),\n deleteToolCallCallback: validator.function().arity(2).required(),\n storeMediaBytesCallback: validator.function().arity(3).required(),\n storeRetrievableBytesCallback: validator.function().arity(3).required(),\n tools: validator\n .array()\n .items(\n validator.any().custom((value: unknown, helpers: { error: (code: string) => unknown }) => {\n if (Tool.isTool(value)) return value\n return helpers.error('any.invalid')\n })\n )\n .default([]),\n turnInputPipeline: validator.array().items(validator.function()).default([]),\n turnOutputPipeline: validator.array().items(validator.function()).default([]),\n dispatchInputPipeline: validator.array().items(validator.function()).default([]),\n dispatchOutputPipeline: validator.array().items(validator.function()).default([]),\n})\n","import { DateTime } from 'luxon'\nimport { Middleware } from '@nhtio/middleware'\nimport { TurnGate } from './classes/turn_gate'\nimport { DispatchRunner } from './dispatch_runner'\nimport { ToolRegistry } from './classes/tool_registry'\nimport { isInstanceOf, isError } from './utils/guards'\nimport { TypedEventEmitter } from '@nhtio/tiny-typed-emitter'\nimport { passesSchema, validateOrThrow } from './utils/validation'\nimport { turnRunnerConfigSchema } from './contracts/turn_runner_config'\nimport { TurnContext, RawTurnContext } from './contracts/turn_runner_context'\nimport {\n E_INVALID_TURN_RUNNER_CONFIG,\n E_INPUT_PIPELINE_ERROR,\n E_OUTPUT_PIPELINE_ERROR,\n E_PIPELINE_SHORT_CIRCUITED,\n} from './exceptions/runtime'\nimport type { Runner } from '@nhtio/middleware'\nimport type { RawTurnGate } from './classes/turn_gate'\nimport type { ResolvedTurnRunnerConfig, TurnRunnerConfig } from './contracts/turn_runner_config'\nimport type {\n OpenGateFn,\n TurnEvents,\n TurnEvent,\n TurnEventListener,\n TurnPipelineMiddlewareFn,\n TurnObservabilityEvents,\n TurnObservabilityEvent,\n TurnObservabilityEventListener,\n} from './types/turn_runner'\n\nexport type {\n TurnPipelineMiddlewareFn,\n TurnStreamableContent,\n TurnToolCallContent,\n TurnStartEvent,\n TurnEndEvent,\n TurnGateClosedEvent,\n ToolExecutionStartEvent,\n ToolExecutionEndEvent,\n EmitMessageFn,\n EmitThoughtFn,\n EmitToolCallFn,\n EmitToolExecutionStartFn,\n EmitToolExecutionEndFn,\n OpenGateFn,\n TurnEvents,\n TurnEvent,\n TurnEventListener,\n TurnObservabilityEvents,\n TurnObservabilityEvent,\n TurnObservabilityEventListener,\n} from './types/turn_runner'\n\n/**\n * Executes a single agent turn through paired input and output middleware pipelines.\n *\n * @remarks\n * Construction validates `config` eagerly and throws {@link @nhtio/adk!E_INVALID_TURN_RUNNER_CONFIG} if it\n * does not satisfy the schema — fail-fast so misconfiguration surfaces before any turn runs.\n *\n * Each call to {@link TurnRunner.run} threads a {@link @nhtio/adk!TurnContext} through the input pipeline,\n * invokes the model, then threads the result through the output pipeline. Middleware on each side\n * can read and mutate the context for pre- and post-processing (e.g. message normalisation, tool\n * call dispatch, response filtering).\n *\n * **Two event buses:**\n * - Functional bus (`on` / `off` / `once`): `message`, `thought`, `toolCall` — pipeline-affecting\n * events that middleware raises throughout turn execution.\n * - Observability bus (`observe` / `unobserve` / `observeOnce`): `turnStart`, `turnEnd`,\n * `turnGateOpen`, `turnGateClosed`, `error` — instrumentation-only events that monitor execution\n * without participating in it.\n *\n * Streaming content is surfaced via `message` and `thought` events; tool call lifecycle via\n * `toolCall`; non-fatal pipeline errors via the observability `error` event; gate lifecycle via\n * `turnGateOpen` and `turnGateClosed` — all throughout execution.\n *\n * @example\n * ```ts\n * const runner = new TurnRunner({\n * fetchMemoriesCallback: async (ctx) => memoryStore.query(ctx),\n * fetchMessagesCallback: async (ctx) => messageStore.history(ctx),\n * fetchThoughtsCallback: async (ctx) => thoughtStore.history(ctx),\n * fetchToolCallsCallback: async (ctx) => toolCallStore.history(ctx),\n * })\n * // Functional bus — pipeline events\n * runner.on('message', (chunk) => process.stdout.write(chunk.aDelta))\n * // Observability bus — instrumentation\n * runner.observe('error', (err) => console.error(err.toString()))\n * runner.observe('turnStart', ({ turnId }) => console.log('turn started', turnId))\n * runner.observe('turnGateOpen', (gate) => {\n * if (gate.reason === 'tool_approval') {\n * gate.resolve(true) // approve immediately for this example\n * }\n * })\n * await runner.run({\n * turnAbortController: new AbortController(),\n * systemPrompt: 'You are a helpful assistant.',\n * standingInstructions: [],\n * })\n * ```\n */\nexport class TurnRunner {\n /**\n * Returns `true` if `value` is a {@link TurnRunner} instance.\n *\n * @remarks\n * Uses {@link @nhtio/adk!isInstanceOf} for cross-realm safety.\n *\n * @param value - The value to test.\n * @returns `true` when `value` is a {@link TurnRunner} instance.\n */\n public static isTurnRunner(value: unknown): value is TurnRunner {\n return isInstanceOf(value, 'TurnRunner', TurnRunner)\n }\n\n #config: ResolvedTurnRunnerConfig\n #inputRunner: Runner<TurnPipelineMiddlewareFn>\n #outputRunner: Runner<TurnPipelineMiddlewareFn>\n #functionalEmitter: TypedEventEmitter<TurnEvents>\n #observabilityEmitter: TypedEventEmitter<TurnObservabilityEvents>\n\n /**\n * @param config - Construction-time configuration validated against {@link turnRunnerConfigSchema}.\n * @throws {@link @nhtio/adk!E_INVALID_TURN_RUNNER_CONFIG} when `config` does not satisfy the schema.\n */\n constructor(config: TurnRunnerConfig) {\n const isValid = passesSchema(turnRunnerConfigSchema, config)\n if (!isValid) {\n throw new E_INVALID_TURN_RUNNER_CONFIG()\n }\n // Store the resolved config so optional fields (e.g. tools) are always present.\n this.#config = validateOrThrow<ResolvedTurnRunnerConfig>(turnRunnerConfigSchema, config, true)\n const turnInputPipeline = new Middleware<TurnPipelineMiddlewareFn>()\n const turnOutputPipeline = new Middleware<TurnPipelineMiddlewareFn>()\n const wrap =\n (fn: TurnPipelineMiddlewareFn): TurnPipelineMiddlewareFn =>\n (ctx, next) => {\n // Skip downstream user middlewares once an abort has been signalled. The\n // wrapper still calls next() so the pipeline reaches its terminal resolver\n // (keeping the short-circuit detector quiet); the original middleware body\n // does not run, so it has nothing to clean up.\n if (ctx.aborted) return next()\n return fn(ctx, next)\n }\n for (const fn of this.#config.turnInputPipeline) turnInputPipeline.add(wrap(fn))\n for (const fn of this.#config.turnOutputPipeline) turnOutputPipeline.add(wrap(fn))\n this.#inputRunner = turnInputPipeline.runner()\n this.#outputRunner = turnOutputPipeline.runner()\n this.#functionalEmitter = new TypedEventEmitter<TurnEvents>()\n this.#observabilityEmitter = new TypedEventEmitter<TurnObservabilityEvents>()\n }\n\n // ── Functional bus ───────────────────────────────────────────────────────\n\n /**\n * Removes a previously registered functional listener for `event`.\n *\n * @param event - The event to stop listening to.\n * @param listener - The listener function to remove.\n * @returns `this` for chaining.\n */\n off<K>(event: TurnEvent<K>, listener: TurnEventListener<K>): this {\n this.#functionalEmitter.off(event, listener)\n return this\n }\n\n /**\n * Registers a persistent functional listener for `event`.\n *\n * @param event - The event to listen to.\n * @param listener - The function to call on each emission.\n * @returns `this` for chaining.\n */\n on<K>(event: TurnEvent<K>, listener: TurnEventListener<K>): this {\n this.#functionalEmitter.on(event, listener)\n return this\n }\n\n /**\n * Registers a one-time functional listener for `event` that is automatically removed after the\n * first emission.\n *\n * @param event - The event to listen to.\n * @param listener - The function to call on the next emission.\n * @returns `this` for chaining.\n */\n once<K>(event: TurnEvent<K>, listener: TurnEventListener<K>): this {\n this.#functionalEmitter.once(event, listener)\n return this\n }\n\n // ── Observability bus ────────────────────────────────────────────────────\n\n /**\n * Removes a previously registered observability listener for `event`.\n *\n * @param event - The event to stop observing.\n * @param listener - The listener function to remove.\n * @returns `this` for chaining.\n */\n unobserve<K>(\n event: TurnObservabilityEvent<K>,\n listener: TurnObservabilityEventListener<K>\n ): this {\n this.#observabilityEmitter.off(event, listener)\n return this\n }\n\n /**\n * Registers a persistent observability listener for `event`.\n *\n * @remarks\n * Use the observability bus (`observe` / `unobserve` / `observeOnce`) for instrumentation:\n * turn lifecycle, gate lifecycle, and non-fatal errors. Use the functional bus (`on` / `off` /\n * `once`) for pipeline-affecting events: `message`, `thought`, `toolCall`.\n *\n * @param event - The event to observe.\n * @param listener - The function to call on each emission.\n * @returns `this` for chaining.\n */\n observe<K>(event: TurnObservabilityEvent<K>, listener: TurnObservabilityEventListener<K>): this {\n this.#observabilityEmitter.on(event, listener)\n return this\n }\n\n /**\n * Registers a one-time observability listener for `event` that is automatically removed after\n * the first emission.\n *\n * @param event - The event to observe once.\n * @param listener - The function to call on the next emission.\n * @returns `this` for chaining.\n */\n observeOnce<K>(\n event: TurnObservabilityEvent<K>,\n listener: TurnObservabilityEventListener<K>\n ): this {\n this.#observabilityEmitter.once(event, listener)\n return this\n }\n\n // ── Turn execution ───────────────────────────────────────────────────────\n\n /**\n * Executes a single agent turn against the provided raw context.\n *\n * @remarks\n * Returns `Promise<void>` intentionally — all meaningful output surfaces via events, not return\n * values. Register listeners before calling `run`: observability events (`turnStart`, `turnEnd`)\n * bracket execution; functional events (`message`, `thought`, `toolCall`) fire throughout;\n * observability `error` carries non-fatal pipeline failures; `turnGateOpen` and `turnGateClosed`\n * fire when middleware suspends via `ctx.waitFor()`. Awaiting this method only tells you the\n * pipeline has finished, not what it produced.\n *\n * Constructs a validated {@link @nhtio/adk!TurnContext} from `context` (throwing\n * {@link @nhtio/adk!E_INVALID_TURN_CONTEXT} on failure), then runs the input middleware pipeline.\n * Abort signals are silently swallowed.\n *\n * @param context - Raw input validated and wrapped into a {@link @nhtio/adk!TurnContext} before execution.\n * @throws {@link @nhtio/adk!E_INVALID_TURN_CONTEXT} when `context` does not satisfy the schema.\n */\n async run(context: RawTurnContext): Promise<void> {\n const abortController = context.turnAbortController ?? new AbortController()\n\n // Forward declaration so openGate can reference turnContext.id before it is assigned.\n let turnContextId: string\n\n const openGate: OpenGateFn = <T>(raw: Omit<RawTurnGate, 'turnId' | 'abortSignal'>) => {\n const gate = new TurnGate<T>({\n ...raw,\n turnId: turnContextId,\n abortSignal: abortController.signal,\n })\n this.#observabilityEmitter.emit('turnGateOpen', gate)\n const promise = gate._promise()\n promise.then(\n () => {\n this.#observabilityEmitter.emit('turnGateClosed', {\n gateId: gate.id,\n turnId: gate.turnId,\n result: 'resolved',\n settledAt: DateTime.now(),\n })\n },\n (err: unknown) => {\n let result: 'rejected' | 'aborted' | 'timeout' = 'rejected'\n if (isInstanceOf(err, 'E_TURN_GATE_ABORTED')) result = 'aborted'\n else if (isInstanceOf(err, 'E_TURN_GATE_TIMEOUT')) result = 'timeout'\n this.#observabilityEmitter.emit('turnGateClosed', {\n gateId: gate.id,\n turnId: gate.turnId,\n result,\n settledAt: DateTime.now(),\n })\n }\n )\n return promise\n }\n\n const tools = new ToolRegistry(this.#config.tools)\n\n const turnContext = new TurnContext(\n { ...context, turnAbortController: abortController },\n {\n fetchMemories: this.#config.fetchMemoriesCallback,\n fetchMessages: this.#config.fetchMessagesCallback,\n fetchThoughts: this.#config.fetchThoughtsCallback,\n fetchToolCalls: this.#config.fetchToolCallsCallback,\n fetchTools: this.#config.fetchToolsCallback,\n refreshStandingInstructions: this.#config.refreshStandingInstructionsCallback,\n storeStandingInstruction: this.#config.storeStandingInstructionCallback,\n mutateStandingInstruction: this.#config.mutateStandingInstructionCallback,\n deleteStandingInstruction: this.#config.deleteStandingInstructionCallback,\n storeMemory: this.#config.storeMemoryCallback,\n mutateMemory: this.#config.mutateMemoryCallback,\n deleteMemory: this.#config.deleteMemoryCallback,\n fetchRetrievables: this.#config.fetchRetrievablesCallback,\n storeRetrievable: this.#config.storeRetrievableCallback,\n mutateRetrievable: this.#config.mutateRetrievableCallback,\n deleteRetrievable: this.#config.deleteRetrievableCallback,\n storeMessage: this.#config.storeMessageCallback,\n mutateMessage: this.#config.mutateMessageCallback,\n deleteMessage: this.#config.deleteMessageCallback,\n storeThought: this.#config.storeThoughtCallback,\n mutateThought: this.#config.mutateThoughtCallback,\n deleteThought: this.#config.deleteThoughtCallback,\n storeToolCall: this.#config.storeToolCallCallback,\n mutateToolCall: this.#config.mutateToolCallCallback,\n deleteToolCall: this.#config.deleteToolCallCallback,\n storeMediaBytes: this.#config.storeMediaBytesCallback,\n storeRetrievableBytes: this.#config.storeRetrievableBytesCallback,\n emitMessage: (content) => this.#functionalEmitter.emit('message', content),\n emitThought: (content) => this.#functionalEmitter.emit('thought', content),\n emitToolCall: (content) => this.#functionalEmitter.emit('toolCall', content),\n emitToolExecutionStart: (event) =>\n this.#observabilityEmitter.emit('toolExecutionStart', event),\n emitToolExecutionEnd: (event) => this.#observabilityEmitter.emit('toolExecutionEnd', event),\n openGate,\n tools,\n }\n )\n\n turnContextId = turnContext.id\n\n const startedAt = DateTime.now()\n this.#observabilityEmitter.emit('turnStart', { turnId: turnContext.id, startedAt })\n\n const emitTurnEnd = () => {\n const endedAt = DateTime.now()\n this.#observabilityEmitter.emit('turnEnd', {\n turnId: turnContext.id,\n startedAt,\n endedAt,\n durationMs: endedAt.diff(startedAt).milliseconds,\n })\n }\n\n // 1. Input pipeline\n let inputFailed = false\n let inputReached = false\n await this.#inputRunner\n .errorHandler(async (error) => {\n if (!isError(error) || !isInstanceOf(error, 'AbortError')) {\n inputFailed = true\n const err = new E_INPUT_PIPELINE_ERROR({\n cause: isError(error) ? error : undefined,\n })\n this.#observabilityEmitter.emit('error', err)\n }\n })\n .finalHandler(async () => {\n inputReached = true\n })\n .run((fn, next) => Promise.resolve(fn(turnContext, next)))\n\n if (!inputReached && !inputFailed && !turnContext.aborted) {\n inputFailed = true\n const err = new E_PIPELINE_SHORT_CIRCUITED(['turn-input'])\n this.#observabilityEmitter.emit('error', err)\n }\n\n if (inputFailed || turnContext.aborted) {\n emitTurnEnd()\n return\n }\n\n // 2. LLM execution dispatch\n let dispatchFailed = false\n try {\n await DispatchRunner.dispatch({\n source: turnContext,\n executor: this.#config.executorCallback,\n turnInputPipeline: this.#config.dispatchInputPipeline,\n turnOutputPipeline: this.#config.dispatchOutputPipeline,\n observers: {\n dispatchStart: [\n (e) => {\n this.#observabilityEmitter.emit('dispatchStart', e)\n },\n ],\n dispatchEnd: [\n (e) => {\n this.#observabilityEmitter.emit('dispatchEnd', e)\n },\n ],\n iterationStart: [\n (e) => {\n this.#observabilityEmitter.emit('iterationStart', e)\n },\n ],\n iterationEnd: [\n (e) => {\n this.#observabilityEmitter.emit('iterationEnd', e)\n },\n ],\n log: [\n (e) => {\n this.#observabilityEmitter.emit('log', e)\n },\n ],\n },\n })\n } catch (err) {\n dispatchFailed = true\n const wrapped = isInstanceOf(err, 'BaseException') ? (err as InstanceType<typeof Error>) : err\n this.#observabilityEmitter.emit('error', wrapped as any)\n }\n\n if (dispatchFailed || turnContext.aborted) {\n emitTurnEnd()\n return\n }\n\n // 3. Output pipeline\n let outputFailed = false\n let outputReached = false\n await this.#outputRunner\n .errorHandler(async (error) => {\n if (!isError(error) || !isInstanceOf(error, 'AbortError')) {\n outputFailed = true\n const err = new E_OUTPUT_PIPELINE_ERROR({\n cause: isError(error) ? error : undefined,\n })\n this.#observabilityEmitter.emit('error', err)\n }\n })\n .finalHandler(async () => {\n outputReached = true\n })\n .run((fn, next) => Promise.resolve(fn(turnContext, next)))\n\n if (!outputReached && !outputFailed && !turnContext.aborted) {\n const err = new E_PIPELINE_SHORT_CIRCUITED(['turn-output'])\n this.#observabilityEmitter.emit('error', err)\n }\n\n emitTurnEnd()\n }\n}\n"],"mappings":"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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { a as validateOrThrow, i as passesSchema } from "./exceptions-NrzIHw_R.mjs";
|
|
2
2
|
import { c as isObject, o as isError, s as isInstanceOf, t as ToolRegistry } from "./tool_registry-DqLOyGyG.mjs";
|
|
3
3
|
import { O as E_TURN_GATE_ABORTED, T as E_PIPELINE_SHORT_CIRCUITED, _ as E_INVALID_TURN_GATE_RESOLUTION, f as E_INVALID_INITIAL_TURN_GATE_VALUE, k as E_TURN_GATE_TIMEOUT, n as E_INPUT_PIPELINE_ERROR, v as E_INVALID_TURN_RUNNER_CONFIG, w as E_OUTPUT_PIPELINE_ERROR } from "./runtime-CrEPIFgr.mjs";
|
|
4
|
-
import { t as Tool } from "./tool-
|
|
5
|
-
import { r as TurnContext, t as DispatchRunner } from "./dispatch_runner-
|
|
4
|
+
import { t as Tool } from "./tool-q4LskG7K.mjs";
|
|
5
|
+
import { r as TurnContext, t as DispatchRunner } from "./dispatch_runner-OimGCkk7.mjs";
|
|
6
6
|
import { validator } from "@nhtio/validation";
|
|
7
7
|
import { DateTime } from "luxon";
|
|
8
8
|
import { Middleware } from "@nhtio/middleware";
|
|
@@ -253,6 +253,8 @@ var turnRunnerConfigSchema = validator.object({
|
|
|
253
253
|
storeToolCallCallback: validator.function().arity(2).required(),
|
|
254
254
|
mutateToolCallCallback: validator.function().arity(2).required(),
|
|
255
255
|
deleteToolCallCallback: validator.function().arity(2).required(),
|
|
256
|
+
storeMediaBytesCallback: validator.function().arity(3).required(),
|
|
257
|
+
storeRetrievableBytesCallback: validator.function().arity(3).required(),
|
|
256
258
|
tools: validator.array().items(validator.any().custom((value, helpers) => {
|
|
257
259
|
if (Tool.isTool(value)) return value;
|
|
258
260
|
return helpers.error("any.invalid");
|
|
@@ -502,6 +504,8 @@ var TurnRunner = class TurnRunner {
|
|
|
502
504
|
storeToolCall: this.#config.storeToolCallCallback,
|
|
503
505
|
mutateToolCall: this.#config.mutateToolCallCallback,
|
|
504
506
|
deleteToolCall: this.#config.deleteToolCallCallback,
|
|
507
|
+
storeMediaBytes: this.#config.storeMediaBytesCallback,
|
|
508
|
+
storeRetrievableBytes: this.#config.storeRetrievableBytesCallback,
|
|
505
509
|
emitMessage: (content) => this.#functionalEmitter.emit("message", content),
|
|
506
510
|
emitThought: (content) => this.#functionalEmitter.emit("thought", content),
|
|
507
511
|
emitToolCall: (content) => this.#functionalEmitter.emit("toolCall", content),
|
|
@@ -600,4 +604,4 @@ var TurnRunner = class TurnRunner {
|
|
|
600
604
|
//#endregion
|
|
601
605
|
export { TurnGate as n, TurnRunner as t };
|
|
602
606
|
|
|
603
|
-
//# sourceMappingURL=turn_runner-
|
|
607
|
+
//# sourceMappingURL=turn_runner-DRBLN2Y_.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"turn_runner-DRBLN2Y_.mjs","names":["#id","#turnId","#reason","#payload","#createdAt","#settled","#schema","#controller","#promise","#resolve","#reject","#config","#inputRunner","#outputRunner","#functionalEmitter","#observabilityEmitter"],"sources":["../src/lib/classes/turn_gate.ts","../src/lib/contracts/turn_runner_config.ts","../src/lib/turn_runner.ts"],"sourcesContent":["import { DateTime } from 'luxon'\nimport { validator } from '@nhtio/validation'\nimport { validateOrThrow } from '../utils/validation'\nimport { isInstanceOf, isError, isObject } from '../utils/guards'\nimport {\n E_TURN_GATE_ABORTED,\n E_TURN_GATE_TIMEOUT,\n E_INVALID_TURN_GATE_RESOLUTION,\n E_INVALID_INITIAL_TURN_GATE_VALUE,\n} from '../exceptions/runtime'\nimport type { Schema } from '@nhtio/validation'\n\n/**\n * Plain input object supplied to {@link TurnGate} at construction time.\n *\n * @remarks\n * `turnId` and `abortSignal` are injected by the runner — callers constructing a gate via\n * `ctx.waitFor()` never supply them directly.\n *\n * `abortSignal` is `AbortSignal` (not `AbortController`) because the gate reacts to turn-level\n * cancellation but cannot trigger it. The gate owns its own internal `AbortController` for\n * `gate.abort()`.\n */\nexport interface RawTurnGate {\n /** Stable unique identifier for this gate. */\n id: string\n /** The ID of the turn that opened this gate. */\n turnId: string\n /** Human-readable label describing why this gate was opened (e.g. `'tool_approval'`). */\n reason: string\n /** Arbitrary data supplied to the gate opener; passed through to `turnGateOpen` listeners. */\n payload: unknown\n /** Optional validator schema for the resolution value. When present, `resolve()` validates before settling. */\n schema?: Schema\n /** Optional timeout in milliseconds. When elapsed the gate self-rejects with {@link @nhtio/adk!E_TURN_GATE_TIMEOUT}. */\n timeout?: number\n /** The turn's abort signal. When fired the gate self-rejects with {@link @nhtio/adk!E_TURN_GATE_ABORTED}. */\n abortSignal?: AbortSignal\n /** When this gate was created. */\n createdAt: string | number | Date | DateTime\n}\n\n/**\n * Fully-resolved {@link RawTurnGate} after schema validation.\n *\n * @internal\n */\ninterface ResolvedTurnGate {\n id: string\n turnId: string\n reason: string\n payload: unknown\n schema?: Schema\n timeout?: number\n abortSignal?: AbortSignal\n createdAt: DateTime\n}\n\n/**\n * Validator schema used to validate a {@link RawTurnGate} before constructing a {@link TurnGate}.\n *\n * @remarks\n * - `schema` and `abortSignal` are validated as opaque passthrough values.\n * - `timeout` must be a positive integer when provided.\n */\nconst rawTurnGateSchema = validator.object<RawTurnGate>({\n id: validator.string().required(),\n turnId: validator.string().required(),\n reason: validator.string().required(),\n payload: validator.any().required(),\n schema: validator\n .any()\n .custom((value, helpers) => {\n if (value === undefined || value === null) return undefined\n if (typeof (value as any).validate === 'function') return value\n return helpers.error('any.invalid')\n })\n .optional(),\n timeout: validator.number().integer().min(1).optional(),\n abortSignal: validator\n .any()\n .custom((value, helpers) => {\n if (value === undefined || value === null) return undefined\n // eslint-disable-next-line adk/use-is-instance-of -- native built-in; AbortSignal cross-realm is handled by the duck-type fallback below\n if (typeof AbortSignal !== 'undefined' && value instanceof AbortSignal) return value\n if (\n isObject(value) &&\n typeof (value as any).aborted === 'boolean' &&\n typeof (value as any).addEventListener === 'function'\n ) {\n return value\n }\n return helpers.error('any.invalid')\n })\n .optional(),\n createdAt: validator.datetime().required(),\n})\n\n/**\n * A cooperative suspension gate that blocks a turn's middleware pipeline until resolved, rejected,\n * aborted, or timed out.\n *\n * @typeParam T - The expected type of the resolution value.\n *\n * @remarks\n * Created exclusively via `ctx.waitFor()` — middleware never constructs a gate directly.\n * The gate emits `turnGateOpen` on the runner's observability bus at creation time and\n * `turnGateClosed` when it settles.\n *\n * Resolution is validated against an optional schema before the internal promise is settled.\n * A validation failure throws {@link @nhtio/adk!E_INVALID_TURN_GATE_RESOLUTION} **synchronously in the\n * caller's context** — the promise is NOT settled and the gate remains open.\n */\nexport class TurnGate<T = unknown> {\n /**\n * Validator schema that accepts a {@link RawTurnGate} object.\n *\n * @remarks\n * Reusable fragment for any schema that needs to validate or nest a gate entry.\n */\n public static schema = rawTurnGateSchema\n\n /**\n * Returns `true` if `value` is a {@link TurnGate} instance.\n *\n * @remarks\n * Uses {@link @nhtio/adk!isInstanceOf} for cross-realm safety.\n *\n * @param value - The value to test.\n * @returns `true` when `value` is a {@link TurnGate} instance.\n */\n public static isTurnGate(value: unknown): value is TurnGate {\n return isInstanceOf(value, 'TurnGate', TurnGate)\n }\n\n declare readonly id: string\n declare readonly turnId: string\n declare readonly reason: string\n declare readonly payload: unknown\n declare readonly createdAt: DateTime\n declare readonly isSettled: boolean\n\n #id: string\n #turnId: string\n #reason: string\n #payload: unknown\n #createdAt: DateTime\n #settled: boolean\n #schema: Schema | undefined\n #controller: AbortController\n #resolve!: (value: T) => void\n #reject!: (reason: unknown) => void\n #promise: Promise<T>\n\n /**\n * @param raw - The raw gate input validated against `rawTurnGateSchema`.\n * @throws {@link @nhtio/adk!E_INVALID_INITIAL_TURN_GATE_VALUE} when `raw` does not satisfy the schema.\n */\n constructor(raw: RawTurnGate) {\n let resolved: ResolvedTurnGate\n try {\n resolved = validateOrThrow<ResolvedTurnGate>(rawTurnGateSchema, raw, true)\n } catch (err) {\n throw new E_INVALID_INITIAL_TURN_GATE_VALUE({ cause: isError(err) ? err : undefined })\n }\n\n this.#id = resolved.id\n this.#turnId = resolved.turnId\n this.#reason = resolved.reason\n this.#payload = resolved.payload\n this.#createdAt = resolved.createdAt\n this.#settled = false\n this.#schema = resolved.schema\n this.#controller = new AbortController()\n\n this.#promise = new Promise<T>((resolve, reject) => {\n this.#resolve = resolve\n this.#reject = reject\n })\n\n // Wire the internal abort controller\n const onAbort = () => {\n if (!this.#settled) {\n this.#settled = true\n this.#reject(new E_TURN_GATE_ABORTED())\n }\n }\n\n this.#controller.signal.addEventListener('abort', onAbort, { once: true })\n\n // Wire the external turn abort signal\n if (resolved.abortSignal) {\n if (resolved.abortSignal.aborted) {\n // Already aborted — reject immediately after construction\n queueMicrotask(() => onAbort())\n } else {\n resolved.abortSignal.addEventListener('abort', onAbort, { once: true })\n // Clean up the external listener once the gate settles via another path\n this.#promise.then(\n () => resolved.abortSignal!.removeEventListener('abort', onAbort),\n () => resolved.abortSignal!.removeEventListener('abort', onAbort)\n )\n }\n }\n\n // Wire the timeout\n if (resolved.timeout !== undefined) {\n const timer = setTimeout(() => {\n if (!this.#settled) {\n this.#settled = true\n this.#reject(new E_TURN_GATE_TIMEOUT())\n }\n }, resolved.timeout)\n\n this.#promise.then(\n () => clearTimeout(timer),\n () => clearTimeout(timer)\n )\n }\n\n Object.defineProperties(this, {\n id: {\n get: () => this.#id,\n enumerable: true,\n configurable: false,\n },\n turnId: {\n get: () => this.#turnId,\n enumerable: true,\n configurable: false,\n },\n reason: {\n get: () => this.#reason,\n enumerable: true,\n configurable: false,\n },\n payload: {\n get: () => this.#payload,\n enumerable: true,\n configurable: false,\n },\n createdAt: {\n get: () => this.#createdAt,\n enumerable: true,\n configurable: false,\n },\n isSettled: {\n get: () => this.#settled,\n enumerable: true,\n configurable: false,\n },\n })\n }\n\n /**\n * Resolves the gate with `value`, unblocking the awaiting middleware.\n *\n * @remarks\n * If a schema was provided at construction, `value` is validated synchronously before the\n * promise is settled. A validation failure throws {@link @nhtio/adk!E_INVALID_TURN_GATE_RESOLUTION}\n * in the caller's context — the promise is NOT settled and the gate remains open.\n *\n * No-ops if the gate is already settled.\n *\n * @param value - The resolution value. Must satisfy the gate's schema when one was provided.\n * @throws {@link @nhtio/adk!E_INVALID_TURN_GATE_RESOLUTION} when `value` fails schema validation.\n */\n resolve(value: unknown): void {\n if (this.#settled) return\n if (this.#schema !== undefined) {\n try {\n value = validateOrThrow(this.#schema, value, true)\n } catch (err) {\n throw new E_INVALID_TURN_GATE_RESOLUTION({\n cause: isError(err) ? err : undefined,\n })\n }\n }\n this.#settled = true\n this.#resolve(value as T)\n }\n\n /**\n * Rejects the gate with `error`, unblocking the awaiting middleware with a rejection.\n *\n * @remarks\n * No-ops if the gate is already settled.\n *\n * @param error - The rejection reason.\n */\n reject(error: Error): void {\n if (this.#settled) return\n this.#settled = true\n this.#reject(error)\n }\n\n /**\n * Aborts the gate by firing the internal `AbortController`, which rejects the promise with\n * {@link @nhtio/adk!E_TURN_GATE_ABORTED}.\n *\n * @remarks\n * No-ops if the gate is already settled. Distinct from the turn-level abort signal — this\n * allows callers to cancel a specific gate without aborting the whole turn.\n */\n abort(): void {\n if (this.#settled) return\n this.#controller.abort()\n }\n\n /**\n * Returns the internal promise. Called by `ctx.waitFor()` to block the middleware pipeline.\n *\n * @internal\n */\n _promise(): Promise<T> {\n return this.#promise\n }\n}\n","import { Tool } from '../classes/tool'\nimport { validator } from '@nhtio/validation'\nimport type { TurnPipelineMiddlewareFn } from '../types/turn_runner'\nimport type { DispatchPipelineMiddlewareFn, DispatchExecutorFn } from '../types/dispatch_runner'\nimport type {\n MemoryRetrievalFn,\n MessageRetrievalFn,\n ThoughtRetrievalFn,\n ToolCallRetrievalFn,\n ToolsRetrievalFn,\n StandingInstructionsRefreshFn,\n StandingInstructionStoreFn,\n StandingInstructionMutateFn,\n StandingInstructionDeleteFn,\n MemoryStoreFn,\n MemoryMutateFn,\n MemoryDeleteFn,\n RetrievableRetrievalFn,\n RetrievableStoreFn,\n RetrievableMutateFn,\n RetrievableDeleteFn,\n MessageStoreFn,\n MessageMutateFn,\n MessageDeleteFn,\n ThoughtStoreFn,\n ThoughtMutateFn,\n ThoughtDeleteFn,\n ToolCallStoreFn,\n ToolCallMutateFn,\n ToolCallDeleteFn,\n MediaBytesStoreFn,\n RetrievableBytesStoreFn,\n} from './turn_runner_context'\n\n/**\n * Configuration supplied to {@link @nhtio/adk!TurnRunner} at construction time.\n *\n * @remarks\n * Validated against `turnRunnerConfigSchema` at construction — a misconfigured runner throws\n * immediately rather than failing on the first turn.\n *\n * All fetch and mutation callbacks are required: they are injected into each {@link @nhtio/adk!TurnContext}\n * so middleware can call fetch, refresh, and persistence methods directly on the context without\n * coupling to the runner.\n *\n * `tools` is optional at the caller level and defaults to `[]` after schema resolution — a runner\n * with no baseline tools is valid.\n */\nexport interface TurnRunnerConfig {\n /** Performs the LLM API/SDK call for each iteration of the dispatch loop; receives the active {@link @nhtio/adk!DispatchContext} and an {@link @nhtio/adk!DispatchExecutorHelpers} object for managing per-id stream state. */\n executorCallback: DispatchExecutorFn\n /** Called once per turn to supply memories; receives the active {@link @nhtio/adk!TurnContext}. */\n fetchMemoriesCallback: MemoryRetrievalFn\n /** Called once per turn to supply conversation history; receives the active {@link @nhtio/adk!TurnContext}. */\n fetchMessagesCallback: MessageRetrievalFn\n /** Called once per turn to supply thought traces; receives the active {@link @nhtio/adk!TurnContext}. */\n fetchThoughtsCallback: ThoughtRetrievalFn\n /** Called once per turn to supply tool call records; receives the active {@link @nhtio/adk!TurnContext}. */\n fetchToolCallsCallback: ToolCallRetrievalFn\n /** Called to supply available tools; receives the active {@link @nhtio/adk!TurnContext}. */\n fetchToolsCallback: ToolsRetrievalFn\n /** Called to refresh and return standing instructions; receives the active {@link @nhtio/adk!TurnContext}. */\n refreshStandingInstructionsCallback: StandingInstructionsRefreshFn\n /** Persists a new standing instruction. */\n storeStandingInstructionCallback: StandingInstructionStoreFn\n /** Updates an existing standing instruction in the persistence layer. */\n mutateStandingInstructionCallback: StandingInstructionMutateFn\n /** Removes a standing instruction from the persistence layer. */\n deleteStandingInstructionCallback: StandingInstructionDeleteFn\n /** Persists a new memory. */\n storeMemoryCallback: MemoryStoreFn\n /** Updates an existing memory in the persistence layer. */\n mutateMemoryCallback: MemoryMutateFn\n /** Removes a memory from the persistence layer by ID. */\n deleteMemoryCallback: MemoryDeleteFn\n /** Called once per turn to supply retrievable (RAG) records; receives the active {@link @nhtio/adk!TurnContext}. */\n fetchRetrievablesCallback: RetrievableRetrievalFn\n /** Persists a new retrievable record. */\n storeRetrievableCallback: RetrievableStoreFn\n /** Updates an existing retrievable record in the persistence layer. */\n mutateRetrievableCallback: RetrievableMutateFn\n /** Removes a retrievable record from the persistence layer by ID. */\n deleteRetrievableCallback: RetrievableDeleteFn\n /** Persists a new message. */\n storeMessageCallback: MessageStoreFn\n /** Updates an existing message in the persistence layer. */\n mutateMessageCallback: MessageMutateFn\n /** Removes a message from the persistence layer by ID. */\n deleteMessageCallback: MessageDeleteFn\n /** Persists a new thought. */\n storeThoughtCallback: ThoughtStoreFn\n /** Updates an existing thought in the persistence layer. */\n mutateThoughtCallback: ThoughtMutateFn\n /** Removes a thought from the persistence layer by ID. */\n deleteThoughtCallback: ThoughtDeleteFn\n /** Persists a new tool call. */\n storeToolCallCallback: ToolCallStoreFn\n /** Updates an existing tool call in the persistence layer. */\n mutateToolCallCallback: ToolCallMutateFn\n /** Removes a tool call from the persistence layer by ID. */\n deleteToolCallCallback: ToolCallDeleteFn\n /** Persists tool-generated media bytes into consumer storage; returns a `MediaReader`. */\n storeMediaBytesCallback: MediaBytesStoreFn\n /** Persists extracted retrievable text bytes into consumer storage; returns a `SpoolReader`. */\n storeRetrievableBytesCallback: RetrievableBytesStoreFn\n /** Baseline tools available on every turn. Middleware may trim or extend this per-turn via `ctx.tools`. Defaults to `[]`. */\n tools?: Tool[]\n /** Turn-level input middleware, executed in order against the {@link @nhtio/adk!TurnContext} before the LLM dispatch. Defaults to `[]`. */\n turnInputPipeline?: TurnPipelineMiddlewareFn[]\n /** Turn-level output middleware, executed in order against the {@link @nhtio/adk!TurnContext} after the LLM dispatch resolves successfully. Defaults to `[]`. */\n turnOutputPipeline?: TurnPipelineMiddlewareFn[]\n /** LLM-iteration input middleware, executed in order against the {@link @nhtio/adk!DispatchContext} before the executor on each iteration. Defaults to `[]`. */\n dispatchInputPipeline?: DispatchPipelineMiddlewareFn[]\n /** LLM-iteration output middleware, executed in order against the {@link @nhtio/adk!DispatchContext} after the executor on each iteration. Defaults to `[]`. */\n dispatchOutputPipeline?: DispatchPipelineMiddlewareFn[]\n}\n\n/**\n * Fully-resolved {@link TurnRunnerConfig} after schema validation.\n *\n * @remarks\n * All optional fields are guaranteed present (e.g. `tools` defaults to `[]`). The runner stores\n * this type internally so field access never needs to guard for undefined.\n */\nexport type ResolvedTurnRunnerConfig = Required<TurnRunnerConfig>\n\n/**\n * Validator schema used to validate a {@link TurnRunnerConfig} at {@link @nhtio/adk!TurnRunner} construction time.\n *\n * @remarks\n * Validates that all callbacks are functions of the correct arity, and that `tools` — when\n * provided — is an array of valid {@link @nhtio/adk!Tool} instances. Defaults `tools` to `[]`.\n *\n * Throws {@link @nhtio/adk!E_INVALID_TURN_RUNNER_CONFIG} (via the {@link @nhtio/adk!TurnRunner} constructor) when\n * validation fails.\n */\nexport const turnRunnerConfigSchema = validator.object<TurnRunnerConfig>({\n executorCallback: validator.function().required(),\n fetchMemoriesCallback: validator.function().arity(1).required(),\n fetchMessagesCallback: validator.function().arity(1).required(),\n fetchThoughtsCallback: validator.function().arity(1).required(),\n fetchToolCallsCallback: validator.function().arity(1).required(),\n fetchToolsCallback: validator.function().arity(1).required(),\n refreshStandingInstructionsCallback: validator.function().arity(1).required(),\n storeStandingInstructionCallback: validator.function().arity(2).required(),\n mutateStandingInstructionCallback: validator.function().arity(2).required(),\n deleteStandingInstructionCallback: validator.function().arity(2).required(),\n storeMemoryCallback: validator.function().arity(2).required(),\n mutateMemoryCallback: validator.function().arity(2).required(),\n deleteMemoryCallback: validator.function().arity(2).required(),\n fetchRetrievablesCallback: validator.function().arity(1).required(),\n storeRetrievableCallback: validator.function().arity(2).required(),\n mutateRetrievableCallback: validator.function().arity(2).required(),\n deleteRetrievableCallback: validator.function().arity(2).required(),\n storeMessageCallback: validator.function().arity(2).required(),\n mutateMessageCallback: validator.function().arity(2).required(),\n deleteMessageCallback: validator.function().arity(2).required(),\n storeThoughtCallback: validator.function().arity(2).required(),\n mutateThoughtCallback: validator.function().arity(2).required(),\n deleteThoughtCallback: validator.function().arity(2).required(),\n storeToolCallCallback: validator.function().arity(2).required(),\n mutateToolCallCallback: validator.function().arity(2).required(),\n deleteToolCallCallback: validator.function().arity(2).required(),\n storeMediaBytesCallback: validator.function().arity(3).required(),\n storeRetrievableBytesCallback: validator.function().arity(3).required(),\n tools: validator\n .array()\n .items(\n validator.any().custom((value: unknown, helpers: { error: (code: string) => unknown }) => {\n if (Tool.isTool(value)) return value\n return helpers.error('any.invalid')\n })\n )\n .default([]),\n turnInputPipeline: validator.array().items(validator.function()).default([]),\n turnOutputPipeline: validator.array().items(validator.function()).default([]),\n dispatchInputPipeline: validator.array().items(validator.function()).default([]),\n dispatchOutputPipeline: validator.array().items(validator.function()).default([]),\n})\n","import { DateTime } from 'luxon'\nimport { Middleware } from '@nhtio/middleware'\nimport { TurnGate } from './classes/turn_gate'\nimport { DispatchRunner } from './dispatch_runner'\nimport { ToolRegistry } from './classes/tool_registry'\nimport { isInstanceOf, isError } from './utils/guards'\nimport { TypedEventEmitter } from '@nhtio/tiny-typed-emitter'\nimport { passesSchema, validateOrThrow } from './utils/validation'\nimport { turnRunnerConfigSchema } from './contracts/turn_runner_config'\nimport { TurnContext, RawTurnContext } from './contracts/turn_runner_context'\nimport {\n E_INVALID_TURN_RUNNER_CONFIG,\n E_INPUT_PIPELINE_ERROR,\n E_OUTPUT_PIPELINE_ERROR,\n E_PIPELINE_SHORT_CIRCUITED,\n} from './exceptions/runtime'\nimport type { Runner } from '@nhtio/middleware'\nimport type { RawTurnGate } from './classes/turn_gate'\nimport type { ResolvedTurnRunnerConfig, TurnRunnerConfig } from './contracts/turn_runner_config'\nimport type {\n OpenGateFn,\n TurnEvents,\n TurnEvent,\n TurnEventListener,\n TurnPipelineMiddlewareFn,\n TurnObservabilityEvents,\n TurnObservabilityEvent,\n TurnObservabilityEventListener,\n} from './types/turn_runner'\n\nexport type {\n TurnPipelineMiddlewareFn,\n TurnStreamableContent,\n TurnToolCallContent,\n TurnStartEvent,\n TurnEndEvent,\n TurnGateClosedEvent,\n ToolExecutionStartEvent,\n ToolExecutionEndEvent,\n EmitMessageFn,\n EmitThoughtFn,\n EmitToolCallFn,\n EmitToolExecutionStartFn,\n EmitToolExecutionEndFn,\n OpenGateFn,\n TurnEvents,\n TurnEvent,\n TurnEventListener,\n TurnObservabilityEvents,\n TurnObservabilityEvent,\n TurnObservabilityEventListener,\n} from './types/turn_runner'\n\n/**\n * Executes a single agent turn through paired input and output middleware pipelines.\n *\n * @remarks\n * Construction validates `config` eagerly and throws {@link @nhtio/adk!E_INVALID_TURN_RUNNER_CONFIG} if it\n * does not satisfy the schema — fail-fast so misconfiguration surfaces before any turn runs.\n *\n * Each call to {@link TurnRunner.run} threads a {@link @nhtio/adk!TurnContext} through the input pipeline,\n * invokes the model, then threads the result through the output pipeline. Middleware on each side\n * can read and mutate the context for pre- and post-processing (e.g. message normalisation, tool\n * call dispatch, response filtering).\n *\n * **Two event buses:**\n * - Functional bus (`on` / `off` / `once`): `message`, `thought`, `toolCall` — pipeline-affecting\n * events that middleware raises throughout turn execution.\n * - Observability bus (`observe` / `unobserve` / `observeOnce`): `turnStart`, `turnEnd`,\n * `turnGateOpen`, `turnGateClosed`, `error` — instrumentation-only events that monitor execution\n * without participating in it.\n *\n * Streaming content is surfaced via `message` and `thought` events; tool call lifecycle via\n * `toolCall`; non-fatal pipeline errors via the observability `error` event; gate lifecycle via\n * `turnGateOpen` and `turnGateClosed` — all throughout execution.\n *\n * @example\n * ```ts\n * const runner = new TurnRunner({\n * fetchMemoriesCallback: async (ctx) => memoryStore.query(ctx),\n * fetchMessagesCallback: async (ctx) => messageStore.history(ctx),\n * fetchThoughtsCallback: async (ctx) => thoughtStore.history(ctx),\n * fetchToolCallsCallback: async (ctx) => toolCallStore.history(ctx),\n * })\n * // Functional bus — pipeline events\n * runner.on('message', (chunk) => process.stdout.write(chunk.aDelta))\n * // Observability bus — instrumentation\n * runner.observe('error', (err) => console.error(err.toString()))\n * runner.observe('turnStart', ({ turnId }) => console.log('turn started', turnId))\n * runner.observe('turnGateOpen', (gate) => {\n * if (gate.reason === 'tool_approval') {\n * gate.resolve(true) // approve immediately for this example\n * }\n * })\n * await runner.run({\n * turnAbortController: new AbortController(),\n * systemPrompt: 'You are a helpful assistant.',\n * standingInstructions: [],\n * })\n * ```\n */\nexport class TurnRunner {\n /**\n * Returns `true` if `value` is a {@link TurnRunner} instance.\n *\n * @remarks\n * Uses {@link @nhtio/adk!isInstanceOf} for cross-realm safety.\n *\n * @param value - The value to test.\n * @returns `true` when `value` is a {@link TurnRunner} instance.\n */\n public static isTurnRunner(value: unknown): value is TurnRunner {\n return isInstanceOf(value, 'TurnRunner', TurnRunner)\n }\n\n #config: ResolvedTurnRunnerConfig\n #inputRunner: Runner<TurnPipelineMiddlewareFn>\n #outputRunner: Runner<TurnPipelineMiddlewareFn>\n #functionalEmitter: TypedEventEmitter<TurnEvents>\n #observabilityEmitter: TypedEventEmitter<TurnObservabilityEvents>\n\n /**\n * @param config - Construction-time configuration validated against {@link turnRunnerConfigSchema}.\n * @throws {@link @nhtio/adk!E_INVALID_TURN_RUNNER_CONFIG} when `config` does not satisfy the schema.\n */\n constructor(config: TurnRunnerConfig) {\n const isValid = passesSchema(turnRunnerConfigSchema, config)\n if (!isValid) {\n throw new E_INVALID_TURN_RUNNER_CONFIG()\n }\n // Store the resolved config so optional fields (e.g. tools) are always present.\n this.#config = validateOrThrow<ResolvedTurnRunnerConfig>(turnRunnerConfigSchema, config, true)\n const turnInputPipeline = new Middleware<TurnPipelineMiddlewareFn>()\n const turnOutputPipeline = new Middleware<TurnPipelineMiddlewareFn>()\n const wrap =\n (fn: TurnPipelineMiddlewareFn): TurnPipelineMiddlewareFn =>\n (ctx, next) => {\n // Skip downstream user middlewares once an abort has been signalled. The\n // wrapper still calls next() so the pipeline reaches its terminal resolver\n // (keeping the short-circuit detector quiet); the original middleware body\n // does not run, so it has nothing to clean up.\n if (ctx.aborted) return next()\n return fn(ctx, next)\n }\n for (const fn of this.#config.turnInputPipeline) turnInputPipeline.add(wrap(fn))\n for (const fn of this.#config.turnOutputPipeline) turnOutputPipeline.add(wrap(fn))\n this.#inputRunner = turnInputPipeline.runner()\n this.#outputRunner = turnOutputPipeline.runner()\n this.#functionalEmitter = new TypedEventEmitter<TurnEvents>()\n this.#observabilityEmitter = new TypedEventEmitter<TurnObservabilityEvents>()\n }\n\n // ── Functional bus ───────────────────────────────────────────────────────\n\n /**\n * Removes a previously registered functional listener for `event`.\n *\n * @param event - The event to stop listening to.\n * @param listener - The listener function to remove.\n * @returns `this` for chaining.\n */\n off<K>(event: TurnEvent<K>, listener: TurnEventListener<K>): this {\n this.#functionalEmitter.off(event, listener)\n return this\n }\n\n /**\n * Registers a persistent functional listener for `event`.\n *\n * @param event - The event to listen to.\n * @param listener - The function to call on each emission.\n * @returns `this` for chaining.\n */\n on<K>(event: TurnEvent<K>, listener: TurnEventListener<K>): this {\n this.#functionalEmitter.on(event, listener)\n return this\n }\n\n /**\n * Registers a one-time functional listener for `event` that is automatically removed after the\n * first emission.\n *\n * @param event - The event to listen to.\n * @param listener - The function to call on the next emission.\n * @returns `this` for chaining.\n */\n once<K>(event: TurnEvent<K>, listener: TurnEventListener<K>): this {\n this.#functionalEmitter.once(event, listener)\n return this\n }\n\n // ── Observability bus ────────────────────────────────────────────────────\n\n /**\n * Removes a previously registered observability listener for `event`.\n *\n * @param event - The event to stop observing.\n * @param listener - The listener function to remove.\n * @returns `this` for chaining.\n */\n unobserve<K>(\n event: TurnObservabilityEvent<K>,\n listener: TurnObservabilityEventListener<K>\n ): this {\n this.#observabilityEmitter.off(event, listener)\n return this\n }\n\n /**\n * Registers a persistent observability listener for `event`.\n *\n * @remarks\n * Use the observability bus (`observe` / `unobserve` / `observeOnce`) for instrumentation:\n * turn lifecycle, gate lifecycle, and non-fatal errors. Use the functional bus (`on` / `off` /\n * `once`) for pipeline-affecting events: `message`, `thought`, `toolCall`.\n *\n * @param event - The event to observe.\n * @param listener - The function to call on each emission.\n * @returns `this` for chaining.\n */\n observe<K>(event: TurnObservabilityEvent<K>, listener: TurnObservabilityEventListener<K>): this {\n this.#observabilityEmitter.on(event, listener)\n return this\n }\n\n /**\n * Registers a one-time observability listener for `event` that is automatically removed after\n * the first emission.\n *\n * @param event - The event to observe once.\n * @param listener - The function to call on the next emission.\n * @returns `this` for chaining.\n */\n observeOnce<K>(\n event: TurnObservabilityEvent<K>,\n listener: TurnObservabilityEventListener<K>\n ): this {\n this.#observabilityEmitter.once(event, listener)\n return this\n }\n\n // ── Turn execution ───────────────────────────────────────────────────────\n\n /**\n * Executes a single agent turn against the provided raw context.\n *\n * @remarks\n * Returns `Promise<void>` intentionally — all meaningful output surfaces via events, not return\n * values. Register listeners before calling `run`: observability events (`turnStart`, `turnEnd`)\n * bracket execution; functional events (`message`, `thought`, `toolCall`) fire throughout;\n * observability `error` carries non-fatal pipeline failures; `turnGateOpen` and `turnGateClosed`\n * fire when middleware suspends via `ctx.waitFor()`. Awaiting this method only tells you the\n * pipeline has finished, not what it produced.\n *\n * Constructs a validated {@link @nhtio/adk!TurnContext} from `context` (throwing\n * {@link @nhtio/adk!E_INVALID_TURN_CONTEXT} on failure), then runs the input middleware pipeline.\n * Abort signals are silently swallowed.\n *\n * @param context - Raw input validated and wrapped into a {@link @nhtio/adk!TurnContext} before execution.\n * @throws {@link @nhtio/adk!E_INVALID_TURN_CONTEXT} when `context` does not satisfy the schema.\n */\n async run(context: RawTurnContext): Promise<void> {\n const abortController = context.turnAbortController ?? new AbortController()\n\n // Forward declaration so openGate can reference turnContext.id before it is assigned.\n let turnContextId: string\n\n const openGate: OpenGateFn = <T>(raw: Omit<RawTurnGate, 'turnId' | 'abortSignal'>) => {\n const gate = new TurnGate<T>({\n ...raw,\n turnId: turnContextId,\n abortSignal: abortController.signal,\n })\n this.#observabilityEmitter.emit('turnGateOpen', gate)\n const promise = gate._promise()\n promise.then(\n () => {\n this.#observabilityEmitter.emit('turnGateClosed', {\n gateId: gate.id,\n turnId: gate.turnId,\n result: 'resolved',\n settledAt: DateTime.now(),\n })\n },\n (err: unknown) => {\n let result: 'rejected' | 'aborted' | 'timeout' = 'rejected'\n if (isInstanceOf(err, 'E_TURN_GATE_ABORTED')) result = 'aborted'\n else if (isInstanceOf(err, 'E_TURN_GATE_TIMEOUT')) result = 'timeout'\n this.#observabilityEmitter.emit('turnGateClosed', {\n gateId: gate.id,\n turnId: gate.turnId,\n result,\n settledAt: DateTime.now(),\n })\n }\n )\n return promise\n }\n\n const tools = new ToolRegistry(this.#config.tools)\n\n const turnContext = new TurnContext(\n { ...context, turnAbortController: abortController },\n {\n fetchMemories: this.#config.fetchMemoriesCallback,\n fetchMessages: this.#config.fetchMessagesCallback,\n fetchThoughts: this.#config.fetchThoughtsCallback,\n fetchToolCalls: this.#config.fetchToolCallsCallback,\n fetchTools: this.#config.fetchToolsCallback,\n refreshStandingInstructions: this.#config.refreshStandingInstructionsCallback,\n storeStandingInstruction: this.#config.storeStandingInstructionCallback,\n mutateStandingInstruction: this.#config.mutateStandingInstructionCallback,\n deleteStandingInstruction: this.#config.deleteStandingInstructionCallback,\n storeMemory: this.#config.storeMemoryCallback,\n mutateMemory: this.#config.mutateMemoryCallback,\n deleteMemory: this.#config.deleteMemoryCallback,\n fetchRetrievables: this.#config.fetchRetrievablesCallback,\n storeRetrievable: this.#config.storeRetrievableCallback,\n mutateRetrievable: this.#config.mutateRetrievableCallback,\n deleteRetrievable: this.#config.deleteRetrievableCallback,\n storeMessage: this.#config.storeMessageCallback,\n mutateMessage: this.#config.mutateMessageCallback,\n deleteMessage: this.#config.deleteMessageCallback,\n storeThought: this.#config.storeThoughtCallback,\n mutateThought: this.#config.mutateThoughtCallback,\n deleteThought: this.#config.deleteThoughtCallback,\n storeToolCall: this.#config.storeToolCallCallback,\n mutateToolCall: this.#config.mutateToolCallCallback,\n deleteToolCall: this.#config.deleteToolCallCallback,\n storeMediaBytes: this.#config.storeMediaBytesCallback,\n storeRetrievableBytes: this.#config.storeRetrievableBytesCallback,\n emitMessage: (content) => this.#functionalEmitter.emit('message', content),\n emitThought: (content) => this.#functionalEmitter.emit('thought', content),\n emitToolCall: (content) => this.#functionalEmitter.emit('toolCall', content),\n emitToolExecutionStart: (event) =>\n this.#observabilityEmitter.emit('toolExecutionStart', event),\n emitToolExecutionEnd: (event) => this.#observabilityEmitter.emit('toolExecutionEnd', event),\n openGate,\n tools,\n }\n )\n\n turnContextId = turnContext.id\n\n const startedAt = DateTime.now()\n this.#observabilityEmitter.emit('turnStart', { turnId: turnContext.id, startedAt })\n\n const emitTurnEnd = () => {\n const endedAt = DateTime.now()\n this.#observabilityEmitter.emit('turnEnd', {\n turnId: turnContext.id,\n startedAt,\n endedAt,\n durationMs: endedAt.diff(startedAt).milliseconds,\n })\n }\n\n // 1. Input pipeline\n let inputFailed = false\n let inputReached = false\n await this.#inputRunner\n .errorHandler(async (error) => {\n if (!isError(error) || !isInstanceOf(error, 'AbortError')) {\n inputFailed = true\n const err = new E_INPUT_PIPELINE_ERROR({\n cause: isError(error) ? error : undefined,\n })\n this.#observabilityEmitter.emit('error', err)\n }\n })\n .finalHandler(async () => {\n inputReached = true\n })\n .run((fn, next) => Promise.resolve(fn(turnContext, next)))\n\n if (!inputReached && !inputFailed && !turnContext.aborted) {\n inputFailed = true\n const err = new E_PIPELINE_SHORT_CIRCUITED(['turn-input'])\n this.#observabilityEmitter.emit('error', err)\n }\n\n if (inputFailed || turnContext.aborted) {\n emitTurnEnd()\n return\n }\n\n // 2. LLM execution dispatch\n let dispatchFailed = false\n try {\n await DispatchRunner.dispatch({\n source: turnContext,\n executor: this.#config.executorCallback,\n turnInputPipeline: this.#config.dispatchInputPipeline,\n turnOutputPipeline: this.#config.dispatchOutputPipeline,\n observers: {\n dispatchStart: [\n (e) => {\n this.#observabilityEmitter.emit('dispatchStart', e)\n },\n ],\n dispatchEnd: [\n (e) => {\n this.#observabilityEmitter.emit('dispatchEnd', e)\n },\n ],\n iterationStart: [\n (e) => {\n this.#observabilityEmitter.emit('iterationStart', e)\n },\n ],\n iterationEnd: [\n (e) => {\n this.#observabilityEmitter.emit('iterationEnd', e)\n },\n ],\n log: [\n (e) => {\n this.#observabilityEmitter.emit('log', e)\n },\n ],\n },\n })\n } catch (err) {\n dispatchFailed = true\n const wrapped = isInstanceOf(err, 'BaseException') ? (err as InstanceType<typeof Error>) : err\n this.#observabilityEmitter.emit('error', wrapped as any)\n }\n\n if (dispatchFailed || turnContext.aborted) {\n emitTurnEnd()\n return\n }\n\n // 3. Output pipeline\n let outputFailed = false\n let outputReached = false\n await this.#outputRunner\n .errorHandler(async (error) => {\n if (!isError(error) || !isInstanceOf(error, 'AbortError')) {\n outputFailed = true\n const err = new E_OUTPUT_PIPELINE_ERROR({\n cause: isError(error) ? error : undefined,\n })\n this.#observabilityEmitter.emit('error', err)\n }\n })\n .finalHandler(async () => {\n outputReached = true\n })\n .run((fn, next) => Promise.resolve(fn(turnContext, next)))\n\n if (!outputReached && !outputFailed && !turnContext.aborted) {\n const err = new E_PIPELINE_SHORT_CIRCUITED(['turn-output'])\n this.#observabilityEmitter.emit('error', err)\n }\n\n emitTurnEnd()\n }\n}\n"],"mappings":"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"}
|
package/turn_runner.cjs
CHANGED
package/turn_runner.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as TurnRunner } from "./turn_runner-
|
|
1
|
+
import { t as TurnRunner } from "./turn_runner-DRBLN2Y_.mjs";
|
|
2
2
|
export { TurnRunner };
|
package/types.d.ts
CHANGED
|
@@ -41,13 +41,13 @@ export type { TokenEncoding } from "./lib/classes/tokenizable";
|
|
|
41
41
|
/**
|
|
42
42
|
* @primaryExport
|
|
43
43
|
*/
|
|
44
|
-
export type { RawTurnContext, ResolvedTurnContext, MemoryRetrievalFn, MessageRetrievalFn, ThoughtRetrievalFn, ToolCallRetrievalFn, ToolsRetrievalFn, RetrievableRetrievalFn, StandingInstructionsRefreshFn, StandingInstructionStoreFn, StandingInstructionMutateFn, StandingInstructionDeleteFn, MemoryStoreFn, MemoryMutateFn, MemoryDeleteFn, MessageStoreFn, MessageMutateFn, MessageDeleteFn, ThoughtStoreFn, ThoughtMutateFn, ThoughtDeleteFn, ToolCallStoreFn, ToolCallMutateFn, ToolCallDeleteFn, RetrievableStoreFn, RetrievableMutateFn, RetrievableDeleteFn, } from "./lib/contracts/turn_runner_context";
|
|
44
|
+
export type { RawTurnContext, ResolvedTurnContext, MemoryRetrievalFn, MessageRetrievalFn, ThoughtRetrievalFn, ToolCallRetrievalFn, ToolsRetrievalFn, RetrievableRetrievalFn, StandingInstructionsRefreshFn, StandingInstructionStoreFn, StandingInstructionMutateFn, StandingInstructionDeleteFn, MemoryStoreFn, MemoryMutateFn, MemoryDeleteFn, MessageStoreFn, MessageMutateFn, MessageDeleteFn, ThoughtStoreFn, ThoughtMutateFn, ThoughtDeleteFn, ToolCallStoreFn, ToolCallMutateFn, ToolCallDeleteFn, RetrievableStoreFn, RetrievableMutateFn, RetrievableDeleteFn, MediaBytesStoreFn, RetrievableBytesStoreFn, } from "./lib/contracts/turn_runner_context";
|
|
45
45
|
export type { TurnRunnerConfig, ResolvedTurnRunnerConfig } from "./lib/contracts/turn_runner_config";
|
|
46
46
|
export type { TurnPipelineMiddlewareFn, TurnStreamableContent, TurnToolCallContent, TurnStartEvent, TurnEndEvent, TurnGateClosedEvent, ToolExecutionStartEvent, ToolExecutionEndEvent, EmitMessageFn, EmitThoughtFn, EmitToolCallFn, EmitToolExecutionStartFn, EmitToolExecutionEndFn, OpenGateFn, TurnEvents, TurnEvent, TurnEventListener, TurnObservabilityEvents, TurnObservabilityEvent, TurnObservabilityEventListener, } from "./lib/types/turn_runner";
|
|
47
47
|
/**
|
|
48
48
|
* @primaryExport
|
|
49
49
|
*/
|
|
50
|
-
export type { RawDispatchContext, DispatchMemoryRetrievalFn, DispatchMessageRetrievalFn, DispatchThoughtRetrievalFn, DispatchToolCallRetrievalFn, DispatchToolsRetrievalFn, DispatchStandingInstructionsRefreshFn, DispatchStandingInstructionStoreFn, DispatchStandingInstructionMutateFn, DispatchStandingInstructionDeleteFn, DispatchMemoryStoreFn, DispatchMemoryMutateFn, DispatchMemoryDeleteFn, DispatchMessageStoreFn, DispatchMessageMutateFn, DispatchMessageDeleteFn, DispatchThoughtStoreFn, DispatchThoughtMutateFn, DispatchThoughtDeleteFn, DispatchToolCallStoreFn, DispatchToolCallMutateFn, DispatchToolCallDeleteFn, } from "./lib/contracts/dispatch_context";
|
|
50
|
+
export type { RawDispatchContext, DispatchMemoryRetrievalFn, DispatchMessageRetrievalFn, DispatchThoughtRetrievalFn, DispatchToolCallRetrievalFn, DispatchToolsRetrievalFn, DispatchStandingInstructionsRefreshFn, DispatchStandingInstructionStoreFn, DispatchStandingInstructionMutateFn, DispatchStandingInstructionDeleteFn, DispatchMemoryStoreFn, DispatchMemoryMutateFn, DispatchMemoryDeleteFn, DispatchMessageStoreFn, DispatchMessageMutateFn, DispatchMessageDeleteFn, DispatchThoughtStoreFn, DispatchThoughtMutateFn, DispatchThoughtDeleteFn, DispatchToolCallStoreFn, DispatchToolCallMutateFn, DispatchToolCallDeleteFn, DispatchMediaBytesStoreFn, DispatchRetrievableBytesStoreFn, ConduitBytes, } from "./lib/contracts/dispatch_context";
|
|
51
51
|
/**
|
|
52
52
|
* @primaryExport
|
|
53
53
|
*/
|
package/chunk-KmRHZBOW.js
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
//#region \0rolldown/runtime.js
|
|
2
|
-
var __create = Object.create;
|
|
3
|
-
var __defProp = Object.defineProperty;
|
|
4
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
|
|
9
|
-
var __copyProps = (to, from, except, desc) => {
|
|
10
|
-
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
11
|
-
key = keys[i];
|
|
12
|
-
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
13
|
-
get: ((k) => from[k]).bind(null, key),
|
|
14
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
return to;
|
|
18
|
-
};
|
|
19
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
20
|
-
value: mod,
|
|
21
|
-
enumerable: true
|
|
22
|
-
}) : target, mod));
|
|
23
|
-
//#endregion
|
|
24
|
-
Object.defineProperty(exports, "__commonJSMin", {
|
|
25
|
-
enumerable: true,
|
|
26
|
-
get: function() {
|
|
27
|
-
return __commonJSMin;
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
|
-
Object.defineProperty(exports, "__toESM", {
|
|
31
|
-
enumerable: true,
|
|
32
|
-
get: function() {
|
|
33
|
-
return __toESM;
|
|
34
|
-
}
|
|
35
|
-
});
|
package/common-DeZaonK1.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"common-DeZaonK1.mjs","names":["#id","#content","#trustTier","#source","#kind","#score","#createdAt","#updatedAt"],"sources":["../src/lib/classes/retrievable.ts","../src/lib/helpers/media_readers.ts"],"sourcesContent":["import { Tokenizable } from './tokenizable'\nimport { validator } from '@nhtio/validation'\nimport { validateOrThrow } from '../utils/validation'\nimport { isInstanceOf, isError } from '../utils/guards'\nimport { E_INVALID_INITIAL_RETRIEVABLE_VALUE } from '../exceptions/runtime'\nimport type { DateTime } from 'luxon'\n\n/**\n * Trust-tier discriminator declared by the retrieval middleware at construction time. Drives\n * which envelope the LLM battery wraps the record in.\n *\n * @remarks\n * Vocabulary deliberately mirrors the published security-research taxonomy (\"first-party /\n * third-party\" per *Hidden-in-Plain-Text* WWW '26 and *When AI Meets the Web* IEEE S&P 2026)\n * and explicitly avoids the words \"user\" or \"system\" so the names cannot leak into the model's\n * OpenAI-Model-Spec role-tier authority resolution.\n *\n * - `'first-party'` — deployer-vetted corpora (signed internal docs, policy KBs, curated\n * reference material). Rendered as a `<retrieved_corpus>` parent with per-record nonce-keyed\n * `<retrieved>` children. The label \"first-party\" never appears in the envelope itself.\n * - `'third-party-public'` — open-web scrapes, search results, public APIs. Rendered through\n * the untrusted-content envelope with `kind: 'retrieved-third-party-public'`.\n * - `'third-party-private'` — user uploads, pasted attachments, partner APIs. Rendered through\n * the untrusted-content envelope with `kind: 'retrieved-third-party-private'`.\n */\nexport type RetrievableTrustTier = 'first-party' | 'third-party-public' | 'third-party-private'\n\n/**\n * Plain input object supplied to {@link Retrievable} at construction time.\n *\n * @remarks\n * Validated against `rawRetrievableSchema` before the `Retrievable` instance is created.\n * Temporal fields accept any value that Luxon can parse — ISO strings, Unix timestamps,\n * `Date` objects, or existing `DateTime` instances.\n */\nexport interface RawRetrievable {\n /**\n * Stable unique identifier for this retrieved record. Used as the closing-tag nonce in the\n * rendered envelope, so it must be unguessable from the payload.\n */\n id: string\n /** The retrieved content as a plain string or an existing {@link @nhtio/adk!Tokenizable} instance. */\n content: string | Tokenizable\n /**\n * Trust tier declared by the retrieval middleware at construction time. Required — there is\n * NO default. The decision must be conscious. See {@link RetrievableTrustTier}.\n */\n trustTier: RetrievableTrustTier\n /** Optional provenance string: URL, document path, knowledge-base id, etc. */\n source?: string\n /** Optional semantic label: 'policy' | 'reference' | 'web-page' | 'pdf' | etc. */\n kind?: string\n /** Optional relevance / similarity score in `[0, 1]` from the retrieval middleware. */\n score?: number\n /** When the source record was created (publication date, upload date, etc.). */\n createdAt: string | number | Date | DateTime\n /** When the source record was last modified. */\n updatedAt: string | number | Date | DateTime\n}\n\n/**\n * A fully-resolved {@link RawRetrievable} where all fields have been validated and temporal\n * values normalised to Luxon `DateTime` instances.\n */\ninterface ResolvedRetrievable {\n id: string\n content: Tokenizable\n trustTier: RetrievableTrustTier\n source?: string\n kind?: string\n score?: number\n createdAt: DateTime\n updatedAt: DateTime\n}\n\n/**\n * Validator schema used to validate a {@link RawRetrievable} before constructing a\n * {@link Retrievable}.\n *\n * @remarks\n * - `id` — required non-empty string.\n * - `content` — required {@link @nhtio/adk!Tokenizable.schema}.\n * - `trustTier` — required, one of `'first-party'`, `'third-party-public'`,\n * `'third-party-private'`. Unknown / missing values reject.\n * - `source` / `kind` — optional strings.\n * - `score` — optional number in `[0, 1]`.\n * - `createdAt` / `updatedAt` — required datetime-parseable values.\n *\n * Throws {@link @nhtio/adk/exceptions!E_INVALID_INITIAL_RETRIEVABLE_VALUE} (via the {@link Retrievable} constructor)\n * when validation fails.\n */\nconst rawRetrievableSchema = validator.object<RawRetrievable>({\n id: validator.string().required(),\n content: Tokenizable.schema.required(),\n trustTier: validator\n .string()\n .valid('first-party', 'third-party-public', 'third-party-private')\n .required(),\n source: validator.string().optional(),\n kind: validator.string().optional(),\n score: validator.number().min(0).max(1).optional(),\n createdAt: validator.datetime().required(),\n updatedAt: validator.datetime().required(),\n})\n\n/**\n * An immutable, validated retrieved record (RAG content) held by the agent.\n *\n * @remarks\n * Peer of {@link @nhtio/adk!Memory} / `Message` / `Thought` / `ToolCall`. Carries an explicit `trustTier`\n * that LLM batteries branch on to choose the rendering envelope. The retrieval middleware that\n * produced the record is the only party that knows its provenance — batteries MUST NOT\n * auto-classify or infer the tier from `source`.\n */\nexport class Retrievable {\n /**\n * Validator schema that accepts a {@link RawRetrievable} object.\n *\n * @remarks\n * Reusable fragment for any schema that needs to validate or nest a retrievable record.\n */\n public static schema = rawRetrievableSchema\n\n /**\n * Returns `true` if `value` is a {@link Retrievable} instance.\n *\n * @remarks\n * Uses {@link @nhtio/adk!isInstanceOf} for cross-realm safety.\n */\n public static isRetrievable(value: unknown): value is Retrievable {\n return isInstanceOf(value, 'Retrievable', Retrievable)\n }\n\n /** Stable unique identifier for this retrieved record. */\n declare readonly id: string\n /** The retrieved content as a {@link @nhtio/adk!Tokenizable} for inline token estimation. */\n declare readonly content: Tokenizable\n /** Trust tier declared by the retrieval middleware. */\n declare readonly trustTier: RetrievableTrustTier\n /** Optional provenance string. */\n declare readonly source: string | undefined\n /** Optional semantic label. */\n declare readonly kind: string | undefined\n /** Optional relevance / similarity score in `[0, 1]`. */\n declare readonly score: number | undefined\n /** When the source record was created. */\n declare readonly createdAt: DateTime\n /** When the source record was last modified. */\n declare readonly updatedAt: DateTime\n\n #id: string\n #content: Tokenizable\n #trustTier: RetrievableTrustTier\n #source: string | undefined\n #kind: string | undefined\n #score: number | undefined\n #createdAt: DateTime\n #updatedAt: DateTime\n\n /**\n * @param raw - The raw retrievable input validated against `rawRetrievableSchema`.\n * @throws {@link @nhtio/adk/exceptions!E_INVALID_INITIAL_RETRIEVABLE_VALUE} when `raw` does not satisfy the schema.\n */\n constructor(raw: RawRetrievable) {\n let resolved: ResolvedRetrievable\n try {\n resolved = validateOrThrow<ResolvedRetrievable>(rawRetrievableSchema, raw, true)\n } catch (err) {\n throw new E_INVALID_INITIAL_RETRIEVABLE_VALUE({ cause: isError(err) ? err : undefined })\n }\n this.#id = resolved.id\n this.#content = Tokenizable.isTokenizable(resolved.content)\n ? resolved.content\n : new Tokenizable(resolved.content)\n this.#trustTier = resolved.trustTier\n this.#source = resolved.source\n this.#kind = resolved.kind\n this.#score = resolved.score\n this.#createdAt = resolved.createdAt\n this.#updatedAt = resolved.updatedAt\n\n Object.defineProperties(this, {\n id: {\n get: () => this.#id,\n enumerable: true,\n configurable: false,\n },\n content: {\n get: () => this.#content,\n enumerable: true,\n configurable: false,\n },\n trustTier: {\n get: () => this.#trustTier,\n enumerable: true,\n configurable: false,\n },\n source: {\n get: () => this.#source,\n enumerable: true,\n configurable: false,\n },\n kind: {\n get: () => this.#kind,\n enumerable: true,\n configurable: false,\n },\n score: {\n get: () => this.#score,\n enumerable: true,\n configurable: false,\n },\n createdAt: {\n get: () => this.#createdAt,\n enumerable: true,\n configurable: false,\n },\n updatedAt: {\n get: () => this.#updatedAt,\n enumerable: true,\n configurable: false,\n },\n })\n }\n}\n","import type { MediaReader } from '../contracts/media_reader'\n\n/**\n * Constructs a {@link @nhtio/adk!MediaReader} backed by an in-memory `Uint8Array`.\n *\n * @remarks\n * Each `stream()` call returns a fresh single-chunk `ReadableStream` over the same buffer. The\n * reader is re-openable by construction — call `stream()` as many times as needed.\n *\n * @param bytes - The buffer to serve.\n * @returns A {@link @nhtio/adk!MediaReader} that re-reads `bytes` on every call.\n */\nexport const inMemoryMediaReader = (bytes: Uint8Array): MediaReader => {\n return {\n stream(): ReadableStream<Uint8Array> {\n return new ReadableStream<Uint8Array>({\n start(controller) {\n controller.enqueue(bytes)\n controller.close()\n },\n })\n },\n byteLength(): number {\n return bytes.byteLength\n },\n }\n}\n\n/**\n * Constructs a {@link @nhtio/adk!MediaReader} backed by a fetch call.\n *\n * @remarks\n * Each `stream()` call re-issues the fetch. Tool authors whose underlying source is rate-limited\n * or expensive must cache locally before constructing the reader — the framework cannot make\n * that decision for them.\n *\n * `byteLength()` returns `undefined` because most remote sources do not promise it without an\n * extra HEAD request; consumers that need a byte size should resolve it out-of-band.\n *\n * @param url - The URL to fetch on each call.\n * @param init - Optional `fetch` init forwarded verbatim.\n * @returns A {@link @nhtio/adk!MediaReader} that re-issues `fetch(url, init)` on every call.\n */\nexport const fromFetch = (url: string | URL, init?: RequestInit): MediaReader => {\n return {\n async stream(): Promise<ReadableStream<Uint8Array>> {\n const response = await fetch(url, init)\n if (!response.ok) {\n throw new Error(`fromFetch: fetch failed with status ${response.status}`)\n }\n if (!response.body) {\n throw new Error('fromFetch: response has no body')\n }\n return response.body as ReadableStream<Uint8Array>\n },\n byteLength(): undefined {\n return undefined\n },\n }\n}\n\n/**\n * Constructs a {@link @nhtio/adk!MediaReader} backed by a browser `File` or `Blob`.\n *\n * @remarks\n * Each `stream()` call re-streams the underlying File via `File.stream()`. `byteLength()`\n * resolves from `file.size`.\n *\n * @param file - The browser `File` or `Blob` to stream.\n * @returns A {@link @nhtio/adk!MediaReader} that re-streams `file` on every call.\n */\nexport const fromWebFile = (file: Blob): MediaReader => {\n return {\n stream(): ReadableStream<Uint8Array> {\n return file.stream() as ReadableStream<Uint8Array>\n },\n byteLength(): number {\n return file.size\n },\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AA2FA,IAAM,uBAAuB,UAAU,OAAuB;CAC5D,IAAI,UAAU,OAAO,EAAE,SAAS;CAChC,SAAS,YAAY,OAAO,SAAS;CACrC,WAAW,UACR,OAAO,EACP,MAAM,eAAe,sBAAsB,qBAAqB,EAChE,SAAS;CACZ,QAAQ,UAAU,OAAO,EAAE,SAAS;CACpC,MAAM,UAAU,OAAO,EAAE,SAAS;CAClC,OAAO,UAAU,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,SAAS;CACjD,WAAW,UAAU,SAAS,EAAE,SAAS;CACzC,WAAW,UAAU,SAAS,EAAE,SAAS;AAC3C,CAAC;;;;;;;;;;AAWD,IAAa,cAAb,MAAa,YAAY;;;;;;;CAOvB,OAAc,SAAS;;;;;;;CAQvB,OAAc,cAAc,OAAsC;EAChE,OAAO,aAAa,OAAO,eAAe,WAAW;CACvD;CAmBA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;;;;;CAMA,YAAY,KAAqB;EAC/B,IAAI;EACJ,IAAI;GACF,WAAW,gBAAqC,sBAAsB,KAAK,IAAI;EACjF,SAAS,KAAK;GACZ,MAAM,IAAI,oCAAoC,EAAE,OAAO,QAAQ,GAAG,IAAI,MAAM,KAAA,EAAU,CAAC;EACzF;EACA,KAAKA,MAAM,SAAS;EACpB,KAAKC,WAAW,YAAY,cAAc,SAAS,OAAO,IACtD,SAAS,UACT,IAAI,YAAY,SAAS,OAAO;EACpC,KAAKC,aAAa,SAAS;EAC3B,KAAKC,UAAU,SAAS;EACxB,KAAKC,QAAQ,SAAS;EACtB,KAAKC,SAAS,SAAS;EACvB,KAAKC,aAAa,SAAS;EAC3B,KAAKC,aAAa,SAAS;EAE3B,OAAO,iBAAiB,MAAM;GAC5B,IAAI;IACF,WAAW,KAAKP;IAChB,YAAY;IACZ,cAAc;GAChB;GACA,SAAS;IACP,WAAW,KAAKC;IAChB,YAAY;IACZ,cAAc;GAChB;GACA,WAAW;IACT,WAAW,KAAKC;IAChB,YAAY;IACZ,cAAc;GAChB;GACA,QAAQ;IACN,WAAW,KAAKC;IAChB,YAAY;IACZ,cAAc;GAChB;GACA,MAAM;IACJ,WAAW,KAAKC;IAChB,YAAY;IACZ,cAAc;GAChB;GACA,OAAO;IACL,WAAW,KAAKC;IAChB,YAAY;IACZ,cAAc;GAChB;GACA,WAAW;IACT,WAAW,KAAKC;IAChB,YAAY;IACZ,cAAc;GAChB;GACA,WAAW;IACT,WAAW,KAAKC;IAChB,YAAY;IACZ,cAAc;GAChB;EACF,CAAC;CACH;AACF;;;;;;;;;;;;;ACpNA,IAAa,uBAAuB,UAAmC;CACrE,OAAO;EACL,SAAqC;GACnC,OAAO,IAAI,eAA2B,EACpC,MAAM,YAAY;IAChB,WAAW,QAAQ,KAAK;IACxB,WAAW,MAAM;GACnB,EACF,CAAC;EACH;EACA,aAAqB;GACnB,OAAO,MAAM;EACf;CACF;AACF;;;;;;;;;;;;;;;;AAiBA,IAAa,aAAa,KAAmB,SAAoC;CAC/E,OAAO;EACL,MAAM,SAA8C;GAClD,MAAM,WAAW,MAAM,MAAM,KAAK,IAAI;GACtC,IAAI,CAAC,SAAS,IACZ,MAAM,IAAI,MAAM,uCAAuC,SAAS,QAAQ;GAE1E,IAAI,CAAC,SAAS,MACZ,MAAM,IAAI,MAAM,iCAAiC;GAEnD,OAAO,SAAS;EAClB;EACA,aAAwB,CAExB;CACF;AACF;;;;;;;;;;;AAYA,IAAa,eAAe,SAA4B;CACtD,OAAO;EACL,SAAqC;GACnC,OAAO,KAAK,OAAO;EACrB;EACA,aAAqB;GACnB,OAAO,KAAK;EACd;CACF;AACF"}
|