@checklabs/core 0.2.1

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.
package/src/types.ts ADDED
@@ -0,0 +1,197 @@
1
+ /**
2
+ * CheckAI public types.
3
+ *
4
+ * The contract that matters most is {@link AgentResponse} (what an agent returns)
5
+ * and {@link AgentAdapter} (how CheckAI talks to any agent). Everything else is
6
+ * built on top of these two.
7
+ */
8
+
9
+ /** Token accounting for a single agent turn. */
10
+ export interface TokenUsage {
11
+ promptTokens: number;
12
+ completionTokens: number;
13
+ totalTokens: number;
14
+ }
15
+
16
+ /** The value every agent turn resolves to. */
17
+ export interface AgentResponse {
18
+ /** Natural-language reply shown to the user. */
19
+ output: string;
20
+ /** Tools/functions the agent invoked this turn. */
21
+ toolsUsed: string[];
22
+ /** Wall-clock latency of the turn, in milliseconds. */
23
+ latencyMs: number;
24
+ /** Model identifier that produced the response. */
25
+ model: string;
26
+ /** Token usage, if the adapter can report it. Estimated by CheckAI otherwise. */
27
+ usage?: TokenUsage;
28
+ /** Pre-computed cost in USD, if known. Estimated from usage + pricing otherwise. */
29
+ costUsd?: number;
30
+ /** Adapter-specific raw payload (never inspected by CheckAI). */
31
+ raw?: unknown;
32
+ }
33
+
34
+ /**
35
+ * A connected agent. Adapters wrap OpenAI, a local function, or an HTTP endpoint
36
+ * behind this single interface so tests are agent-agnostic.
37
+ */
38
+ export interface AgentAdapter {
39
+ /** Human-friendly name, e.g. "support-agent". */
40
+ name: string;
41
+ /** Model id the adapter drives, e.g. "gpt-4.1-mini". */
42
+ model: string;
43
+ /** Run one turn. */
44
+ run(input: string): Promise<AgentResponse>;
45
+ }
46
+
47
+ /** Context injected into every test body. */
48
+ export interface TestContext {
49
+ agent: AgentAdapter;
50
+ }
51
+
52
+ /** A test body. */
53
+ export type TestFn = (ctx: TestContext) => void | Promise<void>;
54
+
55
+ /** A registered test case. */
56
+ export interface TestCase {
57
+ name: string;
58
+ fn: TestFn;
59
+ file: string;
60
+ }
61
+
62
+ /** Outcome of a single LLM-judge evaluation. */
63
+ export interface JudgeResult {
64
+ /** Behavior under evaluation. */
65
+ behavior: string;
66
+ /** Graded score in [0, 1]. */
67
+ score: number;
68
+ /** Minimum score required to pass. */
69
+ threshold: number;
70
+ /** score >= threshold. */
71
+ pass: boolean;
72
+ /** Short human-readable justification. */
73
+ reasoning: string;
74
+ /** Which backend produced the score. */
75
+ backend: "openai" | "heuristic";
76
+ }
77
+
78
+ /** Outcome of a single assertion. */
79
+ export interface AssertionResult {
80
+ /** Matcher name, e.g. "toAskFor" (prefixed with "not." when negated). */
81
+ matcher: string;
82
+ negated: boolean;
83
+ pass: boolean;
84
+ expected: string;
85
+ actual: string;
86
+ /** Present for judge-backed assertions. */
87
+ score?: number;
88
+ threshold?: number;
89
+ }
90
+
91
+ /** Status of one test against one agent. */
92
+ export type TestStatus = "pass" | "fail" | "error";
93
+
94
+ /** Result of running one test against one agent. */
95
+ export interface TestResult {
96
+ name: string;
97
+ file: string;
98
+ status: TestStatus;
99
+ /** Every assertion attempted, up to (and including) the first failure. */
100
+ assertions: AssertionResult[];
101
+ /** The first failing assertion, if status === "fail". */
102
+ failure?: AssertionResult;
103
+ /** Stack/message if status === "error" (a thrown non-assertion error). */
104
+ errorMessage?: string;
105
+ /** Latency of every agent.run() call in the test. */
106
+ latencies: number[];
107
+ /** Union of tools used across the test. */
108
+ toolsUsed: string[];
109
+ /** Aggregated token usage across the test. */
110
+ usage: TokenUsage;
111
+ /** Aggregated estimated cost across the test (USD). */
112
+ costUsd: number;
113
+ /** Total test duration (ms). */
114
+ durationMs: number;
115
+ }
116
+
117
+ /** Aggregate stats for a suite run against one agent. */
118
+ export interface SuiteSummary {
119
+ total: number;
120
+ passed: number;
121
+ failed: number;
122
+ errored: number;
123
+ /** passed / total in [0, 1]. */
124
+ passRate: number;
125
+ avgLatencyMs: number;
126
+ totalTokens: number;
127
+ totalCostUsd: number;
128
+ }
129
+
130
+ /** Full report for one agent run (the unit the JSON/HTML reporters serialize). */
131
+ export interface RunReport {
132
+ kind: "run";
133
+ agent: { name: string; model: string; backend: string };
134
+ results: TestResult[];
135
+ summary: SuiteSummary;
136
+ startedAt: string;
137
+ finishedAt: string;
138
+ }
139
+
140
+ /** A single test compared across agents. */
141
+ export interface ComparisonRow {
142
+ name: string;
143
+ file: string;
144
+ statuses: TestStatus[];
145
+ /** Per-agent first-failure detail (aligned with `statuses`). */
146
+ failures: (AssertionResult | undefined)[];
147
+ /** "regression" | "improvement" | "unchanged" | "error" relative to baseline. */
148
+ delta: "regression" | "improvement" | "unchanged" | "error";
149
+ }
150
+
151
+ /** Result of comparing two or more agents over the same suite. */
152
+ export interface ComparisonResult {
153
+ kind: "comparison";
154
+ agents: { name: string; model: string; backend: string }[];
155
+ baseline: string;
156
+ rows: ComparisonRow[];
157
+ summaries: SuiteSummary[];
158
+ regressions: ComparisonRow[];
159
+ improvements: ComparisonRow[];
160
+ unchanged: number;
161
+ /** Candidate cost vs baseline cost, percent (+/-). */
162
+ costDeltaPct: number;
163
+ /** Candidate latency vs baseline latency, percent (+/-). */
164
+ latencyDeltaPct: number;
165
+ startedAt: string;
166
+ finishedAt: string;
167
+ }
168
+
169
+ /** Named agent: a module path, or an inline adapter. */
170
+ export type AgentSource = string | AgentAdapter;
171
+
172
+ /** User-facing CheckAI configuration (checkai.config.ts default export). */
173
+ export interface CheckAIConfig {
174
+ /** Directory scanned for *.test.ts files (relative to the config file). */
175
+ testDir?: string;
176
+ /** Model used by the LLM judge. */
177
+ judgeModel?: string;
178
+ /** Default pass threshold for toSatisfyBehavior (0..1). */
179
+ judgeThreshold?: number;
180
+ /** Named agents. compare runs the suite against every entry. */
181
+ agents?: Record<string, AgentSource>;
182
+ /** Single-agent shorthand. */
183
+ agent?: AgentSource;
184
+ /** Which agent `checkai run` uses. */
185
+ defaultAgent?: string;
186
+ }
187
+
188
+ /** Config with defaults resolved and paths made absolute. */
189
+ export interface ResolvedConfig {
190
+ configPath: string | null;
191
+ rootDir: string;
192
+ testDir: string;
193
+ judgeModel: string;
194
+ judgeThreshold: number;
195
+ agents: Record<string, AgentSource>;
196
+ defaultAgent: string;
197
+ }