Skip to content
3 min read · 689 words

Interface: RawTool<A>

Plain input object supplied to Tool at construction time.

Type Parameters

Type ParameterDefault typeDescription
A extends SpooledArtifactSpooledArtifactThe @nhtio/adk!SpooledArtifact subtype used to wrap this tool's results when the consumer assembles a ToolCall.results field. Defaults to @nhtio/adk!SpooledArtifact (plain text). Tools producing JSON output should set this to SpooledJsonArtifact; tools producing markdown should set it to SpooledMarkdownArtifact; consumers can also pass a custom subclass.

Properties

PropertyTypeDefault valueDescription
artifactConstructor?ArtifactConstructorResolver<A>undefinedZero-arg resolver returning the @nhtio/adk!SpooledArtifactConstructor the consumer should use when wrapping this tool's serialised output into a ToolCall.results field. Optional — when omitted, wrap-sites fall back to @nhtio/adk!SpooledArtifact (plain text). Remarks Recommended call shape: artifactConstructor: () => SpooledJsonArtifact. The closure is the indirection that lets tool.ts validate this field without eagerly importing SpooledArtifact (which would crash the tool.ts ↔ spooled_artifact.ts ↔ artifact_tool.ts module-load cycle). At validate time the schema invokes the resolver and verifies its return value is a SpooledArtifact-derived constructor — wrong-shape resolvers throw @nhtio/adk!E_INVALID_INITIAL_TOOL_VALUE. Wrap-sites (storage batteries, scripted executors) read the constructor via tool.artifactConstructor?.() ?? SpooledArtifact.
descriptionstringundefinedHuman-readable description passed to the model to explain what the tool does.
ephemeral?booleanfalseWhen true, marks this tool as owned by a specific @nhtio/adk!DispatchContext so that ToolRegistry.pruneEphemeral() will drop it at ctx-completion. Remarks The flag is advisory at the Tool level — registries decide what to do with it. The canonical producer of ephemeral tools is SpooledArtifact.forgeTools(ctx), which sets this to true on every artifact-query tool it emits.
handlerToolHandlerundefinedExecution function. Not exposed as a public property — invoke via executor().
inputSchemaSchemaundefined@nhtio/validation schema for the tool's input arguments. Annotate with .description(), .note(), .example() etc. to produce rich LLM tool definitions via .describe().
meta?Record<string, unknown>undefinedOptional arbitrary metadata for this tool (e.g. RBAC scopes, feature flags). Defaults to {}. Stored in a @nhtio/adk!Registry for dot-path access.
namestringundefinedUnique identifier used in LLM tool definitions. Recommend lowercase snake_case.
onCollision?"keep" | "replace" | "throw"'throw'Self-declared merge collision policy. Honoured by ToolRegistry.merge (NOT by ToolRegistry.register) when this tool collides with another of the same name. Remarks - 'throw' (default): defer to the merge-level options.onCollision. If that is also 'throw', the merge raises E_TOOL_ALREADY_REGISTERED. This matches the default behaviour of ToolRegistry.register. - 'replace': this tool always wins the collision, regardless of the merge-level option. - 'keep': this tool always loses to any previously-registered tool of the same name. Forged artifact-query tools set this to 'replace' so that merging multiple Subclass.forgeTools(ctx) outputs (whose base-method tools overlap by name) resolves silently — the descriptors, snapshot, and handler behaviour are interchangeable across subclasses, so replacement is a behavioural no-op.
trusted?booleanfalseWhen true, declares that this tool's output should be treated as trusted developer/user intent rather than as untrusted third-party text when surfaced to the model. Remarks LLM batteries read this flag per call when rendering tool-call results. The default untrusted envelope (e.g. <untrusted_content> in the OpenAI Chat Completions battery) is the secure-by-default treatment for arbitrary tool output. A tool whose output is authored by the user or operator (Q&A tools surfacing user-authored answers, human-in-the-loop approval gates, feedback-collection tools, configuration tools returning developer-authored constants) sets this to true so the LLM battery routes the result through its trusted envelope (<trusted_content> in the OpenAI Chat Completions battery). Trust is a property of the tool's output, not a property of how a particular battery is wired — putting the flag here means the trust signal travels with the tool wherever it is registered, no per-battery string lists, no name-matching to fail-open on typos.