Koog 1.3 idioms, gotchas, and scaffolding skills for Kotlin agents on the JVM
72
91%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Low
Low-risk findings worth noting
Process steps in order. Do not skip ahead — but in any single migration only the steps that match the user's code will produce changes; the rest are no-ops the user can skim. Don't chase compile errors blind; start with Step 1 and work down.
JDK 17 is the minimum in 1.0 (#1931). Targeting 8/11 fails to compile.
kotlin {
jvmToolchain(17)
}Kotlin 2.3.10 is the recommended version. Android consumers must set android.useAndroidX=true in gradle.properties. Bump these before bumping the Koog dependency — otherwise the build fails on the toolchain check before you can read the API errors.
Proceed immediately to Step 2.
Change every ai.koog:* artifact to the current release. Don't leave mixed versions — pre-1.0 and 1.x do not interoperate. Koog publishes on two version lines and the umbrella's version does not exist for every module, so take each coordinate from rules/module-coordinates.md rather than applying one version string across the board.
If the codebase pulled Ktor types from Koog packages, that route was closed in 1.0 — add ai.koog:http-client-ktor:1.3.0 explicitly. Run ./gradlew dependencies | grep -i ktor if unsure.
Proceed immediately to Step 3.
AIAgent.invoke(...) → top-level AIAgent(...) factory (#1882). Call site reads the same; the resolution target changedGraphAIAgent / FunctionalAIAgent / PlannerAIAgent → top-level AIAgent(...) factoryAIAgentService.invoke(...), ToolRegistry.invoke(...), RollbackToolRegistry.invoke(...), AIAgentPlannerStrategy.invoke(...) → top-level functionsProceed immediately to Step 4.
If the codebase uses planners, add the new module:
implementation("ai.koog:agents-planner:1.3.0-beta")Then:
AIAgentPlannerStrategy.builder() and AIAgentPlannerStrategy.goap() → AIAgentPlannerStrategy(name, planner), Planners.goap(...), Planners.llmBased(...), Planners.llmBasedWithCritic(...)AIAgentPlanner / JavaAIAgentPlanner need new initializeState and provideOutput overridesProceed immediately to Step 5.
If the codebase uses the strategy { ... } DSL:
nodeLLMRequest*, nodeLLMModerateTextMessage.User-input nodes: nodeLLMSendMessage*, nodeLLMSendToolResults*, nodeLLMModerateMessagenodeExecuteTools() now returns ReceivedToolResults directly — the auto-writeback variant is gone. Chain explicitly to nodeLLMSendToolResults (Skill(skill: "author-strategy") covers the full chain)Compile-time errors will surface these; the fix is the rename, not a redesign.
Proceed immediately to Step 6.
If the codebase has Java consumers of Koog APIs:
xxx from Java, xxxBlocking from Kotlin — ExecutorService / Executor parameters were removed throughoutNonSuspendAIAgentStrategy → AIAgentStrategyBlockingNonSuspendAIAgentFunctionalStrategy → AIAgentFunctionalStrategyBlockingFeatureMessageProcessor.javaNonSuspend* → FeatureMessageProcessor.*BlockingProceed immediately to Step 7.
If the code constructs LLMClient instances directly:
LLMClient constructors now take KoogHttpClient.Factory, not a Ktor HttpClientSimplePromptExecutorsKt was renamed SimplePromptExecutors — update Java importsOllamaClient.baseUrl parameter removed — pass it via KoogHttpClient configurationFor default JVM use, simpleOpenAIExecutor(apiKey) (and its siblings) still resolve without a factory argument because the JVM auto-discovers one — code that uses only the simple executors usually doesn't need changes.
Proceed immediately to Step 8.
If the code installs the AgentMemory feature:
AgentMemory was removed. Install LongTermMemory instead — invoke Skill(skill: "manage-state") for the install stepsLongTermMemory: QueryExtractor → SearchQueryProvider; ExtractionStrategy → DocumentExtractor; IngestionTiming is goneRetrieveFactsFromHistory was extracted out of AgentMemory — now standalone in agents-coreProceed immediately to Step 9.
If the code installs OpenTelemetry:
ai.koog.agents.features.opentelemetry.feature.OpenTelemetryConfig; use its current membersaddResourceAttributes signature changed to Map<String, Any>SpanEndStatus → StatusDataai.koog.agents.features.opentelemetry.event package and event APIs on GenAIAgentSpan (events, addEvent, addEvents, removeEvent) were removed. Replace with span attributes (gen_ai.input.messages / gen_ai.output.messages)setShutdownOnAgentClose(true) shuts down telemetry on agent close; close the owning agent explicitlyProceed immediately to Step 10.
If the code uses persistence/checkpoints:
NoPersistencyStorageProvider with durable storage for crash recovery.AIAgentGraphPipeline for graph features.AIAgentPlannerPipeline for planner features.AIAgentPipelineAPI for shared pipeline contracts.AgentCheckpointData from ai.koog.agents.snapshot.feature.graphProperties.nodePath and graphProperties.lastOutput for graph checkpoints.plannerProperties for planner checkpoints.checkpointId, createdAt, version, message history and serialized storage.properties.lastInput payload shape.stateType and planType tokens to
the AIAgentPlanner base constructor; built-in SimpleLLMPlanner supplies both.agent.runFromCheckpoint(checkpoint) with
Persistence.runFromCheckpoint(agent, input, checkpoint).Skill(skill: "add-persistence") for durable providers and automatic restart.Snapshot, snapshot() and runFromSnapshot() examples with
the Persistence save/replay APIs.Skill(skill: "snapshot-and-restore") for forks.AIAgentStorageKey equality is now name-basedAIAgentStorage() no-arg constructor replaced by AIAgentStorage(serializer)AIAgentStorage.toMap() removedProceed immediately to Step 11.
ai.koog.prompt.dsl.Prompt → ai.koog.prompt.Prompt (#2022)prompt { ... } builder DSL stays in ai.koog.prompt.dsl. Imports for the builder don't change; imports for Prompt itself doProceed immediately to Step 12.
If the code passes a Clock to Koog APIs:
kotlin.time.Clock parameters replaced by KoogClock (#1925). Update test doubles too — KoogClock.System is the defaultProceed immediately to Step 13.
Check model references in the code:
AnthropicModels.Haiku_3 — removed; pick a current Anthropic entryBedrockModels.AnthropicClaude3Haiku — removedNew in 1.0 worth knowing: AnthropicModels.Opus_4_7, GPT-5.5/GPT-5.5 Pro, DeepSeek V4 Flash/Pro, Bedrock Kimi K 2.5 / MiniMax 2.5 / Gemma 3 / GPT OSS, Ollama gpt-oss / qwen3.5, LiteRT (local Google).
Proceed immediately to Step 14.
Run ./gradlew build. The earlier steps cover the structural changes; remaining errors are usually unrelated to migration (project-specific code paths). If a compile error still references a Koog symbol, re-check Steps 3–13 — the symbol was probably renamed in one of them.
Finish here.
.tessl-plugin
skills
add-observability
add-persistence
references
add-rag
add-structured-output
add-token-budgeting
add-tool
cache-llm-calls
define-prompt
domain-model-subtask-pipeline
references
enable-prompt-caching
handle-agent-events
manage-state
migrate-from-0-x
model-planner-subtasks
persist-chat-history
query-sql-from-agent
scaffold-agent
snapshot-and-restore
references
test-koog-agents
trace-agent-internals
use-agent-skills
references
use-attachments
use-cli-agents
use-functional-agent
use-llm-node-variants
use-planner
wire-a2a
wire-acp-server
wire-ktor-server
wire-mcp-server
wire-spring-boot