feat: Koog → Aigentic Platform run-publishing proof-of-concept#146
Open
nsmnds wants to merge 5 commits into
Open
feat: Koog → Aigentic Platform run-publishing proof-of-concept#146nsmnds wants to merge 5 commits into
nsmnds wants to merge 5 commits into
Conversation
Demonstrates that JetBrains Koog can publish its agent runs to the Aigentic Platform using the same `POST RunDto -> /gateway/runs` contract Aigentic uses. It installs Koog's public EventHandler hooks (`handleEvents`) to collect a run and POST a RunDto on completion, mirroring Aigentic's automatic `publishRun`. A test runs a real Koog agent (LLM mocked via `getMockExecutor`, platform mocked via a Ktor `MockEngine`) and asserts the RunDto posted to /gateway/runs. This is an isolated Gradle build (Kotlin 2.3.10) because Koog 1.0.0 is built with Kotlin 2.3.10 while the main project is on 2.1.10 and Kotlin metadata is not forward-compatible; it is not wired into the root build and does not affect `./gradlew build`.
Extends the proof-of-concept to cover the full Aigentic MessageDto union: UrlMessageDto and Base64MessageDto are mapped from Koog's MessagePart.Attachment (AttachmentContent.URL / Binary via asBase64()), and MimeTypeDto / StructuredOutputMessageDto are added to the contract DTOs. Documents the two compatibility caveats: Aigentic's MimeTypeDto is a fixed subset (5 image types + PDF) so unsupported Koog media (video/audio/other) is skipped, and structured output has no distinct Koog message type. Adds KoogRunMapperTest covering every supported type and the unsupported-mime skip.
Adds a structured request/response example (PDF invoice -> typed Invoice -> finished) using Koog's nodeLLMRequestStructured<T>, and shows the typed result is published to the Aigentic Platform as the run result (FinishedResultDto.response) plus the assistant JSON message. The exporter now uses the model's actual response text for the finished result, so structured output is captured faithfully. Documents Koog's first-class structured output API and how a PDF attachment feeds into a structured request.
Mirrors how an Aigentic structured-output agent publishes: the exporter detects a structured run from the agent's typed result (result !is String) and emits the final assistant message as StructuredOutputMessageDto (Model sender), sets FinishedResultDto.response to the structured JSON, and populates config.responseJsonSchema from the prompt schema when available. Wires a real PDF MessagePart.Attachment through a structured request so it is published as a Base64MessageDto (APPLICATION_PDF). The structured-output test now runs the full PDF-invoice -> typed Invoice -> finished flow and asserts the published RunDto matches the shape an equivalent Aigentic run would produce.
…ion) Mirrors Aigentic's MessageCategory assignment (seedInitialMessages): the exporter records the base config prompt size at agent start, then categorizes messages as SYSTEM_PROMPT / CONFIG_CONTEXT (config prompt) / RUN_CONTEXT (content before the first model turn) / EXECUTION (from the first assistant message on). An explicit metaInfo.metadata "aigentic.category" tag overrides the positional default, mirroring Aigentic choosing the category from the API used. Adds MessageCategoryTest for both signals and extends the structured PDF test to attach a reference image in the config prompt (CONFIG_CONTEXT) and the invoice PDF in the run (RUN_CONTEXT), asserting the published RunDto distinguishes them.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
Investigates whether JetBrains Koog can be made to publish its agent runs to the Aigentic Platform using the same contract Aigentic itself uses, and provides a working proof-of-concept.
Answer: yes — and no fork/patch of Koog is needed. This was verified against the real Koog
1.0.0source, not guessed.How Aigentic publishes a run (the contract we target)
After every run,
publishRun(src/core/.../agent/AgentExecutor.kt) makes a single authenticated request when aplatform { … }is configured:RunDto(src/platform/wirespec/gateway.ws) carriesstartedAt/finishedAt,config(task, model identifier, system prompt, tools, temperature…),result(Finished/Stuck/Fatal),messages[], andmodelRequests[](per-LLM-call token usage). Publishing is not runtime-specific — it is just "build aRunDtoand POST it".How the PoC mirrors it from Koog
Koog's
agents-features-event-handlerexposes the full lifecycle viahandleEvents { … }. A smallaigenticPlatform(name, secret, …)extension installs it, collects the run, and POSTs aRunDtoon completion — the Koog-side equivalent ofpublishRun:Hooks used:
onAgentStarting,onLLMCallStarting/onLLMCallCompleted(fullPrompt,LLModel, tool descriptors, theMessage.Assistantresponse + its token counts →modelRequests), andonAgentCompleted/onAgentExecutionFailed(→ Finished/Fatal result + POST).What's included
PlatformRunDto.kt— DTOs mirroringgateway.ws.KoogRunMapper.kt— maps KoogMessage/MessagePart/ToolDescriptor→ Aigentic DTOs.AigenticPlatformExporter.kt— theaigenticPlatform(...)EventHandler exporter.AigenticPlatformExporterTest.kt— runs a real Koog agent (LLM mocked viagetMockExecutor, platform mocked via KtorMockEngine) and asserts exactly oneRunDtoPOSTed to/gateway/runscontaining the system prompt, the assistant response, amodelRequestsentry, and aFinishedResultDto. ✅ passing../gradlew -p poc/koog-platform testImportant: why this is an isolated build
Koog
1.0.0is built with Kotlin 2.3.10; Aigentic is on Kotlin 2.1.10. Kotlin metadata is not forward-compatible, so the main (2.1.10) build cannot compile against Koog's artifacts. The PoC is therefore a standalone Gradle build underpoc/koog-platform/(its ownsettings.gradle.kts, Kotlin 2.3.10), is not wired into the root build, and does not affect./gradlew build.PlatformRunDto.ktreproduces the contract locally for the same reason.A production integration would reuse the Wirespec-generated
RunDto/Gatewayclient from the publishedcommunity.flock.aigentic:platformartifact (readable by a Kotlin ≥ 2.3 consumer) or align the two projects' Kotlin versions.See
poc/koog-platform/README.mdfor full details.Generated by Claude Code