Koog 1.0 idioms, gotchas, and scaffolding skills for Kotlin agents on the JVM
86
88%
Does it follow best practices?
Impact
86%
1.86xAverage score across 45 eval scenarios
Advisory
Suggest reviewing before use
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 1.0.0 (or later). Don't leave mixed versions — pre-1.0 and 1.0 do not interoperate.
If the codebase pulled Ktor types from Koog packages, that route was closed in 1.0 — add ai.koog:http-client-ktor:1.0.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.0.0")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:
addSpanExporter, addMetricExporter, addMetricFilter) moved to OpenTelemetryConfigJvm — update importsaddResourceAttributes 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)Proceed immediately to Step 10.
If the code uses persistence/checkpoints:
Persistency* → Persistence*AIAgentPipeline / AIAgentPipelineImpl → AIAgentPipelineAPI + AIAgentGraphPipeline / AIAgentPlannerPipelineAgentCheckpointData shape changed — nodePath, lastInput, lastOutput moved inside properties: JSONObjectAIAgentStorageKey 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.
evals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10
scenario-11
scenario-12
scenario-13
scenario-14
scenario-15
scenario-16
scenario-17
scenario-18
scenario-19
scenario-20
scenario-21
scenario-22
scenario-23
scenario-24
scenario-25
scenario-26
scenario-27
scenario-28
scenario-29
scenario-30
scenario-31
scenario-32
scenario-33
scenario-34
scenario-35
scenario-36
scenario-37
scenario-38
scenario-39
scenario-40
scenario-41
scenario-42
scenario-43
scenario-44
scenario-45
skills
add-observability
add-persistence
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
test-koog-agents
trace-agent-internals
use-attachments
use-functional-agent
use-llm-node-variants
use-planner
wire-a2a
wire-acp-server
wire-ktor-server
wire-mcp-server
wire-spring-boot