Annotation Runtime Status
A reference of the annotations TnsAI exposes in com.tnsai.annotations, grouped by area, with each one's runtime status so you know what actually takes effect.
This page is the published runtime-status catalog (wired / nested-wired / partial / scaffold). For field tables and usage examples, see the Semantic Annotation Framework.
TnsAI is annotation-driven: you describe an agent, role, action, or tool declaratively and the framework wires the behaviour. A handful of annotations are still being wired or are on their way out — this page tells you which is which, so you don't reach for one that silently does nothing.
Status legend
| Status | What it means for you |
|---|---|
| Wired | The runtime honours the annotation and all of its advertised fields. Safe to use. |
| Nested-wired | Honoured, but only valid inside a parent annotation (e.g. @LLMSpec inside @RoleSpec(llm = …)), not on its own. |
| Partial | Honoured, but only a subset of fields takes effect today; the rest are no-ops until a later release. Notes call out which. |
| Scaffold | Declared but not yet wired — using it has no runtime effect yet. Planned. |
Annotations that used to exist but were removed are listed under Recently consolidated with their replacements. See the Changelog for the exact release and migration notes.
Core
The annotations almost every agent uses.
@RoleSpec — Wired
Declares a role: identity, goals, domains, and (nested) LLM/memory config.
@RoleSpec(
name = "Researcher",
description = "Answers questions with citations from a local corpus.",
llm = @LLMSpec(provider = LLMSpec.Provider.OPENAI, model = "gpt-4o-mini", temperature = 0.2f))
public class ResearchRole extends Role { /* @ActionSpec methods … */ }@AgentSpec — Partial
Type-level agent metadata and partial declarative configuration. The runtime
consumes members including roles (as a fallback), maxContextTokens, and
toolCallFilter, but it does not consume the nested llm member. There is no
name (derived from the class) and no role string.
package com.example.tnsai.docs;
import com.tnsai.agents.Agent;
import com.tnsai.annotations.AgentSpec;
import com.tnsai.llm.LLMClient;
import com.tnsai.llm.providers.AnthropicClient;
import com.tnsai.roles.Role;
import java.util.List;
@AgentSpec(description = "A helpful research assistant")
public final class AnnotatedAgentExample extends Agent {
@Override
protected LLMClient getLLM() {
return new AnthropicClient("claude-sonnet-4-20250514");
}
@Override
protected List<Role> getRoles() {
return List.of(Role.create(QuickstartBuilderExample.AssistantRole.class));
}
public static void main(String[] args) {
var agent = new AnnotatedAgentExample();
agent.start();
String answer = agent.chat("What is quantum computing?");
System.out.println(answer);
}
}Direct subclasses must implement the abstract getRoles() method. A non-empty
result takes precedence over @AgentSpec.roles; an empty result allows the
annotation's public-no-arg role classes to supply the fallback. Provide the
agent-level LLM through getLLM() or AgentBuilder.llm(...).
toolCallFilter is Class<? extends ToolCallFilter>. The shipped default is
AllowAllToolFilter — that class is the "not set" sentinel, not an allow-list.
There is no AllowlistFilter / AllowlistToolFilter type. A real filter is
your own ToolCallFilter with a public no-arg constructor.
@ActionSpec — Wired
Marks a method as an agent action/tool, with type, description, and behavioural constraints.
@ActionSpec(type = ActionType.LOCAL, description = "Look up an order",
mustAlways = {"validate the order id"})
public Order lookup(String orderId) { … }@State — Wired
Marks a planner field on a Role. The planner reads those fields as a
Map to evaluate @Goal conditions and action pre/postconditions. This is
not com.tnsai.models.agent.Belief and is not BDI extraction.
@Contract — Wired
Design-by-Contract pre/postconditions and invariants (JEXL), enforced around the action. See Contracts.
Tools
@Tool / @ToolParam — Wired
Expose a POJO method (and its parameters) to the LLM as a callable tool. @Tool carries
requiresConfirmation and keywords, which the agent's approval gate (AGENT-V006) reads.
public final class PaymentTools {
@Tool(description = "Send a wire transfer", requiresConfirmation = true)
public String wire(@ToolParam("recipient") String to, @ToolParam("amount") double amount) { … }
}TnsAI 0.14.0 (TnsAI@a070d674, TAN-3411) fails registration when a
parameter has no @ToolParam(name) and javac emitted argN. The
positional @ToolParam("recipient") form above is already safe.
timeoutMs ships in Maven Central 0.14.1 as an eighth @Tool member
(@since 0.14.0; PR #164
/ TAN-2958).
A positive value is one
wall-clock budget for the full POJO dispatch, including idempotency work;
0 keeps the enclosing agent policy. Expiry is retryable
ToolTimeoutException. Interruption is best-effort
(TAN-4387).
Dynamic tools and MCP server deadlines are out of scope. See
Custom Tools.
@ToolExample — Nested-wired
Few-shot examples for a tool; read from @ActionSpec.examples().
@Idempotent — Wired
Marks an action safe to retry; consulted by the retry/fallback layer.
LLM configuration
@LLMSpec — Nested partial
@LLMSpec has @Target({}), so it is valid only as a member of another
annotation. @RoleSpec(llm = …) consumes provider, model, temperature,
maxTokens, and topP for the role-level client. frequencyPenalty,
presencePenalty, apiKeyEnv, endpoint, timeoutMs, and streaming are
export metadata only; fallbackModel and systemPrompt are currently unused.
provider is LLMSpec.Provider, not a String; that enum is not the
LLMClientFactory provider-name inventory.
@AgentSpec(llm = …) is also syntactically valid, but the agent initializer
does not consume it today. Use an agent's getLLM() override or
AgentBuilder.llm(...). The older type-level @LLM was removed (see below).
Both paragraphs describe the core agent initializer. The SCOP bridge resolves
separately and does read the agent tier, as well as endpoint and apiKeyEnv, when
it builds an LLMConfiguration — and an external configuration source can override
any of them per agent. See
External LLM Configuration.
@LLMParam / @LLMParams — Wired
Bind action parameters to LLM-extracted values.
Memory & retrieval
@Memory / @VectorMemory — Wired / Partial
Configure the agent's memory store. Read from the agent class only — on a Role these are
introspection/export metadata and do not change memory behaviour. @VectorMemory.provider has no
provider SPI lookup yet: inmemory uses the base store with TF-IDF search, and every other value
falls back to that same store after logging a notice. @Memory.vector() has no runtime consumer at
all.
@MemorySpec — Nested-wired
Memory config nested in @AgentSpec(memory = …); also available programmatically as
MemoryConfig.builder() via AgentBuilder.memoryConfig(...).
@KnowledgeSource / @KnowledgeSources — Wired
Declares the corpora a Role retrieves from. All six fields are honoured. It
describes ingestion only; how documents are searched is @Retrieval's. FILE
is the one bundled loader — URL, DATABASE and MEMORY are SourceLoader
SPI extension points an optional module registers against.
A source whose type has no installed loader is skipped with a warning. The Role still binds from whichever sources did load. Binding fails only when every enabled source is unloadable. A missing loader costs part of the corpus; it does not fail dispatch by itself.
@Retrieval — Wired
Retrieval tuning. All 21 fields are honoured and all 8 strategies have a runtime
path. queryParam selects a named action argument, while navigatorModel
selects the installed TreeNavigator for Strategy.REASONING. GRAPH resolves
the bundled FILE-corpus, KnowledgeTools, or Neo4j adapters,
while an explicit application provider overrides the framework defaults.
Reranking, query expansion (including MULTI_QUERY), and REASONING resolve
model SPIs that TnsAI deliberately ships no provider for; the framework side
(resolution, validation, capping, and error classification) is complete.
On Maven Central 0.14.1, an unservable rerankerModel or
queryExpansionModel fails at dispatch, inside the span
@Retrieval.onFailure guards. CONTINUE can then emit an ungrounded
answer. GRAPH already treats a missing provider as a configuration
error above that guard.
Since 0.15.0 (TnsAI@cb14410d,
PR #198 /
TAN-5887)
those two model names resolve when Role.create establishes the
retrieval configuration. An unservable name is a wiring-time
configuration error and is not reachable through onFailure. Failures
a provider raises while ranking or expanding still follow
onFailure. Roles with no effective @Retrieval, and declarations
that do not ask for rerank or expansion, do not load those provider
graphs. To inspect what resolved without throwing, see
RAG diagnostics
(RagDiagnostics, @since 0.15.0).
Guardrails & safety
@InputGuardrail / @OutputGuardrail — Wired
Validate/transform input before, and output after, an action. These annotations
are not the supervisor Guardrail interface and not the quality tracing
Guardrail SPI — see Guardrails.
@Security — Wired
Permission checks and sandboxing, enforced by SecurityEnforcer.
@ApprovalRequired — Wired
Requires human approval before an action runs (raises ApprovalRequiredException).
Resilience & observability
@Resilience — Partial
Umbrella resilience policy. Retry and timeout are enforced today; circuit-breaker,
rate-limit, and bulkhead fields are scaffolded for a later release. The builder counterpart
is RoleBuilder.resilience(ResilienceConfig…).
@Traced / @Metered — Wired
Tracing and metrics decorators around actions.
@Fallback — Wired
Declares a fallback method, resolved by FallbackResolver.
Lifecycle, events & coordination
@Lifecycle — Wired
Lifecycle phase hooks.
@EventHandler / @EventEmitter — Wired / Scaffold
@EventHandler methods are dispatched by EventHandlerProcessor. @EventEmitter is not yet wired.
@Coordination — Partial
Multi-agent coordination; only the nested negotiation() configuration is honoured today.
@Communication / @CommunicationStyle — Wired
Agent communication style, tone, and languages.
Identity
@DIDSpec — Nested-wired
W3C Decentralised Identifier config, nested in @AgentSpec(did = …).
@GroupMember — Nested-wired
Group membership, nested in @AgentSpec(groups = …).
Scaffold & being-consolidated
These exist but have no runtime effect yet (wiring planned) — don't rely on them:
@Norm / @Norms (deontic logic), @EvalMetric (custom evaluation metrics),
@QualityGate (release gates), @AuditLog (declarative audit), @OutputFormatSpec
(prettyPrint/schema not yet honoured).
Recently consolidated
During the 0.11.x annotation cleanup, 23 unwired annotations were removed in favour of
their working counterparts. 0.14.0 continues the same delete-don't-deprecate
policy for @Param. If you were using any of these, switch to the replacement:
| Removed | Use instead |
|---|---|
@Param (removed in 0.14.0) | the Java parameter name (-parameters); @ToolParam / @LLMParam if you need a live annotation |
@LLM (type-level) | @LLMSpec nested in @RoleSpec/@AgentSpec |
@RateLimited | @Resilience(rateLimit = …) |
@OnConnect / @OnDisconnect / @OnMessage | the Channel interface methods |
@FSMState / @FSMTransition / @FSMStates / @FSMTransitions | StateMachine.builder() |
@SystemPrompt | @RoleSpec.description (or @LLMSpec.systemPrompt) |
@ChannelSpec | the Channel interface |
@Pipeline / @PipelineStep | PipelineBuilder |
@RequiresPairing | @Security |
@ContextCompaction, @SlashCommand, @WorkspaceSpec, @Property, @ConfigProperty, @Trigger, @Delegate, @Sanitize, @ContentFilter | removed — no runtime consumer existed |
Each removal is a ### Removed entry in the Changelog with the rationale.
See also
- Semantic Annotation Framework — field tables and usage examples
- Contracts —
@ContractDesign-by-Contract - Validation — build-time agent validators
- Changelog — per-release breaking changes & migration notes
Semantic Annotation Framework
Use this page as an annotation lookup and index. Topic pages remain the teaching source for complete declarative/programmatic examples, precedence, and field status. The first parity pilots are RAG and Memory; later topic conversions should replace duplicated teaching prose here with links in the same way.
Tool Catalog Reference
Next Page