ciagent 0.8.0__tar.gz → 0.9.0__tar.gz

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.
Files changed (59) hide show
  1. {ciagent-0.8.0 → ciagent-0.9.0}/CHANGELOG.md +101 -1
  2. {ciagent-0.8.0 → ciagent-0.9.0}/PKG-INFO +123 -112
  3. {ciagent-0.8.0 → ciagent-0.9.0}/README.md +118 -107
  4. {ciagent-0.8.0 → ciagent-0.9.0}/pyproject.toml +12 -12
  5. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/adapters/langgraph.py +25 -4
  6. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/adapters/openai_agents.py +2 -2
  7. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/assertions.py +8 -8
  8. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/baselines.py +11 -7
  9. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/capture.py +120 -17
  10. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/cli.py +532 -73
  11. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/config.py +1 -1
  12. ciagent-0.9.0/src/ciagent/conversation.py +166 -0
  13. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/diff_engine.py +47 -8
  14. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/engine/__init__.py +1 -1
  15. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/engine/check_generator.py +3 -3
  16. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/engine/correctness.py +3 -3
  17. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/engine/cost.py +3 -3
  18. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/engine/cost_estimator.py +92 -1
  19. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/engine/diff.py +146 -16
  20. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/engine/judge.py +1 -1
  21. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/engine/judge_audit.py +83 -7
  22. ciagent-0.9.0/src/ciagent/engine/mock_runner.py +256 -0
  23. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/engine/parallel.py +8 -8
  24. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/engine/path.py +7 -7
  25. ciagent-0.9.0/src/ciagent/engine/persona.py +141 -0
  26. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/engine/reporter.py +36 -7
  27. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/engine/results.py +17 -2
  28. ciagent-0.9.0/src/ciagent/engine/retrieval.py +473 -0
  29. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/engine/runner.py +28 -9
  30. ciagent-0.9.0/src/ciagent/engine/simulate.py +514 -0
  31. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/engine/span_assertions.py +6 -6
  32. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/engine/stability.py +202 -7
  33. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/examples/demo_spec.yaml +3 -3
  34. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/loader.py +4 -4
  35. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/models.py +1 -0
  36. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/runner.py +3 -3
  37. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/schema/agentci_spec.schema.json +329 -7
  38. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/schema/generate_schema.py +2 -2
  39. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/schema/spec_models.py +194 -6
  40. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/templates/github_action.yml.j2 +4 -4
  41. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/templates/report.html.j2 +3 -3
  42. ciagent-0.8.0/src/agentci/engine/mock_runner.py +0 -129
  43. {ciagent-0.8.0 → ciagent-0.9.0}/.gitignore +0 -0
  44. {ciagent-0.8.0 → ciagent-0.9.0}/LICENSE +0 -0
  45. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/__init__.py +0 -0
  46. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/adapters/__init__.py +0 -0
  47. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/adapters/base.py +0 -0
  48. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/adapters/generic.py +0 -0
  49. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/cost.py +0 -0
  50. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/engine/metrics.py +0 -0
  51. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/examples/__init__.py +0 -0
  52. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/exceptions.py +0 -0
  53. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/mocks.py +0 -0
  54. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/py.typed +0 -0
  55. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/pytest_plugin.py +0 -0
  56. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/report.py +0 -0
  57. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/schema/__init__.py +0 -0
  58. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/templates/__init__.py +0 -0
  59. {ciagent-0.8.0/src/agentci → ciagent-0.9.0/src/ciagent}/templates/pre_push_hook.sh.j2 +0 -0
