feat(viz): agent_runs_timeline helpers — pure filter/sort/format
Issue 0118. Pure helpers in fn_viz::timeline namespace, free of ImGui: - passes_filter / filter_and_sort (multi-select app + status + since_ts) - format_duration (running | Ns | MmSSs | HhMMm | —) - status_color_token / status_icon_id (status → fn_tokens index / TI_*) - app_chip_hex (app id → accent hex, fallback gray) Designed for unit-test isolation. Render layer (separate commit) consumes these via agent_runs_timeline.h. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
#pragma once
|
||||
//
|
||||
// agent_runs_timeline_helpers.h — pure helpers for the agent runs timeline panel.
|
||||
//
|
||||
// These helpers operate on AgentRun + TimelineFilter from agent_runs_timeline.h
|
||||
// but never call ImGui. They are unit-testable in isolation (see
|
||||
// cpp/tests/test_agent_runs_timeline.cpp).
|
||||
//
|
||||
// Issue 0118.
|
||||
|
||||
#include "viz/agent_runs_timeline.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cstdint>
|
||||
|
||||
namespace fn_viz {
|
||||
namespace timeline {
|
||||
|
||||
// True iff `r` matches every active sub-filter:
|
||||
// - filter.apps empty => any app
|
||||
// - filter.statuses empty => any status
|
||||
// - filter.since_ts == 0 => any started_at
|
||||
// All filters are AND-combined.
|
||||
bool passes_filter(const AgentRun& r, const TimelineFilter& f);
|
||||
|
||||
// Returns a copy of `runs` with `passes_filter` applied and sorted by
|
||||
// `started_at` descending (most recent first). Stable for runs with equal
|
||||
// started_at: ties broken by id ascending.
|
||||
std::vector<AgentRun> filter_and_sort(const std::vector<AgentRun>& runs,
|
||||
const TimelineFilter& f);
|
||||
|
||||
// Human-friendly duration string built from two unix-epoch SECOND timestamps.
|
||||
// - finished_at == 0 => "running"
|
||||
// - duration < 60s => "Ns" (e.g. "45s")
|
||||
// - duration < 3600s => "MmSs" (e.g. "12m05s")
|
||||
// - else => "HhMm" (e.g. "1h12m")
|
||||
// Negative or inverted (finished < started) => "—".
|
||||
std::string format_duration(int64_t started_at, int64_t finished_at);
|
||||
|
||||
// Returns a small integer color token (0..7) per status. The render layer
|
||||
// maps this token to an actual ImVec4 using fn_tokens::colors.
|
||||
//
|
||||
// pending -> 1 (info)
|
||||
// running -> 1 (info)
|
||||
// done -> 2 (success)
|
||||
// validated -> 2 (success)
|
||||
// merged -> 3 (primary)
|
||||
// aborted -> 5 (warning)
|
||||
// failed -> 6 (danger)
|
||||
// <other> -> 0 (neutral)
|
||||
int status_color_token(const std::string& status);
|
||||
|
||||
// Returns the TI_* macro string for the given status (already utf-8 encoded
|
||||
// 3-byte sequence). Render layer uses these directly in ImGui::Text.
|
||||
std::string status_icon_id(const std::string& status);
|
||||
|
||||
// Hardcoded chip color hex for known app ids. Returns "#5C5F66" (border_strong
|
||||
// / neutral gray) for unknown apps. Render layer parses the hex to ImVec4.
|
||||
std::string app_chip_hex(const std::string& app);
|
||||
|
||||
} // namespace timeline
|
||||
} // namespace fn_viz
|
||||
Reference in New Issue
Block a user