AiAgentRunAction:实现逻辑与页面展示逻辑
对应源码:
AiAgentRunAction.java ·
summary.jelly ·
CodexLogFormat.java
一、数据结构定义
| 类 | 职责 | 关键字段 |
|---|---|---|
InvocationRecord | 一次 AI 调用的元数据,序列化进 build.xml | id(自增调用号)、agentType(agent 显示名)、model、exitCode(null = 未结束)、startedAt/completedAt |
EventView | Agent 运行过程解析出的一条事件(工具调用、AI 输出等) | category(assistant / tool_call / tool_result / thinking / system / error / raw)、content、toolInput / toolOutput |
AgentUsageStats | 一次调用的用量汇总 | input/output/cache/reasoning tokens、cost、duration、numTurns、toolCalls |
二、运行过程数据
运行期间的数据分两路存储,各司其职:
-
Agent 元数据 → build.xml
每次aiAgent步骤执行时,markStarted分配自增invocationId并追加一条InvocationRecord;结束时markCompleted回填exitCode和completedAtMillis。两者都显式调用run.save()立即落盘。
注意:prompt和commandLine刻意写空——可能含凭据明文,不允许序列化进 build.xml。 -
运行过程记录 → 构建目录下的 jsonl 文件
文件名ai-agent-stream-{invocationId}.jsonl(由getRawLogFile定位)。Agent CLI 进程的 stdout/stderr 逐行写入(AiAgentExecutor.AgentOutputHandler),写入前先脱敏 API Key。这个文件是后续页面展示的唯一数据源。
三、数据解析
核心思路:先从 build.xml 拿到「谁调用、哪一次」,再用它反查解析策略、定位过程文件。
getEvents(invocationId)
→ resolveHandler()
→ getInvocation(id) // 从 invocations 找到 InvocationRecord
→ inv.agentType(显示名,如 "Codex CLI")
→ 遍历 Jenkins.get().getDescriptorList(AiAgentTypeHandler.class)
→ displayName 匹配 → handler.newInstance()
→ handler.getLogFormat() // 如 CodexLogFormat / CursorLogFormat
→ AiAgentLogParser.parse(rawFile, format)
→ 逐行 JSON 解析 → 多级 fallback 分类 → 去重 + 合并 delta
→ List<EventView> // 交给 Jelly/前端渲染对话
要点:
agentType存的是显示名,反查依赖@Extension注解索引;索引缺失(如 IDE 增量编译)时 handler 为 null,页面退化为基础分类。getUsageStats()走同一条反查链,只是拿到的是handler.getStatsExtractor(),最终由AgentUsageStats.fromLogFile()返回 token/费用汇总。- 页面展示分两种模式:构建运行中由 JS 每 2s 调
doProgressiveEvents增量轮询(start/nextStart行号游标续传);构建结束后服务端全量解析直接渲染。
转载自 CSDN-专业IT技术社区
原文链接:https://blog.csdn.net/Light91011/article/details/164728933