@@ -5,9 +5,109 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [0.9.0] - 2026-07-06
9
+
10
+ ### Added — retrieval layer 2.5: `retrieval:` assertions (F4, F6 Phase 4)
11
+ - New `retrieval:` block on queries and scenario `per_turn:`/`outcome:`
12
+ checks — deterministic assertions on the retriever tool's captured
13
+ `ToolCall.result`: `forbid_empty` (empty retrieval + confident answer →
14
+ WARN "ungrounded answer"; a refusal passes), `min_results`,
15
+ `expected_sources`, `facts_in_context` (informational-only in v1),
16
+ `result_format` hint, `empty_markers`/`refusal_markers` overrides
17
+ - Binding result-interpretation contract: the layer SKIPs on uncaptured or
18
+ unparseable results — it never guesses. Empty means None/[]/""/whitespace
19
+ plus spec markers. Retrieval never hard-fails (WARN tier, like path/cost)
20
+ - Fifth stability flip source `retrieval-variance` (single-turn and
21
+ scenario): verdict flipped, same tool sequence, retrieved set differed →
22
+ blames the retriever, not the prompt; attribution skips when any run's
23
+ retriever output wasn't captured
24
+ - Judge audit gains a "judged against EMPTY retrieval" row (console + JSON):
25
+ the judge graded an answer whose ground truth was already lost
26
+ - Diff engine gains `RETRIEVAL_CHANGED`: retrieved source set changed vs
27
+ golden, emitted only when a source set is extractable from both traces
28
+ - Mock runner synthesizes retrieval results satisfying the spec — the
29
+ zero-key path exercises layer 2.5 end to end
30
+ - Adapter capture verification and fixes: langgraph now pairs `ToolMessage`
31
+ outputs onto tool calls by `tool_call_id`; the openai/anthropic
32
+ monkey-patches backfill `ToolCall.result` from the next request's
33
+ `role="tool"` messages / `tool_result` blocks (openai-agents adapter
34
+ already captured results)
35
+
36
+ ### Added — generative personas, cost guardrails, stability (F6 Phase 3)
37
+ - Scenarios with `persona:`/`goal:` and no `turns:` get user turns from a
38
+ persona LLM (cheap haiku-class default, `persona_config` spec key) — the
39
+ finder path. Termination rules unchanged: max_turns / stop_when only; a
40
+ derailed persona (empty/unusable output) marks the scenario infra-error
41
+ with partial turns kept rather than silently grading the agent
42
+ - `--max-cost` session budget: hard-aborts mid-conversation at the next turn
43
+ boundary; partial results are clearly marked and the outcome verdict is
44
+ never evaluated on a partial conversation. Pre-run cost estimate with a
45
+ confirm gate; per-scenario cost line
46
+ - `--runs N` scenario stability with new `simulation-variance` flip source:
47
+ the simulated user said different things across runs — the persona varied,
48
+ not the agent. `--workers` runs scenarios in parallel (turns stay
49
+ sequential); a mock persona gives a zero-key generative path
50
+
51
+ ### Added — record + replay: found bug → regression test (F6 Phase 2)
52
+ - `--record` / `--record-dir`: save any driven conversation as a golden
53
+ envelope at `<baseline_dir>/<agent>/scenarios/<slug>.json`. Recording
54
+ never prechecks — a FAILED scenario records too (`checks_passed: false`),
55
+ because converting a found bug into a regression test is the point
56
+ - `--replay`: recorded user turns are fed back verbatim (the persona is
57
+ never consulted); the scenario spec is embedded in the envelope so goldens
58
+ are self-contained. Replaying a deterministic agent twice yields
59
+ byte-identical verdicts (the `scenario_verdict` contract)
60
+ - Conversation-aware diff (`diff_envelopes`): per-turn tool-sequence and
61
+ answer changes between a golden conversation and a fresh run
62
+
63
+ ### Added — `ciagent simulate` Phase 1: scripted multi-turn scenarios (F6)
64
+ - New `scenarios:` spec block: `turns:` (scripted user messages), `max_turns`,
65
+ `per_turn:` checks (evaluated on every turn), `outcome:` checks (evaluated
66
+ once at the END as the verdict — never a stop condition), and explicit
67
+ `stop_when: {tool_called: X}` early exit. Termination is deterministic only:
68
+ script exhausted, max_turns, or the stop_when event — no judge, no keywords
69
+ - New `conversation_runner:` spec key — `(messages: list[{role, content}]) →
70
+ str | Trace`, history passed explicitly, same capture/coercion as `test`
71
+ - `ciagent simulate` CLI: `--mock` runs scenarios on synthetic traces with
72
+ zero API keys (the CI path); live runs confirm turn count first. Exit codes:
73
+ 0 pass / 1 outcome or per-turn correctness failure / 2 config or agent error
74
+ - Agent exception mid-conversation marks the scenario `infra-error` and keeps
75
+ the completed turns; conversations convert to schema_version-2 envelopes
76
+ - Spec change: `queries:` is no longer required when `scenarios:` is present
77
+ (at least one of the two must exist)
78
+ - 18 new tests, incl. the ADR checklist items: both termination causes,
79
+ agent-raises-mid-conversation, per_turn + outcome evaluation, and
80
+ outcome-never-stops (a turn-1 keyword match must not end the scenario)
81
+
82
+ ### Added — schema_version + conversation envelope (F6 Phase 0)
83
+ - `schema_version: 1` written into new single-trace baselines; unversioned
84
+ files read as legacy; envelopes are `schema_version: 2`; newer-than-reader
85
+ files rejected by name. `ConversationEnvelope`: one loader for envelope,
86
+ wrapper, and bare-trace shapes (single-turn = 1-turn degenerate case)
87
+
88
+ ### Changed — brand and story
89
+ - **Brand: AgentCI → CIAgent** (display name), standardizing on the `ciagent`
90
+ package name. Spec/runner filenames (`agentci_spec.yaml`), `AGENTCI_*` env
91
+ vars, and `AgentCISpec`/`AgentCITraceProcessor` class names unchanged.
92
+ - **BREAKING: Python module renamed `agentci` → `ciagent`** (`from ciagent
93
+ import ...`); the `agentci` CLI entry point is removed (`ciagent` is the
94
+ command), and the pytest plugin entry point is now `ciagent`. Flag-day, no
95
+ deprecation shim (pre-adoption). Motive is a verified collision: the
96
+ unrelated PyPI package `agentci` 0.1.1 (Agent-CI) installs a top-level
97
+ `agentci/` module and an `agentci` console script — installing both tools
98
+ in one environment broke ours.
99
+ - **GitHub repo renamed** to `suniel12/ciagent` (old URLs redirect).
100
+ - **Claude Code plugin identity renamed**: install is now
101
+ `/plugin marketplace add suniel12/ciagent` + `/plugin install ciagent@ciagent`;
102
+ skills are `ciagent:onboard` / `ciagent:check`. (The 0.8.0 identity below had
103
+ zero installs.)
104
+ - **README hero, PyPI description, and GitHub About repositioned to the
105
+ eval-reliability wedge** ("Your eval score is stable. Your system isn't."),
106
+ per the strategy ADR; regression testing remains as supporting capability.
107
+
8
108
  ## [0.8.0] - 2026-07-06
