Migration
TnsAI is pre-1.0, so the public API can shift between minor versions. The current published Maven Central release is listed on Installation. The framework deliberately does not ship long-lived @Deprecated shims — when a replacement lands, the old surface goes in the same release. That means every upgrade is potentially a small surgical step rather than a sprawling deprecation cleanup, but it also means you have to read the right release notes to know what to change.
Where the migration steps live
Each release's CHANGELOG entry includes a Migration subsection whenever consumers need to do something other than bump the version. So the canonical guide for moving from version X to Y is every CHANGELOG entry strictly between X (exclusive) and Y (inclusive).
→ Changelog has the full list, newest first.
This page is a roadmap: it points to the entries that contain non-trivial breaking changes so you don't have to read the entire changelog when planning an upgrade.
Releases that require active migration
Only release entries where ignoring the steps would actually break consumer code are listed here. Patch releases that touch internals only are omitted.
Maven groupId io.github.tansuasici → dev.tnsai
Coordinates move to the tnsai.dev namespace. Artifact IDs stay. Java packages (com.tnsai.*) stay. Versions already on Maven Central under io.github.tansuasici (through 0.15.0) keep resolving as real artifacts. 0.15.1 is the handover: on the old groupId it is a relocation POM, so bumping to it follows to dev.tnsai with a Maven warning. Bumping to 0.15.0 instead resolves a real artifact and stays on the retired coordinate.
OpenRewrite recipe IDs io.github.tansuasici.rewrite.UpgradeTnsAI_* do not change.
- Automated path:
mvn rewrite:runwithdev.tnsai.rewrite.ChangeMavenGroupId(thetnsai-rewritemodule). - Manual path: replace
<groupId>io.github.tansuasici</groupId>(and the Gradleio.github.tansuasici:prefix) withdev.tnsai.
0.14.0 — @Param deleted
TnsAI 0.14.0 removes @com.tnsai.annotations.Param. The annotation shipped in Maven Central 0.13.0 and never had a runtime reader. ActionDiscovery.discoverParameters builds every ParamSpec from Parameter.getName() under the -parameters compiler flag, so an action's LLM-visible name has always been the Java parameter name. A mismatch with @Param(name = "q") String query silently resolved to query.
@ToolParam and @LLMParam are different, live annotations and are untouched.
- Automated path:
mvn rewrite:runwithio.github.tansuasici.rewrite.UpgradeTnsAI_0_14_0(thetnsai-rewritemodule). It deletes@Paramusages only. - Manual path: delete every
@Paramusage. Parameter names and types continue to come from the method signature, so nothing else changes.-parametersis already set by the parent POM. - See Changelog → 0.14.0 for the full entry (auto-synced from the framework CHANGELOG).
This shipped in 0.14.0 on Maven Central.
0.13.0 — declarative RAG starts taking effect, and @KnowledgeSource narrows to ingestion
The largest breaking release so far (21 entries), and most of it is behavioural: @Retrieval members that were accepted and then silently discarded are now enforced. Your code still compiles — it just starts doing what the declaration always said.
Read your @Retrieval declarations before upgrading. rerank, cache/cacheTTL, onFailure, queryExpansion, deduplicate, contextWindow/includeSpec and the GRAPH/HIERARCHICAL/TEMPORAL strategies were inert; they now change retrieval behaviour. Two specifics worth knowing:
cachedefaults totruewith a 300s TTL, so caching switches on for every existing@Retrieval. Corpus changes are picked up on the next dispatch only if you callRoleRagBinding.invalidate(Class); otherwise entries clear by TTL or LRU. Setcache = falseto keep the previous behaviour.rerank,queryExpansionandstrategy = GRAPHresolve through SPI seams with no bundled provider. Enabling them without an add-on module now throws at dispatch instead of being ignored.
@KnowledgeSource is now ingestion-only — 17 members down to 6 (name, type, path, connection, query, enabled). The 11 removed members (provider, index, topK, minSimilarity, embeddingModel, dimensions, namespace, filter, cache, cacheTTL, priority) never had a reader, so deleting them changes nothing at runtime. Retrieval tuning belongs to @Retrieval, which removes the old ambiguity where both annotations declared topK/cache/cacheTTL with no rule for which wins.
KnowledgeType drops to FILE, URL, DATABASE, MEMORY, and the default moves from VECTOR_DB to FILE. VECTOR_DB, WEB_SEARCH and CACHE are removed with no replacement: a remote index is queried per request, which the ingest-time SourceLoader seam cannot express. Those belong behind RetrievalEngineProvider.
- Automated path:
mvn rewrite:runwithio.github.tansuasici.rewrite.UpgradeTnsAI_0_13_0(thetnsai-rewritemodule). 73 entries — 61 type moves from thecom.tnsai.quality.*andcom.tnsai.agents.groups.*consolidations, 11 attribute removals for the narrowed@KnowledgeSource, and one method rename (RoleRagBinding.evictForTesting→invalidate). Activate the recipe for the version you are moving to. - What the recipe cannot do: the behavioural changes above. A recipe could auto-insert
cache = falseand pin you to the old behaviour, which is the opposite of what you want to decide. It also does not migrate the removedKnowledgeTypevalues (no target to rewrite to). - If you implement
SourceLoader:load(...)and the optionalmetadata(...)hook now takecom.tnsai.rag.KnowledgeSourceConfiginstead of the@KnowledgeSourceannotation.KnowledgeSourceConfig's six components are name-for-name and type-for-type identical to the narrowed annotation's six members, so a body that readsname/type/path/connection/query/enabledcompiles unchanged and only the parameter type in the signature needs editing. If your loader read one of the 11 removed members —topK,provider,embeddingModeland the rest — that is a separate break to resolve; in practice a loader readspath/connection/query, not retrieval knobs. Not yet covered by the recipe. - See Changelog → 0.13.0 → Migration for the full entry.
0.12.0 — name collisions + 23 orphan annotations removed
Two simple-name collisions in core, plus the 0.11.1-era orphan-annotation
and @LLM removals bundled into the first release after 0.11.0.
-
The
com.tnsai.identity.AgentSpecrecord is renamed toAgentDescriptor. (The@AgentSpecannotation is a different type and is unchanged.) -
The
@com.tnsai.roles.annotations.RoleIdentityannotation is renamed to@RoleDeclaration. (The runtimecom.tnsai.models.role.RoleIdentityidentity class is unchanged.) -
Combined guide: 0.11 → 0.12 — removed list, newly active wiring, Config records, recipe.
-
Automated path:
mvn rewrite:runwithio.github.tansuasici.rewrite.UpgradeTnsAI_0_12_0(the two renames only). -
See Changelog → 0.12.0 → Migration for the full entry.
0.7.0 — Legacy Tool interface removed
Function-shape ToolMethod is now the only tool abstraction in the runtime. If your code still does class MyTool implements Tool, this is the breaking change to plan for.
- Migration paths: convert to a POJO with
@Tool-annotated methods (recommended), or build aDynamicToolMethoddirectly. - See Changelog → 0.7.0 → Migration for the exact replacement snippets.
0.6.0 — Tool interface metadata methods + ChatRequest.tools type changed
Removed the 12 metadata-discovery default methods (getCategory, getUsageExamples, etc.) and changed ChatRequest.getTools() from List<ToolDefinition> to List<Map<String, Object>> (JSON-Schema fragments).
- Custom-tool-catalog callers that built
ChatRequestdirectly must switch to the new map shape. - Direct
Toolimplementers can simply drop overrides of the removed metadata methods — they're no longer called. - See Changelog → 0.6.0 → Migration for before/after snippets.
0.5.7 — Legacy tool catalog removed from tnsai-tools
The 130+ extends AbstractTool classes were replaced by ~60 typed POJOs exposing ~190 @Tool-annotated methods. Most consumers already used AgentBuilder.toolPojos(...) and don't need to touch anything.
- Consumers still using
AgentBuilder.tool(Tool)keep working through the compatibility surface in this release. - See Changelog → 0.5.7 → Consumer migration.
0.5.0 — AgentState.READY renamed to RUNNING
Single-token rename. No deprecation shim: search-and-replace AgentState.READY → AgentState.RUNNING in your code.
Other 0.5.0 behaviour changes that can surface as silent breaks if your code depended on them:
Agent.chat()now throwsIllegalStateExceptionafter the agent has been stopped (was silent / undefined before).BridgeLLMClient.streamChat()now throwsLLMCapabilityException(was returning a single-element synthetic stream).BridgeLLMClient.chat()now throws typedLLMException(was rawRuntimeException).
See Changelog → 0.5.0 → Migration notes.
0.4.0 — Monorepo migration
Not a code break, but a coordinate break: the 11 separately-published modules consolidated under a single tnsai-bom. The recommended dependency shape is now to import the BOM once and depend on individual modules without <version>.
- See Changelog → 0.4.0 → For Consumers for the new dependency snippet.
When in doubt
If you're skipping multiple versions, walk forward one minor at a time and read the migration subsection of each entry. The deletions are intentionally aggressive — sleeping on the changelog for six months and trying to jump from 0.5 to 0.10 in one go is harder than four 30-minute upgrade sessions spread across releases.
For changes that aren't covered above but caused you grief, open a discussion on the framework repo — the entry will land here in the next release.