Regression Tests for kagent Agents with agentevals A developer built kagent-agentevals, an open-source tool that converts kagent session records into the trajectory format scored by LangChain's agentevals, plus a golden-suite runner that exits non-zero when an agent's behavior changes. The converter addresses a key mismatch: kagent stores agent activity as Google ADK events, where human-in-the-loop confirmation round-trips carry the agent's own function calls and results under a user content role, so naive role mapping misattributes tool calls to the person and corrupts trajectory comparisons. The tool also adds a summary view that explains why each event was dropped, since ADK serializes roughly forty null optional fields per event. Originally published at webofmike.com https://webofmike.com/kagent-trajectory-evals/?utm source=devto&utm medium=syndication&utm campaign=kagent-trajectory-evals on 2026-09-25. The demo repo and every command in it were run before publishing. An AI agent that stops calling its tools does not throw an error. It answers from the model's memory, confidently and plausibly, and the output still looks fine in the UI. I wanted a regression test that catches that, so I wrote kagent-agentevals https://github.com/themsquared/kagent-agentevals : a converter from kagent https://kagent.dev/ session records into the trajectory format agentevals https://github.com/langchain-ai/agentevals scores, plus a golden-suite runner that exits non-zero when an agent's behavior changes. The conversion is where the work turned out to be. agentevals wants a flat list of OpenAI-format chat messages. kagent records what its agents do as Google ADK https://google.github.io/adk-docs/ events. Getting from one to the other is not a field rename, and three of the reasons only showed up when I ran it against real sessions instead of reading the schema. kagent writes one row per ADK event, with the event JSON in event.data . A single event carrying a tool call looks like this: {"author": "github assistant", "invocation id": "e-c51ee408-...", "partial": null, "content": {"role": "model", "parts": {"function call": {"id": "toolu 01...", "name": "search users", "args": {"query": "themsquared"}}} }} That is the readable version. ADK serializes every optional field, so the actual row has around forty keys set to null around the four that matter. Dumping a session's raw events to a terminal is unusable, which is why the first thing the tool grew was a view that accounts for each event and says why anything was dropped: kagent-evals extract