/** * The orchestration battery — plan lifecycle, execution, and the model-facing tool forge. * * @module @nhtio/adk/batteries/orchestration * * @remarks * This is the battery's BARREL and its single entry point: the assembly gate where the * work-package pieces (validation, approval, the executor, templates, rendering, the raw * views, the outline reader and the tool forge) are wired together. It is the one place a * precondition can be enforced for every operation, which is why the encoder requirement and * evaluator loading live here rather than scattered across the modules that happen to need them. * * ### Why `createOrchestration` is async * * Construction is the last moment a deployment can fail LOUDLY and EARLY. Four things are * resolved here, before any plan is created, frozen or approved: * * 1. **The encoder is required.** `@nhtio/encoder` is declared an OPTIONAL PEER of the whole * package — peer metadata is package-wide, not subpath-scoped, so making it required would * force it on every consumer including the many who never import orchestration. The * requirement is enforced where it CAN be: at construction, by eagerly * `await import('@nhtio/encoder')` and throwing {@link E_ORCH_ENCODER_REQUIRED} (naming the * package and its install command) if it is absent. Failing here means no plan is ever created, * frozen or approved in a deployment missing the encoder — the property that actually matters. * It is genuinely required because the digest comes from a lossless canonical encoding, and * digests are load-bearing in every lifecycle transition, approval binding and `claimRun` — * even an in-memory store needs them. * 2. **Encodables are registered once.** `registerOrchestrationEncodables()` is called here, * once, because `registerClass` is a global registry and decoding an unregistered class throws. * 3. **Every configured evaluator cell is loaded.** `await load()` runs on each cell supplied at * construction, so a missing optional peer surfaces HERE rather than part-way through a freeze. * A cell supplied per-run is loaded at that point, with the same named error. * 4. **Every registered template is validated.** `validateTemplate` runs on each template and a * blocking issue throws, so a misconfigured deployment fails at boot with a named error rather * than at first instantiation months later. * * ### Dependency precedence * * Resolved HERE and stated once so it cannot drift: **per-run wins field by field over * construction**; anything absent from both is a named error if the plan needs it. `evaluators` * MERGE BY CELL `id` — a per-run cell replaces the configured one with the same id, others * survive — because a run legitimately swaps one cell while keeping the rest. Everything else * replaces wholesale. * * ### Environment neutrality * * The barrel stays environment-neutral: there is no `node:*` anywhere in its module graph. The * Lua cell (`./cells/lua`) imports `node:worker_threads` and is therefore NOT re-exported here — * it is reachable only via its own deep subpath. * * The conformance suite (`./conformance`) is excluded for the same reason in a different * dimension: it imports `vitest`, which is an OPTIONAL peer dependency. A barrel re-export makes * that import part of every consumer's module graph, so `import '@nhtio/adk/batteries/orchestration'` * fails with `ERR_MODULE_NOT_FOUND` for anyone who has not installed a test runner — which is * every production consumer. It is reachable only via its own deep subpath, from a test * environment where `vitest` is present. This matches `batteries/vector`, whose conformance suite * is likewise vitest-based and likewise subpath-only. (`batteries/sandbox` DOES re-export its * suite from its barrel, and that is fine: it asserts through a local `assert` helper and imports * no test framework at all. The rule is about the `vitest` import, not about conformance suites.) * * The structured and jexl cells, the types, the exceptions, the store contract and the in-memory * store, and the raw/render/outline functions are all re-exported. * * ### How the deep subpaths are named * * Every module carrying an `@module` tag becomes one published entry, and the entry key is its * FULL path from `src/` — `batteries/orchestration/forge`, not `forge`. The build derives the map * by scanning for those tags (`getEntries` in `bin/utils`), and the emitted declaration sits at * the matching path, so `dist/batteries/orchestration/types.d.ts` and `dist/types.d.ts` are * different files reached by different specifiers. * * Stated because the leaf basenames repeat and that looks alarming: this battery ships `forge` * and `types`, and so do the root package and several other batteries — 25 modules end in * `/types` today, four in `/forge`. None of them collide, because nothing is keyed on the * basename. A module tagged here can never overwrite `@nhtio/adk/forge`. */ import type { CreateOrchestration } from "./types"; export { InMemoryPlanStore } from "./in_memory"; export { createStructuredCell } from "./cells/structured"; export type { JexlCellOptions, JexlTransform } from "./cells/jexl"; export { createJexlCell } from "./cells/jexl"; export { renderPlan } from "./render"; export type { RenderPlanOptions } from "./render"; export { rawPlan, rawOps, rawDiff } from "./raw"; export { planOutline, planRead } from "./outline"; export { NodeRef, ParamRef, registerOrchestrationEncodables, planDigest } from "./encoding"; export { computeAuthoritySet } from "./approval"; export { validateTemplate, instantiateTemplate } from "./templates"; export { forgeOrchestrationTools } from "./forge"; export type { ForgeOrchestrationRuntime, ForgeOrchestrationOptions } from "./forge"; export { effectiveToolMethods } from "./artifact_methods"; export { isPlanNode, isPlanEdge, nodeById, outgoing, incoming, entryNodes, reachableFrom, findCycle, routesBetween, immediateDominator, handleAppliesTo, readPath, isValidNodeId, isValidEdgeId, } from "./plan"; export { foldRun } from "./runs"; export { foldOps, branchKey } from "./ops"; export { joinPromptParts, stripInstructionTags, wrapInstruction, decodeOutputSchema, validateReasonerOutput, } from "./reason"; export { isPredicateLeaf, isAllPredicate, isAnyPredicate, isNotPredicate, isStructuredPredicate, parseStructuredPredicate, loadOnce, } from "./predicates"; export type { PredicateOp, PredicateLeaf, AllPredicate, AnyPredicate, NotPredicate, StructuredPredicate, ParsePredicateResult, } from "./predicates"; export { createDispatchReasoner } from "./dispatch_reasoner"; export { E_ORCH_ENCODER_REQUIRED, E_ORCH_CELL_UNAVAILABLE } from "./exceptions"; export type { PlanStore, CreateResult, AppendResult, TransitionRequest, TransitionResult, ClaimRunResult, } from "./store"; export type { PlanLock, PlanLockFactory } from "./locks"; export type { PlanState, PlanId, NodeId, EncodableValue, ArgValue, BranchId, RouteSegment, NodeOutput, OutputItem, OutputTable, ArtifactTable, SpooledArtifactLike, MediaLike, PlanNodeKind, EdgeHandle, PlanEdge, DeclaredField, EntryNodeDefinition, CallNodeDefinition, ReasonNodeDefinition, PromptPart, TransformNodeDefinition, BranchNodeDefinition, SelectNodeDefinition, JoinNodeDefinition, PlanNode, PlanOutline, PhaseEntry, PlanSlice, NodeOutcome, FrameRef, RunEvent, PendingFrame, JoinState, RunProjection, CallInvokerFn, ToolResult, ArtifactMethodDescriptor, ArtifactClassLike, ReasonerFn, PredicateEvaluator, PredicateContext, PredicateVerdict, AuthorityClaim, AuthorityVerb, PlanOp, PlanBounds, PlanTemplate, TemplateArgValue, TemplateNode, TemplateDefinitionOf, InstantiateResult, RawPlanView, PlanSummary, PlanIssue, PlanDiff, ApprovalRecord, InterruptionCause, PlanProvenance, ClonedFrom, InstantiatedFrom, RunDeps, RunOptions, ExecutePlanFn, FreezeInputs, InvocableTools, Orchestration, CreateOrchestration, } from "./types"; /** * THE battery's single entry point. Everything public is reached through the * {@link Orchestration} object it returns, so it is the one place a precondition can be enforced * for every operation. * * Construction is async because it eagerly resolves the `@nhtio/encoder` optional peer (throwing * {@link E_ORCH_ENCODER_REQUIRED} if absent), registers the orchestration encodables once, loads * every configured evaluator cell (so a missing optional peer surfaces here rather than at * freeze), and validates every registered template (so a misconfigured deployment fails at boot * with a named error rather than at first instantiation). * * **You do not need to call `registerOrchestrationEncodables()` yourself if you construct through * this function** — it runs here, before any plan can exist, so `decode()` can rebuild `NodeRef` * and `ParamRef` from that moment on. Call it directly only when you reach the deep subpaths * WITHOUT constructing an `Orchestration`: decoding a persisted plan in a worker that never builds * one, for instance. It is idempotent, so calling it anyway is harmless. * * See the module doc for the full rationale and the dependency-precedence rules. * * @param config - The store, tier-C allowlist, optional run-dependency defaults, and optional * consumer-defined plan templates. * @returns The assembled {@link Orchestration} surface. * @throws {E_ORCH_ENCODER_REQUIRED} if `@nhtio/encoder` is not installed. * @throws {E_ORCH_CELL_UNAVAILABLE} if a configured evaluator cell's optional peer is missing. * @throws {Error} if a registered template has a blocking validation issue. */ export declare const createOrchestration: CreateOrchestration;