Major Features
- Spring AI 2.0 integration: New set of Koog starters for Spring Boot 4+ / Spring AI 2.0 (KG-851, #2149)
- Spring WebClient support: Added Spring
WebClientas aKoogHttpClientimplementation, and removed@Experimentalannotations from the now-stable HTTP client APIs/modules (KG-820, #2065) - Explicit model resolution via
DynamicPromptExecutor: NewPromptExecutorsubclass that exposes model resolution (resolveModel) as an explicit step before LLM dispatch, so decorators likeContextualPromptExecutorknow whichLLModelwill be used.MultiLLMPromptExecutorandRoutingLLMPromptExecutormoved fallback logic intoresolveModel; existing executors are unaffected (#2081) - Non-text content in tool results: Widened
Message.Tool.Result.partsfromList<ContentPart.Text>toList<ContentPart>, allowing tools to return images and files alongside text. Anthropic, OpenAI, and Gemini clients handle the new content types; unsupported API paths throw a clear error (#1852) CliAIAgentwrapper: IntroducedCliAIAgent, anAIAgentthat calls another CLI agent (e.g. claude, codex) under the hood and can also be used as a graph node via.asNode()(#1413)- Amazon Bedrock AgentCore Memory auto-discovery: Added auto-discovery for Amazon Bedrock AgentCore
LongTermMemory(#2003) - Anthropic Claude Fable 5: Added support for the newly released Anthropic Claude Fable 5 model (#2130)
Improvements
- Cache control on all message parts: Introduced the ability to add
cacheControlto allMessagePartobjects, including tool results andResponsePart(#2152) freshHistoryparameter for subgraphs: AddedfreshHistory: Boolean = falsetoAIAgentSubgraph, allsubgraph()DSL overloads, allsubgraphWithTask()overloads, andsetupSubgraphWithTask(). Whentrue, the subgraph starts with an empty conversation history and discards it upon completion — useful for optimizable subgraphs that should reason independently (#1889)- Strategy input on
StrategyStartingContext: Added aninput: Any?field (mirroringresult: Any?onStrategyCompletedContext), so features can see what the agent was invoked with before the strategy starts (#2128) - New Gemini profiles: Added
Gemini3_1Pro_Preview,Gemini3_1FlashLite_Preview,Gemini3_1FlashLite, andGemini3_5Flashprofiles (#2076)
Bug Fixes
- Spring AI 2.0
ClassCastException:SpringAiLLMClientV2 now useschatModel.options.mutate()to obtain a concrete-typed options builder, avoiding aClassCastExceptionthrown by Spring AI 2.0.0 when passing a genericChatOptions. Added an integration test suite for the V2 client across OpenAI, Google, and Anthropic (#2155) MessageTokenizerstorage key conflict: Renamed theMessageTokenizerstorage key fromagents-features-tracingtoagents-features-message-tokenizer, fixing a runtime exception when the Tracing feature is also installed (#2143, #2144)- Generics preserved in
decodeFromJSONElement:JacksonSerializer.decodeFromJSONElementnow passes the fullJavaTypetotreeToValue, so parameterized types (e.g.List<Person>) no longer deserialize elements asMap(#2115, #2116) - Double-encoded tool-call arguments: Emit
Tool.Call.argsverbatim in OpenAI-compatible request paths (Chat Completions and Responses API) instead of re-encoding them, fixing400errors on strict backends like DashScope / Qwen (#2095, #2096) @Contextualproperties in JSON schema: Added aSerialKind.CONTEXTUALbranch toGenericJsonSchemaGeneratorsoexecuteStructuredno longer crashes on@Contextualproperties (e.g.java.util.UUID); resolves the contextual serializer or throws a descriptive error (#1486, #1875)- Sealed type outputs in
subgraphWithTask: The schema converter now prefersoneOf/anyOfwhen present andFinishToolgenerates its schema with the polymorphic discriminator enabled, sosubgraphWithTask<Input, SealedOutput>advertises and decodes sealed results correctly (#1941, #2013) - Anthropic enum serialization: Dropped an incorrect
.lowercase()call inAnthropicLLMClientenum serialization (#2020, #2099) - Streaming tool-call fragmentation:
StreamFrameFlowBuilder.emitToolCallDelta()now treats a repeated tool-callidas a continuation rather than a new tool call, so OpenAI-compatible providers that repeat the sameidper chunk no longer fragment one tool call into multiple prematureToolCallCompleteframes (#2002, #2052) AIAgentGraphContext.fork: Fixed forking of the agent graph context (#1916, #2083)- Bedrock Nova empty system prompt: Added a guard for Bedrock Nova's empty system prompt array (#2089, #2090)
- Multiple tool calls in
LiteRTLLMClient: Support multiple tool calls per response (#2073) - Nullable collections in OpenAI JSON schema:
OpenAIStandardJsonSchemaGeneratornow emitsanyOffor nullableList<X>?fields instead of{"type": ["array", "null"]}, which GPT-5-family strict mode rejects (#1930, #1943)
Breaking Changes in Beta modules
- Removed
PromptAugmenter.SECTION_SEPARATOR(#2074)
Build & CI
- ABI validation: Enabled Kotlin's built-in ABI validation to catch breaking public-API changes before merge; beta modules are excluded automatically, and
./gradlew checkLegacyAbiruns in CI (#2082) - Lower Android minSdk: Decreased Android
minSdkfrom 35 to 23 to cover more devices (#2059, #2053)
Tests
- Long-term memory & auto-discovery: Refactored AgentCore long-term memory integration tests and added an auto-discovery strategies test (#920, #2092)
- Integration checks: Replaced a deprecated Google model, added DeepSeek, ACP message conversion, and metadata retrieval tests plus nullable tool schema support, and fixed the Ollama test run (#2075)
- Message-part round-trips: Added provider round-trip coverage for the redesigned message parts (#2085)
Examples
- DataStore settings: Unified the DataStore-based settings implementation across platforms, adding Okio-backed DataStore support on the web target (#1608)
Documentation
- Beta modules: Added beta-module descriptions and versioning notes, updated after 1.0.0 (#2077)
koog-agents-additions: Documented thekoog-agents-additionsdependency in the Readme and Quickstart (#2086, #2087, #2091)
Deprecations
Gemini 3 Pro Previewis no longer supported; useGemini3_1Pro_Previewinstead (#2076)