@railtownai/railtracks-visualizer 0.0.69 → 0.0.71

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Categorical evaluator view: one card per categorical metric, with collapsible
3
+ * accordions per category label listing the agent nodes that received that label.
4
+ * Each node exposes Session Details / Visualizer call-to-actions (see NodeActions)
5
+ * and an inline toggle to reveal reasoning when present.
6
+ *
7
+ * Generic over any evaluator that produces categorical metrics. The built-in
8
+ * JudgeEvaluator passes its own title/icon; custom Evaluators fall back to neutral
9
+ * categorical branding.
10
+ */
11
+ import React from "react";
12
+ import type { LucideIcon } from "lucide-react";
13
+ import type { CategoricalMetric } from "../utils/categoricalAggregateTree";
14
+ export interface CategoricalAggregateViewProps {
15
+ metrics: CategoricalMetric[];
16
+ /** Heading shown above the cards. Defaults to a neutral categorical title. */
17
+ title?: string;
18
+ /** Icon shown on each metric card header. Defaults to a neutral tags icon. */
19
+ icon?: LucideIcon;
20
+ /** Text shown when there are no metrics. Defaults to a neutral message. */
21
+ emptyLabel?: string;
22
+ /** Opens the run for a node in the Session Details drawer. sessionId may be undefined for legacy evaluations. */
23
+ onAgentNodeClick?: (sessionId: string | undefined, nodeId: string) => void;
24
+ /** Opens the run for a node in the full Visualizer. */
25
+ onOpenVisualizer?: (sessionId: string | undefined, nodeId: string) => void;
26
+ }
27
+ export declare const CategoricalAggregateView: React.FC<CategoricalAggregateViewProps>;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Custom (numerical) evaluator view: one card per numerical metric, showing
3
+ * summary statistics (mean/min/max/median/std/runs) in the header and a collapsible
4
+ * list of the per-run values. Each value exposes Session Details / Visualizer
5
+ * call-to-actions (see NodeActions). Used for custom Evaluators that emit a
6
+ * `NumericalAggregate` (e.g. EndToEndLatencyEvaluator).
7
+ */
8
+ import React from "react";
9
+ import type { NumericalMetric } from "../utils/numericalAggregateTree";
10
+ export interface NumericalAggregateViewProps {
11
+ metrics: NumericalMetric[];
12
+ /** Opens the run for a node in the Session Details drawer. sessionId may be undefined for legacy evaluations. */
13
+ onAgentNodeClick?: (sessionId: string | undefined, nodeId: string) => void;
14
+ /** Opens the run for a node in the full Visualizer. */
15
+ onOpenVisualizer?: (sessionId: string | undefined, nodeId: string) => void;
16
+ }
17
+ export declare const NumericalAggregateView: React.FC<NumericalAggregateViewProps>;
@@ -2,6 +2,8 @@ import React from "react";
2
2
  import type { AgentRun } from "../../dto/AgentRun";
3
3
  import type { AgentRunNode } from "../../dto/AgentRunNode";
4
4
  import type { SessionListItem } from "../hooks/useSessions";
5
+ /** Wall-clock elapsed time across a node and all descendants (unix stamp times). */
6
+ export declare const getSubtreeWallClockSeconds: (nodeId: string, childrenMap: Map<string, string[]>, nodeMap: Map<string, AgentRunNode>) => number;
5
7
  /** Tool/agent failure is carried on the incoming edge's details.status (e.g. Failed), same as flow edges and session I/O. */
6
8
  export declare function isNodeFailureFromIncomingEdge(run: AgentRun, nodeId: string): boolean;