9
109
 
10
- ### Added — Claude Code plugin (F5: your coding agent onboards and operates AgentCI)
110
+ ### Added — Claude Code plugin (F5: your coding agent onboards and operates CIAgent)
11
111
  - The repo is now a Claude Code plugin marketplace
12
112
  (`/plugin marketplace add suniel12/AgentCI`, `/plugin install agentci@agentci`)
13
113
  with two skills: **onboard** (write the runner, record goldens via
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ciagent
3
- Version: 0.8.0
4
- Summary: Continuous Integration for AI Agents. Catch cost spikes and logic regressions before production.
5
- Project-URL: Documentation, https://github.com/suniel12/AgentCI#readme
6
- Project-URL: Repository, https://github.com/suniel12/AgentCI.git
7
- Project-URL: Issues, https://github.com/suniel12/AgentCI/issues
3
+ Version: 0.9.0
4
+ Summary: Find out whether your AI agent's evals are lying to you: stability reports with flip attribution, LLM judge audits, and deterministic checks mined from your KB.
5
+ Project-URL: Documentation, https://github.com/suniel12/ciagent#readme
6
+ Project-URL: Repository, https://github.com/suniel12/ciagent.git
7
+ Project-URL: Issues, https://github.com/suniel12/ciagent/issues
8
8
  License: Apache-2.0
9
9
  License-File: LICENSE
10
10
  Keywords: agents,ai,ci-cd,llm,regression,testing
@@ -41,17 +41,24 @@ Provides-Extra: openai
41
41
  Requires-Dist: openai>=1.0; extra == 'openai'
42
42
  Description-Content-Type: text/markdown
43
43
 
44
- # AgentCI
44
+ # CIAgent
45
45
 
46
- **Pytest-native regression testing for AI agents.** Catch routing changes, tool call drift, and cost spikes before production.
46
+ **Your eval score is stable. Your system isn't.**
47
+
48
+ CIAgent tells you whether your agent's evals are lying to you:
49
+
50
+ - **Run the suite N times** — see which verdicts flip, with the blame attached
51
+ (`agent-variance` → fix the agent, `judge-flake` → fix the eval)
52
+ - **Audit your LLM judge** against ground truth you already have
53
+ - **Replace judge calls with deterministic fact-checks** mined from your knowledge base
47
54
 
48
55
  [![PyPI](https://img.shields.io/pypi/v/ciagent)](https://pypi.org/project/ciagent/)
49
- [![CI](https://github.com/suniel12/AgentCI/actions/workflows/ci.yml/badge.svg)](https://github.com/suniel12/AgentCI/actions/workflows/ci.yml)
56
+ [![CI](https://github.com/suniel12/ciagent/actions/workflows/ci.yml/badge.svg)](https://github.com/suniel12/ciagent/actions/workflows/ci.yml)
50
57
  [![License: Apache-2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE)
51
58
  [![AGENTS.md](https://img.shields.io/badge/AGENTS.md-supported-blue)](AGENTS.md)
52
59
 
53
- You changed a prompt. Your agent broke in production. Three days later, a user complained. You had no tests, no diff, no idea what went wrong.
54
-
60
+ Built from a real study: 1 in 7 answers an LLM judge passed were wrong, and deterministic
61
+ checks caught 8 of 8 — methodology and raw numbers in [STUDY.md](STUDY.md).
55
62
  Works with OpenAI, Anthropic, and LangGraph. Runs inside pytest.
56
63
 
57
64
  ## See It in 30 Seconds
@@ -82,80 +89,6 @@ Suite score across 3 runs: 88% / 88% / 88% ← looks stable
82
89
 
83
90
  The aggregate score is identical every run. Three of the eight verdicts underneath it flipped. A single-run eval score would never tell you — the stability report does, and attributes every flip to the layer that caused it. (The demo simulates a flaky agent; point it at your own with the spec below.)
84
91
 
85
- ## Add to Your Project
86
-
87
- ```bash
88
- pip install ciagent
89
- ```
90
-
91
- Write your golden queries — what should your agent handle, and what should it refuse?
92
-
93
- ```yaml
94
- # agentci_spec.yaml
95
- agent: my-agent
96
- # runner: any function that takes a query string and returns a response
97
- runner: my_app.agent:run_for_agentci
98
- queries:
99
- - query: "How do I install AgentCI?"
100
- correctness:
101
- any_expected_in_answer: ["pip install", "ciagent"]
102
- path:
103
- expected_tools: [retrieve_docs]
104
- cost:
105
- max_llm_calls: 8
106
-
107
- - query: "What's the CEO's favorite restaurant?"
108
- correctness:
109
- not_in_answer: ["restaurant", "favorite"]
110
- path:
111
- expected_tools: [] # expect no tools called for out-of-scope queries
112
- ```
113
-
114
- Run:
115
-
116
- ```bash
117
- agentci test --mock # start here: zero-cost with synthetic traces
118
- agentci test # run live against your real agent
119
- ```
120
-
121
- `agentci test` evaluates each query through 3 layers — correctness, path, and cost:
122
-
123
- ```
124
- ============================================================
125
-
126
- Query: How do I install AgentCI?
127
- Answer: To install AgentCI, you can use pip with the following command:
128
- pip install ciagent. Make sure you have Python 3.10 or later.
129
-
130
- ✅ CORRECTNESS: PASS
131
- ✓ Found keywords: "pip install ciagent"
132
- ✓ LLM judge passed (score: 5 ≥ 0.6)
133
- 📈 PATH: PASS
134
- ✓ Tool recall: 1.000 (expected: [retrieve_docs])
135
- ✓ Tool precision: 0.500
136
- ✓ No loops detected
137
- 💰 COST: PASS
138
- ✓ LLM calls: 8 ≤ max 8
139
-
140
- ============================================================
141
-
142
- Query: What Python version does AgentCI require and what frameworks does it support?
143
- Answer: AgentCI currently does not specify a required Python version
144
- in the provided context, so I don't have that information...
145
-
146
- ❌ CORRECTNESS: FAIL
147
- • Expected '3.10' not found in answer
148
- 📈 PATH: PASS
149
- ✓ Tool recall: 1.000 (expected: [retrieve_docs])
150
- ✓ Loops: 1 ≤ max 3
151
- 💰 COST: PASS
152
- ✓ LLM calls: 4 ≤ max 5
153
-
154
- ============================================================
155
- ```
156
-
157
- Don't have golden queries yet? `agentci init --generate` scans your code and generates a starter spec.
158
-
159
92
  ## A stable score is not a stable system
160
93
 
161
94
  Run the identical eval three times and you can get 96% / 95% / 96% — rock solid — while
@@ -163,7 +96,7 @@ individual queries flip verdicts every run. The aggregate holds because the erro
163
96
  around. `--runs N` shows what a single run can't:
164
97
 
165
98
  ```bash
166
- agentci test --runs 3
99
+ ciagent test --runs 3
167
100
  ```
168
101
 
169
102
  ```
@@ -196,7 +129,7 @@ facts; pass@k/pass^k estimates live in the JSON output, labeled as estimates.
196
129
 
197
130
  Flaky-but-passing exits 0 so adoption won't break your CI; add `--fail-on-flaky` when
198
131
  you're ready to gate on it. Try it with zero API keys:
199
- `AGENTCI_MOCK_FLAKY=1 agentci test --mock --runs 3`. Details: [docs/stability.md](docs/stability.md).
132
+ `AGENTCI_MOCK_FLAKY=1 ciagent test --mock --runs 3`. Details: [docs/stability.md](docs/stability.md).
200
133
 
201
134
  ## Audit the judge itself
202
135
 
@@ -206,7 +139,7 @@ nothing, passes it. `judge-audit` measures your judge against ground truth you a
206
139
  by re-scoring recorded baselines (the agent is never re-run):
207
140
 
208
141
  ```bash
209
- agentci judge-audit
142
+ ciagent judge-audit
210
143
  ```
211
144
 
212
145
  1. **Judge vs. deterministic checks** — the disagreement matrix. The row that matters:
@@ -223,7 +156,7 @@ shouldn't be trusted where you can't. Verdict: `TRUSTWORTHY` / `NEEDS CALIBRATIO
223
156
 
224
157
  Most agent failures that matter involve a hard fact — a product name, a price, a version number. Those are checkable deterministically, for free. And an LLM judge grading against the same context as your agent inherits your agent's blind spots: when retrieval comes up empty, the agent answers from nothing and the judge — reading the same nothing — passes it.
225
158
 
226
- So AgentCI runs deterministic checks first and treats the judge as the last resort, not the default:
159
+ So CIAgent runs deterministic checks first and treats the judge as the last resort, not the default:
227
160
 
228
161
  1. **Fact checks in code** — `expected_in_answer`, `not_in_answer`, `regex_match`, `json_schema`. Zero LLM calls, zero flakiness, same verdict every run.
229
162
  2. **Path checks** — did the agent call the tools it should have? A missing expected tool warns; a forbidden tool fails.
@@ -233,7 +166,7 @@ So AgentCI runs deterministic checks first and treats the judge as the last reso
233
166
  Don't write the fact checks by hand — mine them from your knowledge base:
234
167
 
235
168
  ```bash
236
- agentci generate-checks
169
+ ciagent generate-checks
237
170
  ```
238
171
 
239
172
  It extracts hard facts (prices, rates, SKUs, "30 days") as variant-set assertions, and
@@ -241,44 +174,122 @@ It extracts hard facts (prices, rates, SKUs, "30 days") as variant-set assertion
241
174
  would fail a known-good answer is rejected before you ever see it. One LLM call at
242
175
  authoring time; the checks run free forever. Details: [docs/generate-checks.md](docs/generate-checks.md).
243
176
 
177
+ ## Add to Your Project
178
+
179
+ ```bash
180
+ pip install ciagent
181
+ ```
182
+
183
+ Write your golden queries — what should your agent handle, and what should it refuse?
184
+
185
+ ```yaml
186
+ # agentci_spec.yaml
187
+ agent: my-agent
188
+ # runner: any function that takes a query string and returns a response
189
+ runner: my_app.agent:run_for_agentci
190
+ queries:
191
+ - query: "How do I install CIAgent?"
192
+ correctness:
193
+ any_expected_in_answer: ["pip install", "ciagent"]
194
+ path:
195
+ expected_tools: [retrieve_docs]
196
+ retrieval:
197
+ tool: retrieve_docs # assert on what the retriever actually returned
198
+ forbid_empty: true # empty retrieval + confident answer = ungrounded
199
+ expected_sources: [install.md]
200
+ cost:
201
+ max_llm_calls: 8
202
+
203
+ - query: "What's the CEO's favorite restaurant?"
204
+ correctness:
205
+ not_in_answer: ["restaurant", "favorite"]
206
+ path:
207
+ expected_tools: [] # expect no tools called for out-of-scope queries
208
+ ```
209
+
210
+ Run:
211
+
212
+ ```bash
213
+ ciagent test --mock # start here: zero-cost with synthetic traces
214
+ ciagent test # run live against your real agent
215
+ ```
216
+
217
+ `ciagent test` evaluates each query through 4 layers — correctness, path, retrieval, and cost. The retrieval layer reads the retriever tool's captured result and warns on empty retrievals, missing sources, and count floors — deterministically, and it SKIPs (never guesses) when a result wasn't captured or doesn't parse:
218
+
219
+ ```
220
+ ============================================================
221
+
222
+ Query: How do I install CIAgent?
223
+ Answer: To install CIAgent, you can use pip with the following command:
224
+ pip install ciagent. Make sure you have Python 3.10 or later.
225
+
226
+ ✅ CORRECTNESS: PASS
227
+ ✓ Found keywords: "pip install ciagent"
228
+ ✓ LLM judge passed (score: 5 ≥ 0.6)
229
+ 📈 PATH: PASS
230
+ ✓ Tool recall: 1.000 (expected: [retrieve_docs])
231
+ ✓ Tool precision: 0.500
232
+ ✓ No loops detected
233
+ 💰 COST: PASS
234
+ ✓ LLM calls: 8 ≤ max 8
235
+
236
+ ============================================================
237
+
238
+ Query: What Python version does CIAgent require and what frameworks does it support?
239
+ Answer: CIAgent currently does not specify a required Python version
240
+ in the provided context, so I don't have that information...
241
+
242
+ ❌ CORRECTNESS: FAIL
243
+ • Expected '3.10' not found in answer
244
+ 📈 PATH: PASS
245
+ ✓ Tool recall: 1.000 (expected: [retrieve_docs])
246
+ ✓ Loops: 1 ≤ max 3
247
+ 💰 COST: PASS
248
+ ✓ LLM calls: 4 ≤ max 5
249
+
250
+ ============================================================
251
+ ```
252
+
253
+ Don't have golden queries yet? `ciagent init --generate` scans your code and generates a starter spec.
254
+
244
255
  ## Let your coding agent set it up
245
256
 
246
- AgentCI ships as a Claude Code plugin. Two skills: **onboard** (writes the runner,
257
+ CIAgent ships as a Claude Code plugin. Two skills: **onboard** (writes the runner,
247
258
  records golden baselines, generates the spec, verifies it) and **check** (runs the
248
259
  right test after every change to your agent and routes failures by flip source).
249
260
 
250
261
  ```
251
- /plugin marketplace add suniel12/AgentCI
252
- /plugin install agentci@agentci
262
+ /plugin marketplace add suniel12/ciagent
263
+ /plugin install ciagent@ciagent
253
264
  ```
254
265
 
255
- Then ask your coding agent to "set up AgentCI for this repo." It records goldens with
256
- `agentci bootstrap --yes` and verifies with `agentci test --runs 3` — no human CLI use
266
+ Then ask your coding agent to "set up CIAgent for this repo." It records goldens with
267
+ `ciagent bootstrap --yes` and verifies with `ciagent test --runs 3` — no human CLI use
257
268
  needed. The runner it writes is one function: `(query: str) -> str`; trace capture is
258
269
  automatic.
259
270
 
260
271
  ## Demo
261
272
 
262
- Here's a RAG agent demo where someone "optimizes for latency" by reducing retriever docs from 8 to 1. AgentCI catches the correctness regression:
273
+ Here's a RAG agent demo where someone "optimizes for latency" by reducing retriever docs from 8 to 1. CIAgent catches the correctness regression:
263
274
 
264
- ![AgentCI Demo](demo/agentci-rag-demo.gif)
275
+ ![CIAgent Demo](demo/agentci-rag-demo.gif)
265
276
 
266
277
  ## CLI
267
278
 
268
279
  ```bash
269
- agentci init --generate # Scan project, generate test spec
270
- agentci init # Generate GitHub Actions workflow + pre-push hook
271
- agentci test --mock --yes # Zero-cost synthetic traces, CI-friendly (no keys, no prompts)
272
- agentci test # Run 3-layer evaluation (correctness → path → cost)
273
- agentci test --runs 3 # Stability report: verdict flips + flip-source attribution
274
- agentci judge-audit # Audit the LLM judge against checks, retests, hand labels
275
- agentci generate-checks # Mine KB facts into deterministic assertions (gated)
276
- agentci test --format html -o report.html # HTML report with per-query details
277
- agentci calibrate # Measure real agent metrics, auto-tune spec budgets
278
- agentci doctor # Health check: spec, deps, API keys
279
- agentci record <test> # Record golden baseline
280
- agentci diff # Diff against baseline
281
- agentci report -i results.json # Generate HTML report from JSON results
280
+ ciagent init --generate # Scan project, generate test spec
281
+ ciagent init # Generate GitHub Actions workflow + pre-push hook
282
+ ciagent test --mock --yes # Zero-cost synthetic traces, CI-friendly (no keys, no prompts)
283
+ ciagent test # Run 3-layer evaluation (correctness → path → cost)
284
+ ciagent test --runs 3 # Stability report: verdict flips + flip-source attribution
285
+ ciagent judge-audit # Audit the LLM judge against checks, retests, hand labels
286
+ ciagent generate-checks # Mine KB facts into deterministic assertions (gated)
287
+ ciagent test --format html -o report.html # HTML report with per-query details
288
+ ciagent calibrate # Measure real agent metrics, auto-tune spec budgets
289
+ ciagent doctor # Health check: spec, deps, API keys
290
+ ciagent record <test> # Record golden baseline
291
+ ciagent diff # Diff against baseline
292
+ ciagent report -i results.json # Generate HTML report from JSON results
282
293
  ```
283
294
  ## Docs
284
295
 
@@ -295,13 +306,13 @@ agentci report -i results.json # Generate HTML report from JSON results
295
306
 
296
307
  ## Why not just an LLM judge?
297
308
 
298
- Judge-only evals are expensive, flaky, and blind to their own context. AgentCI is pytest-native regression testing: deterministic checks catch the factual failures, golden traces catch behavioral drift, cost budgets catch spend regressions — and the judge handles only what genuinely needs judgment. Mock mode (`agentci test --mock`) runs the whole suite with zero API keys and zero cost, so it can gate every PR.
309
+ Judge-only evals are expensive, flaky, and blind to their own context. CIAgent is pytest-native regression testing: deterministic checks catch the factual failures, golden traces catch behavioral drift, cost budgets catch spend regressions — and the judge handles only what genuinely needs judgment. Mock mode (`ciagent test --mock`) runs the whole suite with zero API keys and zero cost, so it can gate every PR.
299
310
 
300
311
  ## Contributing
301
312
 
302
- [GitHub Issues](https://github.com/suniel12/AgentCI/issues) ·
313
+ [GitHub Issues](https://github.com/suniel12/ciagent/issues) ·
303
314
  [DemoAgents](https://github.com/suniel12/DemoAgents) — working examples for OpenAI, Anthropic, and LangGraph agents
304
315
 
305
- Apache 2.0. If you build an agent and test it with AgentCI, I'd love to hear about it.
316
+ Apache 2.0. If you build an agent and test it with CIAgent, I'd love to hear about it.
306
317
 
307
318
  ---