This is the first stable release of Koog. The 1.0 line establishes a long-term-supported surface across the framework: modules are split into stable and beta streams so production code can pin to APIs that won't break without a deprecation cycle, every previously deprecated API has been removed, and the graph DSL's node names are finalized. Alongside that, 1.0 lands a redesigned Java interop layer, decouples HTTP transport from Ktor, brings OpenTelemetry to Kotlin Multiplatform, and adds Anthropic prompt caching.
Major Features
Stable / Beta module split
- Modules now ship under two streams — stable and beta — so production code can pin to APIs that won't break without a deprecation cycle (#2011, #2000).
- All previously
@DeprecatedAPIs have been removed across event handlers, pipeline, agent/strategy/DSL, tools, persistence, executors, MCP, models, Spring autoconfig, and RAG utilities. The 1.0 line carries no deprecated surface (#2001).
Java interop, redesigned
- Uniform blocking API: All Java-facing entry points follow one pattern —
xxxBlockingin Kotlin, plainxxxfrom Java. ExplicitExecutorService/Executorparameters are gone; the agent's configured dispatcher is used instead (#2005). - Deadlock-free reentrant calls: Kotlin → Java → Kotlin call chains on a single-threaded executor no longer deadlock — the reentrant dispatch is detected and skipped (#1945, KG-750).
Graph DSL, finalized
- The
String-input nodes (nodeLLMRequest,nodeLLMRequestOnlyCallingTools,nodeLLMRequestWithoutTools,nodeLLMRequestForceOneTool,nodeLLMRequestMultipleChoices,nodeLLMRequestStreaming,nodeLLMRequestStructured) keep their original names; theMessage.User-input variants now use anodeLLMSendMessage*prefix. nodeExecuteToolsreturnsReceivedToolResultsdirectly — connect it tonodeLLMSendMessage/nodeLLMSendToolResults*instead of relying on the old auto-writeback behavior.- New
nodeLLMModerateText(name, moderatingModel, includeCurrentPrompt)accepts plainStringinput alongside the existingnodeLLMModerateMessage(Message.User)(#2035).
Memory and persistence
AIAgentStoragein checkpoints: Custom key-value data is now saved and restored alongside agent checkpoints; a newrunFromCheckpointAPI restores execution without requiring the Persistence feature (#1998, #1828).- Persistence for planner agents: Planner-based agents now support checkpoint/restore (#1786, KG-673).
- Amazon Bedrock AgentCore as
LongTermMemory: Managed vector-memory backend on Bedrock (#1855, KG-603). LongTermMemoryreliability: Storage errors no longer silently swallowed — newFailurePolicyplus a fix for double-ingestion during active sessions. Feature promoted from experimental (#1963).
HTTP transport, decoupled from Ktor
- Pluggable HTTP factory: LLM clients now take a
KoogHttpClient.Factoryinstead of a KtorHttpClient. A Ktor-backed default is auto-discovered on JVM/Android; users can plug in Java's HTTP client, OkHttp, or Spring'sRestClientwithout touching Koog internals (#2006, #1948, KG-821, KG-818). - Ollama on
KoogHttpClient: Ollama now routes streaming, headers, and endpoint config through the same abstraction as every other provider (#1993, KG-833).
OpenTelemetry on every target
- Multiplatform OpenTelemetry: Langfuse, Weave, and DataDog now run on every Koog target via a Ktor-based OTLP/JSON exporter, not just JVM (#1942, KG-785). Please note: the WasmJS target is not included for now (please see KG-846 for more details).
- Built-in metrics: Agents emit standard
gen_ai.client.token.usage,gen_ai.client.operation.duration, and a customgen_ai.client.tool.countmetric — plug straight into existing Prometheus/Grafana stacks (#1381, KG-136).
Anthropic prompt caching
- Automatic and explicit cache control: End-to-end caching support — automatic on requests, explicit breakpoints on messages, cache tokens in usage metrics. Cuts cost and latency for agents that re-send long system prompts (#1812, KG-707).
New providers
- LiteRT LLM client: New client for running Google's LiteRT models locally (#1980).
- Oracle Database
ChatHistoryProviderfor Oracle-standardized deployments (#1851, KG-772).
Improvements
- New models: Anthropic Opus 4.7 (#1861), OpenAI GPT-5.5 and GPT-5.5 Pro (#1913), DeepSeek V4 Flash and Pro (#1914), additional Bedrock models — Kimi K 2.5, MiniMax 2.5, Gemma 3, GPT OSS (#1902), and Ollama gpt-oss / qwen3.5 (#1292).
ToolCallMetadataside channel: Tools can now receive per-call context (trace IDs, correlation IDs, feature flags, the liveAIAgentContext) without polluting their LLM-visible argument schema. Features can contribute metadata viaAIAgentPipeline.provideToolCallMetadata, with caller-supplied values winning on key collision (#1886, #1777).- Planners moved to a dedicated module:
GOAPPlannerandSimpleLLMPlannernow live in a separateagents:agents-plannersmodule, and a simplerAIAgentPlannerStrategy.create(name, planner)factory replaces the old builder. Agents that don't use planning no longer pay the dependency cost (#1997). - MCP SDK upgrade with Streamable HTTP: MCP kotlin-sdk upgraded from 0.8.1 to 0.11.1; Streamable HTTP is now the primary transport for both MCP client and server (#1870, KG-792, KG-756, KG-755, KG-49).
RetrieveFactsFromHistoryextracted from AgentMemory: ThisHistoryCompressionStrategynow lives outside the AgentMemory feature so it can be used independently. The oldAgentMemoryfeature is removed in favor of the more capableLongTermMemory(#1927).- OpenTelemetry GenAI semantic conventions update: Aligned with the latest spec — content is carried via
gen_ai.input.messages/gen_ai.output.messagesattributes instead of deprecated per-message events; moderation results moved to a Koog custom attributekoog.moderation.result(#1967, KG-826). KoogClockmigration: Internal time APIs now use aKoogClockabstraction instead ofkotlin.time.Clock, enabling virtual-time testing and consistent clock behavior across platforms (#1925).- Minimum Java version raised to 17: Aligns the runtime requirement with documentation and modern toolchain expectations (#1931).
- Factory functions replace
invokeconstructors:AIAgent,AIAgentService,ToolRegistry,RollbackToolRegistry, andAIAgentPlannerStrategynow use top-level factory functions. Usage syntax (A(...)) is unchanged for normal callers (#1882). - Agent pipeline cleanup: Pipeline event contexts now expose the
AIAgentinstance directly instead of separateagentId/configfields; parameter order is harmonized across pipeline interfaces (#1991, KG-807).
Bug Fixes
Highlights below — see the 1.0.0-preview entry for the full per-PR list.
- Streaming hardening across providers (#1844, #1775, #1887, #1237, #1888, KG-811, #1884, #1878, #2012, #1978, #1868, #1865, #1866, #1369, KG-626): Ollama (
Flow invariant is violatedfrom cross-dispatcher emission,text/plainJSON responses, tool-call-before-text ordering), OpenAI (additional_propertiesleak underJsonNamingStrategy.SnakeCase, decode failures wrapped inLLMClientException, keepalive frames honored), Google (reasoning vs. plain text in streaming), and OpenRouter (tool calls during streaming) all now behave consistently end-to-end. - Error propagation through the pipeline (#1918, KG-815, #1548, KG-704, #2037, KG-845, #2024, KG-844): Pipeline failure hooks now receive the original
Throwableinstead of a stringifiedAIAgentError— fixes a latenterror.typemislabel in OpenTelemetry spans, and reflective tool failures surface the real exception message instead of"Unknown error".LLMCallFailedContext.eventTypenow reportsLLMCallFailed(wasLLMCallStarting);LLMCallFailedEvent/LLMStreaming/SubgraphExecutionare registered for remote event serialization. - OpenTelemetry stability (#1435, KG-675, #1969, KG-808, #1547, KG-703, #1856, #1850): Failed LLM requests no longer crash the feature — failures are signaled via span ERROR status and
error.type.SpanAdapter.onBeforeSpanFinishednow runs on fully populated spans, so Langfuse and Weave adapters see the same data the SDK exports. Langfuse trace-level attributes (langfuse.environment, etc.) are set on every span, not justinvoke_agent. The hardcoded JVM shutdown hook is gone — opt in viasetShutdownOnAgentClose(defaultfalse). - Persistence & subgraph correctness (#2044, #1971, #2039):
Persistence.runFromCheckpointskips tools that are no longer registered instead of throwing.subgraphWithTask/subtaskno longer drop tool results when the finish tool is called alongside other tools.PromptAugmenterimplementations (SystemPromptAugmenter,UserPromptAugmenter,AgentcorePromptAugmenter) append a newMessagePartto the existingMessageafter theMessage/MessagePartrefactor. - Tool / concurrency / security (#1883, #1881, #1871, #1965):
@Tool(customName = ...)is honored inToolSet.asTools().withPromptuses a write lock (was read lock — could race with concurrent prompt mutations). Anthropic API key is masked in Spring Boot autoconfiguration logs (security fix).
Breaking Changes
The 1.0 release is the stable baseline. Highlights below — for the full per-API list (constructor signatures, parameter renames, removed members), see the 1.0.0-preview entry.
- All
@DeprecatedAPIs removed (#2001): no deprecated members survive into 1.0. Includes a typo-spelling fixPersistency*→Persistence*across the storage providers (update imports). OldAIAgentPipeline/AIAgentPipelineImplare gone — useAIAgentPipelineAPI/AIAgentGraphPipeline/AIAgentPlannerPipeline. Retired models:AnthropicModels.Haiku_3,BedrockModels.AnthropicClaude3Haiku, and deprecated Google / DeepSeek entries. Companioninvokeconstructors forAIAgent,AIAgentService,ToolRegistry,RollbackToolRegistry,AIAgentPlannerStrategyare also gone (#1882) — normalA(...)syntax is unchanged. - Graph DSL node renames (#2035):
String-input nodes arenodeLLMRequest*/nodeLLMModerate*;Message.User-input variants arenodeLLMSendMessage*/nodeLLMSendToolResults*.nodeExecuteToolsnow returnsReceivedToolResultsdirectly (previouslynodeExecuteToolsAndGetResults); the old auto-writebacknodeExecuteToolsis removed. - Java blocking API redesign (#2005): uniform
xxxBlockingin Kotlin, plainxxxfrom Java via@JvmName, so most Java source code requires no changes.ExecutorService/Executorparameters are removed from blocking wrappers — the agent's own dispatcher is used instead (also dropsSubtaskBuilder.withExecutorService()and theexecutorServiceproperty). Renames coverAIAgent.javaNonSuspendRun→runBlocking,FeatureMessageProcessor.javaNonSuspend*→*Blocking,AIAgentService/PromptExecutor/LLMClientJava overloads →*Blocking,NonSuspendAIAgentStrategy→AIAgentStrategyBlocking,NonSuspendAIAgentFunctionalStrategy→AIAgentFunctionalStrategyBlocking. - HTTP transport decoupled from Ktor (#2006): LLM client constructors and
PromptExecutor.builder().{openAI, anthropic, google, deepseek, mistral, ollama, openRouter, dashscope}(...)no longer accept a KtorHttpClient— pass aKoogHttpClient.Factoryinstead, or omit for the auto-discovered default.prompt-executor-llms-allno longer leaks Ktor types transitively (depend onhttp-client-ktordirectly if you usedKtorKoogHttpClient). Java synthetic classSimplePromptExecutorsKtis renamed toSimplePromptExecutors.KoogHttpClientimplementations must implement the newlines()method for non-SSE line streaming and accept per-requestheadersparameters (#1993, KG-833);OllamaClient.baseUrlproperty removed — endpoint configuration is delegated to the suppliedKoogHttpClient. - OpenTelemetry Multiplatform migration (#1942, KG-785, #1967, KG-826):
addSpanExporter,addMetricExporter,addMetricFilterare now JVM-only extensions onOpenTelemetryConfigJvm(JVM users must update imports).addResourceAttributessignature changes fromio.opentelemetry.api.common.AttributestoMap<String, Any>. TheSpanEndStatuswrapper is removed — useStatusDatadirectly. Theai.koog.agents.features.opentelemetry.eventpackage and all event APIs onGenAIAgentSpan(events,addEvent,addEvents,removeEvent) are removed; thegen_ai.systemattribute andmoderation.resultspan event are no longer emitted. - Planners moved to a new module (#1997): GOAP and LLM-based planner usage requires an explicit
agents:agents-plannersdependency.AIAgentPlannerandJavaAIAgentPlannergain two abstract methods (initializeState,provideOutput);AIAgentPlannerStrategy.builder()/.goap()are removed in favor ofAIAgentPlannerStrategy(name, planner)/.create(name, planner). - Memory & persistence API changes:
AgentMemoryfeature removed — useLongTermMemoryinstead;RetrieveFactsFromHistorymoved out ofagents-features-memory(#1927).LongTermMemoryrenames:QueryExtractor→SearchQueryProvider,ExtractionStrategy→DocumentExtractor,IngestionTimingremoved (#1963).AIAgentStorage:AIAgentStorageKeyequality is now name-based; no-arg constructor replaced byAIAgentStorage(serializer);toMap()removed (usetoSerializedMap()/putAll(other));runFromCheckpoint'sagentInputrenamed toinput(#1998).AgentCheckpointDatafieldsnodePath,lastInput,lastOutputremoved — they now live insideproperties: JSONObject(#1786). Promptclass moved out ofdsl(#2022):ai.koog.prompt.dsl.Prompt→ai.koog.prompt.Prompt. Theprompt { ... }DSL builder stays inai.koog.prompt.dsl— only the type import changes.KoogClockreplaceskotlin.time.Clock(#1925) in all APIs that previously took aClockparameter.- Anthropic prompt caching: deprecated
usermessage builders removed to make room for thecacheControlvariant (#1812). - Minimum Java version: 17 (#1931).
- Dependency ABI cleanup (#2007):
oshai.kotlin.loggingno longer in:prompt-executor-clientspublic API (consumers must add their ownimplementation(libs.oshai.kotlin.logging));oshai-loggingupgraded7.0.7→8.0.01;ktor.server.sseno longer transitively exposed by:agents-features-tokenizer/:agents-features-trace;android.useAndroidX=trueis now required.