7
9
  export interface SelectedNodeInfo {
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Builds the categorical evaluator view model from aggregate_results.
3
+ *
4
+ * Generic over any evaluator that emits a CategoricalAggregate — the built-in
5
+ * JudgeEvaluator is the common case, but custom Evaluators that produce
6
+ * categorical metrics share the exact same shape and render through this path.
7
+ *
8
+ * Shape of the data (see sample.json -> JudgeEvaluator):
9
+ * - aggregate_results.roots -> CategoricalAggregate nodes (one per metric) with
10
+ * `categories`, `counts`, `most_common_label`, `least_common_label`, and `children`.
11
+ * - Each child id resolves (in aggregate_results.nodes) to a Base leaf result whose
12
+ * `value` is the category label string and `agent_data_id[0]` is the agent node id.
13
+ * - Judge reasoning (a Judge-specific enrichment) lives separately in metric_results
14
+ * as Base results named `JudgeReasoning/<metric>`, paired to a node by
15
+ * `agent_data_id[0]` + metric name. Custom evaluators have none; reasoning is then
16
+ * simply absent.
17
+ */
18
+ import type { EvaluationResultItem, EvaluationAgent } from "../../dto/Evaluation";
19
+ /** A single evaluated agent node under a category label. */
20
+ export interface CategoricalNodeRef {
21
+ nodeId: string;
22
+ /** Session that owns the node, when the evaluation carries session context. */
23
+ sessionId?: string;
24
+ /** Reasoning text for this node + metric, when available (Judge only). */
25
+ reasoning?: string;
26
+ }
27
+ /** One category label within a metric, with the nodes that received it. */
28
+ export interface CategoricalLabel {
29
+ labelName: string;
30
+ count: number;
31
+ nodes: CategoricalNodeRef[];
32
+ }
33
+ /** One categorical metric evaluated across all runs. */
34
+ export interface CategoricalMetric {
35
+ key: string;
36
+ metricName: string;
37
+ description?: string;
38
+ mostCommon?: string;
39
+ leastCommon?: string;
40
+ total: number;
41
+ labels: CategoricalLabel[];
42
+ }
43
+ type NodeMap = Record<string, unknown>;
44
+ type AgentLike = Pick<EvaluationAgent, "agent_name" | "agent_node_ids"> | {
45
+ agent_name: string;
46
+ agent_node_ids?: string[] | {
47
+ session_id: string;
48
+ agent_node_id: string;
49
+ }[];
50
+ };
51
+ export interface BuildCategoricalMetricsInput {
52
+ roots: string[];
53
+ nodes: NodeMap;
54
+ agents?: AgentLike[];
55
+ /** Full evaluator results (metric_results + aggregates) used to resolve reasoning. */
56
+ rawResults?: EvaluationResultItem[];
57
+ }
58
+ /** Build the categorical view model: one entry per categorical metric. */
59
+ export declare function buildCategoricalMetricsFromAggregate(input: BuildCategoricalMetricsInput): CategoricalMetric[];
60
+ export {};
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Builds the custom (numerical) evaluator view model from aggregate_results.
3
+ *
4
+ * Custom Evaluators (anything that isn't the built-in Judge/ToolUse/LLMInference)
5
+ * emit a `Numerical` metric and a `NumericalAggregate` aggregate node. Shape of the
6
+ * data (see custom_sample.json -> EndToEndLatencyEvaluator):
7
+ * - aggregate_results.roots -> NumericalAggregate nodes (one per metric) with
8
+ * `mean`, `minimum`, `maximum`, `median`, `std`, `values`, and `children`.
9
+ * - Each child id resolves (in aggregate_results.nodes) to a Base leaf result whose
10
+ * `value` is the per-run number and `agent_data_id[0]` is the agent node id.
11
+ *
12
+ * NOTE: this only handles the aggregate-tree shape. A custom evaluator that emits
13
+ * only `metric_results` with no `aggregate_results` is not yet rendered (deferred).
14
+ */
15
+ import type { EvaluationResultItem, EvaluationAgent } from "../../dto/Evaluation";
16
+ /** A single per-run leaf value for a numerical metric. */
17
+ export interface NumericalNodeRef {
18
+ nodeId: string;
19
+ /** Session that owns the node, when the evaluation carries session context. */
20
+ sessionId?: string;
21
+ value: number;
22
+ }
23
+ /** One numerical metric aggregated across all runs. */
24
+ export interface NumericalMetric {
25
+ key: string;
26
+ metricName: string;
27
+ description?: string;
28
+ mean?: number;
29
+ minimum?: number;
30
+ maximum?: number;
31
+ median?: number;
32
+ std?: number;
33
+ count: number;
34
+ nodes: NumericalNodeRef[];
35
+ }
36
+ type NodeMap = Record<string, unknown>;
37
+ type AgentLike = Pick<EvaluationAgent, "agent_name" | "agent_node_ids"> | {
38
+ agent_name: string;
39
+ agent_node_ids?: string[] | {
40
+ session_id: string;
41
+ agent_node_id: string;
42
+ }[];
43
+ };
44
+ export interface BuildNumericalMetricsInput {
45
+ roots: string[];
46
+ nodes: NodeMap;
47
+ agents?: AgentLike[];
48
+ /** Full evaluator results (metric_results + aggregates), used as a leaf-value fallback. */
49
+ rawResults?: EvaluationResultItem[];
50
+ }
51
+ /** Build the custom (numerical) evaluator view model: one entry per numerical metric. */
52
+ export declare function buildNumericalMetricsFromAggregate(input: BuildNumericalMetricsInput): NumericalMetric[];
53
+ export {};
@@ -0,0 +1,26 @@
1
+ import React from "react";
2
+ /** Error envelope produced by the Railtracks backend for a failed node/tool. */
3
+ export interface ToolErrorOutput {
4
+ /** Exception class name, e.g. "ValueError". */
5
+ type?: string;
6
+ /** Human-readable exception message. */
7
+ message?: string;
8
+ /** Full Python traceback string. */
9
+ traceback?: string;
10
+ }
11
+ /**
12
+ * Detect whether a tool/node output is an error envelope rather than a regular
13
+ * return value. Failed nodes serialize as `{ type, message, traceback }`; a
14
+ * traceback alone, or a `type` + `message` pair, is enough to treat it as an
15
+ * error. Returns the parsed error (with only string fields kept) or null.
16
+ */
17
+ export declare function parseErrorOutput(output: unknown): ToolErrorOutput | null;
18
+ export interface ErrorOutputProps {
19
+ error: ToolErrorOutput;
20
+ }
21
+ /**
22
+ * Renders a failed node/tool output distinctly from a regular returned object:
23
+ * a destructive-tinted surface with the exception type, message, and a
24
+ * collapsible traceback.
25
+ */
26
+ export declare const ErrorOutput: React.FC<ErrorOutputProps>;
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * DTOs for evaluation data from .railtracks/data/evaluations/*.json
3
3
  */
4
- /** Numeric metric definition (LLMMetric or ToolMetric) */
4
+ /** Numeric metric definition (LLMMetric, ToolMetric, or Numerical for custom evaluators) */
5
5
  export type EvaluationNumericMetricDefinition = {
6
6
  name: string;
7
- metric_type: "LLMMetric" | "ToolMetric";
7
+ metric_type: "LLMMetric" | "ToolMetric" | "Numerical";
8
8
  identifier: string;
9
9
  description: string | null;
10
10
  min_value: number | null;
@@ -58,7 +58,7 @@ export type EvaluationMetricReference = {
58
58
  identifier: string;
59
59
  min_value?: number;
60
60
  max_value?: number | null;
61
- metric_type?: "LLMMetric" | "ToolMetric" | "Categorical";
61
+ metric_type?: "LLMMetric" | "ToolMetric" | "Categorical" | "Numerical";
62
62
  description?: string | null;
63
63
  categories?: string[];
64
64
  };
@@ -111,8 +111,23 @@ export type EvaluationCategoricalAggregate = {
111
111
  counts: Record<string, number>;
112
112
  children?: string[];
113
113
  };
114
+ /** Numerical aggregate (mean/median/etc for a custom evaluator's numerical metric) */
115
+ export type EvaluationNumericalAggregate = {
116
+ type: "NumericalAggregate";
117
+ identifier?: string;
118
+ name?: string;
119
+ metric: EvaluationMetricReference;
120
+ values: number[];
121
+ mean: number;
122
+ minimum: number;
123
+ maximum: number;
124
+ median: number;
125
+ std: number;
126
+ mode: number;
127
+ children?: string[];
128
+ };
114
129
  /** Union of possible items in evaluator results array */
115
- export type EvaluationResultItem = EvaluationLLMResult | EvaluationToolResult | EvaluationBaseResult | EvaluationLLMInferenceAggregate | EvaluationToolAggregate | EvaluationCategoricalAggregate;
130
+ export type EvaluationResultItem = EvaluationLLMResult | EvaluationToolResult | EvaluationBaseResult | EvaluationLLMInferenceAggregate | EvaluationToolAggregate | EvaluationCategoricalAggregate | EvaluationNumericalAggregate;
116
131
  /** Type guard for LLM result */
117
132
  export declare function isLLMResult(item: EvaluationResultItem): item is EvaluationLLMResult;
118
133
  /** Type guard for Tool result */
@@ -125,8 +140,10 @@ export declare function isLLMInferenceAggregate(item: EvaluationResultItem): ite
125
140
  export declare function isToolAggregate(item: EvaluationResultItem): item is EvaluationToolAggregate;
126
141
  /** Type guard for CategoricalAggregate */
127
142
  export declare function isAggregateCategorical(item: EvaluationResultItem): item is EvaluationCategoricalAggregate;
128
- /** Type guard for aggregated stats (numeric - LLMInferenceAggregate or ToolAggregate) */
129
- export declare function isAggregatedStats(item: EvaluationResultItem): item is EvaluationLLMInferenceAggregate | EvaluationToolAggregate;
143
+ /** Type guard for NumericalAggregate (custom evaluator numeric aggregate) */
144
+ export declare function isNumericalAggregate(item: EvaluationResultItem): item is EvaluationNumericalAggregate;
145
+ /** Type guard for aggregated stats (numeric - LLMInferenceAggregate, ToolAggregate, or NumericalAggregate) */
146
+ export declare function isAggregatedStats(item: EvaluationResultItem): item is EvaluationLLMInferenceAggregate | EvaluationToolAggregate | EvaluationNumericalAggregate;
130
147
  /** Aggregate results tree (roots + nodes by identifier) */
131
148
  export type EvaluationAggregateResults = {
132
149
  roots: string[];
@@ -138,7 +155,7 @@ export type EvaluationEvaluatorResult = {
138
155
  evaluator_id: string;
139
156
  /** Per-metric results (LLM, Tool, Base) */
140
157
  metric_results: EvaluationResultItem[];
141
- /** Aggregate tree (roots + nodes with ToolAggregate, LLMInferenceAggregate, CategoricalAggregate) */
158
+ /** Aggregate tree (roots + nodes with ToolAggregate, LLMInferenceAggregate, CategoricalAggregate, NumericalAggregate) */
142
159
  aggregate_results?: EvaluationAggregateResults;
143
160
  };
144
161
  /** New format: agent node with session context */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@railtownai/railtracks-visualizer",
3
- "version": "0.0.69",
3
+ "version": "0.0.71",
4
4
  "license": "MIT",
5
5
  "author": "Railtown AI",
6
6
  "description": "A visualizer for Railtracks agentic flows",
@@ -1,16 +0,0 @@
1
- /**
2
- * Judge (LLM-as-judge) evaluator view: one card per categorical metric, with
3
- * collapsible accordions per category label listing the agent nodes that received
4
- * that label. Each node exposes Session Details / Visualizer call-to-actions
5
- * (see NodeActions) and an inline toggle to reveal the judge's reasoning when present.
6
- */
7
- import React from "react";
8
- import type { JudgeMetric } from "../utils/judgeAggregateTree";
9
- export interface JudgeAggregateViewProps {
10
- metrics: JudgeMetric[];
11
- /** Opens the run for a judged node in the Session Details drawer. sessionId may be undefined for legacy evaluations. */
12
- onAgentNodeClick?: (sessionId: string | undefined, nodeId: string) => void;
13
- /** Opens the run for a judged node in the full Visualizer. */
14
- onOpenVisualizer?: (sessionId: string | undefined, nodeId: string) => void;
15
- }
16
- export declare const JudgeAggregateView: React.FC<JudgeAggregateViewProps>;
@@ -1,55 +0,0 @@
1
- /**
2
- * Builds the Judge (categorical) evaluator view model from aggregate_results.
3
- *
4
- * Shape of the data (see sample.json -> JudgeEvaluator):
5
- * - aggregate_results.roots -> CategoricalAggregate nodes (one per metric) with
6
- * `categories`, `counts`, `most_common_label`, `least_common_label`, and `children`.
7
- * - Each child id resolves (in aggregate_results.nodes) to a Base leaf result whose
8
- * `result_name` is `JudgeResult/<metric>`, `value` is the category label string, and
9
- * `agent_data_id[0]` is the agent node id that was judged.
10
- * - Reasoning lives separately in metric_results as Base results named
11
- * `JudgeReasoning/<metric>`, paired to a node by `agent_data_id[0]` + metric name.
12
- */
13
- import type { EvaluationResultItem, EvaluationAgent } from "../../dto/Evaluation";
14
- /** A single judged agent node under a category label. */
15
- export interface JudgeNodeRef {
16
- nodeId: string;
17
- /** Session that owns the node, when the evaluation carries session context. */
18
- sessionId?: string;
19
- /** Judge reasoning text for this node + metric, when available. */
20
- reasoning?: string;
21
- }
22
- /** One category label within a metric, with the nodes that received it. */
23
- export interface JudgeLabel {
24
- labelName: string;
25
- count: number;
26
- nodes: JudgeNodeRef[];
27
- }
28
- /** One categorical metric judged across all runs. */
29
- export interface JudgeMetric {
30
- key: string;
31
- metricName: string;
32
- description?: string;
33
- mostCommon?: string;
34
- leastCommon?: string;
35
- total: number;
36
- labels: JudgeLabel[];
37
- }
38
- type NodeMap = Record<string, unknown>;
39
- type AgentLike = Pick<EvaluationAgent, "agent_name" | "agent_node_ids"> | {
40
- agent_name: string;
41
- agent_node_ids?: string[] | {
42
- session_id: string;
43
- agent_node_id: string;
44
- }[];
45
- };
46
- export interface BuildJudgeMetricsInput {
47
- roots: string[];
48
- nodes: NodeMap;
49
- agents?: AgentLike[];
50
- /** Full evaluator results (metric_results + aggregates) used to resolve reasoning. */
51
- rawResults?: EvaluationResultItem[];
52
- }
53
- /** Build the Judge view model: one entry per categorical metric. */
54
- export declare function buildJudgeMetricsFromAggregate(input: BuildJudgeMetricsInput): JudgeMetric[];
55
- export {};