ciagent 0.7.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.7.0 → ciagent-0.9.0}/CHANGELOG.md +142 -1
  2. {ciagent-0.7.0 → ciagent-0.9.0}/PKG-INFO +150 -95
  3. {ciagent-0.7.0 → ciagent-0.9.0}/README.md +145 -90
  4. {ciagent-0.7.0 → ciagent-0.9.0}/pyproject.toml +12 -11
  5. {ciagent-0.7.0/src/agentci → ciagent-0.9.0/src/ciagent}/adapters/langgraph.py +25 -4
  6. {ciagent-0.7.0/src/agentci → ciagent-0.9.0/src/ciagent}/adapters/openai_agents.py +2 -2
  7. {ciagent-0.7.0/src/agentci → ciagent-0.9.0/src/ciagent}/assertions.py +8 -8
  8. {ciagent-0.7.0/src/agentci → ciagent-0.9.0/src/ciagent}/baselines.py +11 -7
  9. {ciagent-0.7.0/src/agentci → ciagent-0.9.0/src/ciagent}/capture.py +155 -32
  10. {ciagent-0.7.0/src/agentci → ciagent-0.9.0/src/ciagent}/cli.py +596 -73
  11. {ciagent-0.7.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.7.0/src/agentci → ciagent-0.9.0/src/ciagent}/diff_engine.py +47 -8
  14. {ciagent-0.7.0/src/agentci → ciagent-0.9.0/src/ciagent}/engine/__init__.py +1 -1
  15. {ciagent-0.7.0/src/agentci → ciagent-0.9.0/src/ciagent}/engine/check_generator.py +3 -3
  16. {ciagent-0.7.0/src/agentci → ciagent-0.9.0/src/ciagent}/engine/correctness.py +3 -3
  17. {ciagent-0.7.0/src/agentci → ciagent-0.9.0/src/ciagent}/engine/cost.py +3 -3
  18. {ciagent-0.7.0/src/agentci → ciagent-0.9.0/src/ciagent}/engine/cost_estimator.py +92 -1
  19. {ciagent-0.7.0/src/agentci → ciagent-0.9.0/src/ciagent}/engine/diff.py +146 -16
  20. {ciagent-0.7.0/src/agentci → ciagent-0.9.0/src/ciagent}/engine/judge.py +1 -1
  21. {ciagent-0.7.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.7.0/src/agentci → ciagent-0.9.0/src/ciagent}/engine/parallel.py +8 -8
  24. {ciagent-0.7.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.7.0/src/agentci → ciagent-0.9.0/src/ciagent}/engine/reporter.py +46 -7
  27. {ciagent-0.7.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.7.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.7.0/src/agentci → ciagent-0.9.0/src/ciagent}/engine/span_assertions.py +6 -6
  32. {ciagent-0.7.0/src/agentci → ciagent-0.9.0/src/ciagent}/engine/stability.py +202 -7
  33. ciagent-0.9.0/src/ciagent/examples/__init__.py +3 -0
  34. ciagent-0.9.0/src/ciagent/examples/demo_spec.yaml +73 -0
  35. {ciagent-0.7.0/src/agentci → ciagent-0.9.0/src/ciagent}/loader.py +4 -4
  36. {ciagent-0.7.0/src/agentci → ciagent-0.9.0/src/ciagent}/models.py +1 -0
  37. {ciagent-0.7.0/src/agentci → ciagent-0.9.0/src/ciagent}/runner.py +3 -3
  38. {ciagent-0.7.0/src/agentci → ciagent-0.9.0/src/ciagent}/schema/agentci_spec.schema.json +329 -7
  39. {ciagent-0.7.0/src/agentci → ciagent-0.9.0/src/ciagent}/schema/generate_schema.py +2 -2
  40. {ciagent-0.7.0/src/agentci → ciagent-0.9.0/src/ciagent}/schema/spec_models.py +194 -6
  41. {ciagent-0.7.0/src/agentci → ciagent-0.9.0/src/ciagent}/templates/github_action.yml.j2 +4 -4
  42. {ciagent-0.7.0/src/agentci → ciagent-0.9.0/src/ciagent}/templates/report.html.j2 +3 -3
  43. ciagent-0.7.0/src/agentci/engine/mock_runner.py +0 -111
  44. {ciagent-0.7.0 → ciagent-0.9.0}/.gitignore +0 -0
  45. {ciagent-0.7.0 → ciagent-0.9.0}/LICENSE +0 -0
  46. {ciagent-0.7.0/src/agentci → ciagent-0.9.0/src/ciagent}/__init__.py +0 -0
  47. {ciagent-0.7.0/src/agentci → ciagent-0.9.0/src/ciagent}/adapters/__init__.py +0 -0
  48. {ciagent-0.7.0/src/agentci → ciagent-0.9.0/src/ciagent}/adapters/base.py +0 -0
  49. {ciagent-0.7.0/src/agentci → ciagent-0.9.0/src/ciagent}/adapters/generic.py +0 -0
  50. {ciagent-0.7.0/src/agentci → ciagent-0.9.0/src/ciagent}/cost.py +0 -0
  51. {ciagent-0.7.0/src/agentci → ciagent-0.9.0/src/ciagent}/engine/metrics.py +0 -0
  52. {ciagent-0.7.0/src/agentci → ciagent-0.9.0/src/ciagent}/exceptions.py +0 -0
  53. {ciagent-0.7.0/src/agentci → ciagent-0.9.0/src/ciagent}/mocks.py +0 -0
  54. {ciagent-0.7.0/src/agentci → ciagent-0.9.0/src/ciagent}/py.typed +0 -0
  55. {ciagent-0.7.0/src/agentci → ciagent-0.9.0/src/ciagent}/pytest_plugin.py +0 -0
  56. {ciagent-0.7.0/src/agentci → ciagent-0.9.0/src/ciagent}/report.py +0 -0
  57. {ciagent-0.7.0/src/agentci → ciagent-0.9.0/src/ciagent}/schema/__init__.py +0 -0
  58. {ciagent-0.7.0/src/agentci → ciagent-0.9.0/src/ciagent}/templates/__init__.py +0 -0
  59. {ciagent-0.7.0/src/agentci → ciagent-0.9.0/src/ciagent}/templates/pre_push_hook.sh.j2 +0 -0
@@ -5,7 +5,148 @@ 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
- ## [Unreleased]
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
+
108
+ ## [0.8.0] - 2026-07-06
109
+
110
+ ### Added — Claude Code plugin (F5: your coding agent onboards and operates CIAgent)
111
+ - The repo is now a Claude Code plugin marketplace
112
+ (`/plugin marketplace add suniel12/AgentCI`, `/plugin install agentci@agentci`)
113
+ with two skills: **onboard** (write the runner, record goldens via
114
+ `bootstrap --yes`, generate + tighten the spec, verify with `test --runs 3`)
115
+ and **check** (run the right check after agent changes; route failures by
116
+ flip source; never weaken a correct check to go green)
117
+ - `agentci bootstrap --yes`: fully non-interactive golden recording (requires
118
+ `--queries`); bootstrap now runs the runner through the same TraceContext
119
+ capture path as `agentci test`, so **runners returning plain strings work**
120
+ (previously crashed on anything but a Trace)
121
+ - `--format json` output now includes the agent's `answer` text per query
122
+ (eng-review work item: JSON consumers need what the agent said, not just
123
+ verdicts; also unblocks JSON as a judge-audit answers source)
124
+ - Tests: skills are lint-gated — every `agentci` command and flag a skill
125
+ teaches is asserted to exist in the CLI, so skill docs cannot rot silently
126
+
127
+ ### Fixed — from Codex cross-model review of this branch
128
+ - **Nested `TraceContext` no longer double-records or loses capture**: a
129
+ Trace-returning runner that uses `TraceContext` internally, wrapped again by
130
+ the executor, used to stack SDK patches (every LLM call recorded once per
131
+ wrapper) and its exit cleared the outer context entirely. Patches now install
132
+ only in the outermost context, and exits restore the enclosing context via
133
+ contextvar tokens. Affected `agentci test` as well as the new bootstrap path
134
+ - JSON `answer` field now uses the correctness layer's extractor (metadata →
135
+ last span output), so trace shapes the evaluator can grade also serialize
136
+ their answer instead of `null`
137
+
138
+ ### Added — zero-key demo (`uvx ciagent test --mock --runs 3`)
139
+ - `agentci test --mock` with no `agentci_spec.yaml` in the working directory now
140
+ falls back to a bundled demo spec (8 synthetic support-agent queries), clearly
141
+ labeled as demo mode with synthetic data. An explicitly passed `--config` that
142
+ is missing remains an error — the fallback only applies to the default path
143
+ - Demo multi-run sessions simulate a pseudo-flaky agent by default with the new
144
+ `"spread"` style (one query breaks per run), so the aggregate score stays
145
+ constant while individual verdicts flip — the report the demo exists to show.
146
+ `AGENTCI_MOCK_FLAKY=0` turns the simulation off; non-demo specs are unaffected
147
+ (flakiness stays env-var opt-in, `"alternate"` style unchanged)
148
+ - Missing spec without `--mock` now exits with a hint pointing at both
149
+ `agentci init` and the zero-key demo command
9
150
 
10
151
  ### Changed — stability report hardening (pre-launch fixes from eng review)
11
152
  - **Flip attribution now compares per-layer sub-verdicts first**: if every
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ciagent
3
- Version: 0.7.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,92 +41,53 @@ 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
- ## Add to Your Project
64
+ ## See It in 30 Seconds
58
65
 
59
- ```bash
60
- pip install ciagent
61
- ```
62
-
63
- Write your golden queries — what should your agent handle, and what should it refuse?
64
-
65
- ```yaml
66
- # agentci_spec.yaml
67
- agent: my-agent
68
- # runner: any function that takes a query string and returns a response
69
- runner: my_app.agent:run_for_agentci
70
- queries:
71
- - query: "How do I install AgentCI?"
72
- correctness:
73
- any_expected_in_answer: ["pip install", "ciagent"]
74
- path:
75
- expected_tools: [retrieve_docs]
76
- cost:
77
- max_llm_calls: 8
78
-
79
- - query: "What's the CEO's favorite restaurant?"
80
- correctness:
81
- not_in_answer: ["restaurant", "favorite"]
82
- path:
83
- expected_tools: [] # expect no tools called for out-of-scope queries
84
- ```
85
-
86
- Run:
66
+ No install, no API keys, no config — one command runs a bundled demo suite three times on synthetic traces:
87
67
 
88
68
  ```bash
89
- agentci test --mock # start here: zero-cost with synthetic traces
90
- agentci test # run live against your real agent
69
+ uvx ciagent test --mock --runs 3
91
70
  ```
92
71
 
93
- `agentci test` evaluates each query through 3 layers — correctness, path, and cost:
94
-
95
72
  ```
96
- ============================================================
73
+ Run 1/3: 7/8 passed
74
+ Run 2/3: 7/8 passed
75
+ Run 3/3: 7/8 passed
97
76
 
98
- Query: How do I install AgentCI?
99
- Answer: To install AgentCI, you can use pip with the following command:
100
- pip install ciagent. Make sure you have Python 3.10 or later.
101
-
102
- ✅ CORRECTNESS: PASS
103
- ✓ Found keywords: "pip install ciagent"
104
- ✓ LLM judge passed (score: 5 ≥ 0.6)
105
- 📈 PATH: PASS
106
- ✓ Tool recall: 1.000 (expected: [retrieve_docs])
107
- ✓ Tool precision: 0.500
108
- ✓ No loops detected
109
- 💰 COST: PASS
110
- ✓ LLM calls: 8 ≤ max 8
111
-
112
- ============================================================
113
-
114
- Query: What Python version does AgentCI require and what frameworks does it support?
115
- Answer: AgentCI currently does not specify a required Python version
116
- in the provided context, so I don't have that information...
77
+ ────────────────────────────────────────────────────────────
78
+ Stability Report
79
+ ────────────────────────────────────────────────────────────
80
+ Suite score across 3 runs: 88% / 88% / 88% ← looks stable
117
81
 
118
- ❌ CORRECTNESS: FAIL
119
- • Expected '3.10' not found in answer
120
- 📈 PATH: PASS
121
- Tool recall: 1.000 (expected: [retrieve_docs])
122
- ✓ Loops: 1 ≤ max 3
123
- 💰 COST: PASS
124
- ✓ LLM calls: 4 ≤ max 5
82
+ ⚠️ FLAKY — 3/8 queries flipped verdicts across runs: is not
83
+ "What's your return window?" ❌✅✅ pass_rate=0.67 source: agent-variance
84
+ "Do you ship internationally?" ✅❌✅ pass_rate=0.67 source: agent-variance
85
+ "How do I reset my password?" ✅✅❌ pass_rate=0.67 source: agent-variance
125
86
 
126
- ============================================================
87
+ Flip sources: 3 agent-variance (fix the agent) │ 0 judge-flake (fix the eval)
127
88
  ```
128
89
 
129
- Don't have golden queries yet? `agentci init --generate` scans your code and generates a starter spec.
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.)
130
91
 
131
92
  ## A stable score is not a stable system
132
93
 
@@ -135,7 +96,7 @@ individual queries flip verdicts every run. The aggregate holds because the erro
135
96
  around. `--runs N` shows what a single run can't:
136
97
 
137
98
  ```bash
138
- agentci test --runs 3
99
+ ciagent test --runs 3
139
100
  ```
140
101
 
141
102
  ```
@@ -168,7 +129,7 @@ facts; pass@k/pass^k estimates live in the JSON output, labeled as estimates.
168
129
 
169
130
  Flaky-but-passing exits 0 so adoption won't break your CI; add `--fail-on-flaky` when
170
131
  you're ready to gate on it. Try it with zero API keys:
171
- `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).
172
133
 
173
134
  ## Audit the judge itself
174
135
 
@@ -178,7 +139,7 @@ nothing, passes it. `judge-audit` measures your judge against ground truth you a
178
139
  by re-scoring recorded baselines (the agent is never re-run):
179
140
 
180
141
  ```bash
181
- agentci judge-audit
142
+ ciagent judge-audit
182
143
  ```
183
144
 
184
145
  1. **Judge vs. deterministic checks** — the disagreement matrix. The row that matters:
@@ -195,7 +156,7 @@ shouldn't be trusted where you can't. Verdict: `TRUSTWORTHY` / `NEEDS CALIBRATIO
195
156
 
196
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.
197
158
 
198
- 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:
199
160
 
200
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.
201
162
  2. **Path checks** — did the agent call the tools it should have? A missing expected tool warns; a forbidden tool fails.
@@ -205,7 +166,7 @@ So AgentCI runs deterministic checks first and treats the judge as the last reso
205
166
  Don't write the fact checks by hand — mine them from your knowledge base:
206
167
 
207
168
  ```bash
208
- agentci generate-checks
169
+ ciagent generate-checks
209
170
  ```
210
171
 
211
172
  It extracts hard facts (prices, rates, SKUs, "30 days") as variant-set assertions, and
@@ -213,28 +174,122 @@ It extracts hard facts (prices, rates, SKUs, "30 days") as variant-set assertion
213
174
  would fail a known-good answer is rejected before you ever see it. One LLM call at
214
175
  authoring time; the checks run free forever. Details: [docs/generate-checks.md](docs/generate-checks.md).
215
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
+
255
+ ## Let your coding agent set it up
256
+
257
+ CIAgent ships as a Claude Code plugin. Two skills: **onboard** (writes the runner,
258
+ records golden baselines, generates the spec, verifies it) and **check** (runs the
259
+ right test after every change to your agent and routes failures by flip source).
260
+
261
+ ```
262
+ /plugin marketplace add suniel12/ciagent
263
+ /plugin install ciagent@ciagent
264
+ ```
265
+
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
268
+ needed. The runner it writes is one function: `(query: str) -> str`; trace capture is
269
+ automatic.
270
+
216
271
  ## Demo
217
272
 
218
- 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:
219
274
 
220
- ![AgentCI Demo](demo/agentci-rag-demo.gif)
275
+ ![CIAgent Demo](demo/agentci-rag-demo.gif)
221
276
 
222
277
  ## CLI
223
278
 
224
279
  ```bash
225
- agentci init --generate # Scan project, generate test spec
226
- agentci init # Generate GitHub Actions workflow + pre-push hook
227
- agentci test --mock --yes # Zero-cost synthetic traces, CI-friendly (no keys, no prompts)
228
- agentci test # Run 3-layer evaluation (correctness → path → cost)
229
- agentci test --runs 3 # Stability report: verdict flips + flip-source attribution
230
- agentci judge-audit # Audit the LLM judge against checks, retests, hand labels
231
- agentci generate-checks # Mine KB facts into deterministic assertions (gated)
232
- agentci test --format html -o report.html # HTML report with per-query details
233
- agentci calibrate # Measure real agent metrics, auto-tune spec budgets
234
- agentci doctor # Health check: spec, deps, API keys
235
- agentci record <test> # Record golden baseline
236
- agentci diff # Diff against baseline
237
- 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
238
293
  ```
239
294
  ## Docs
240
295
 
@@ -251,13 +306,13 @@ agentci report -i results.json # Generate HTML report from JSON results
251
306
 
252
307
  ## Why not just an LLM judge?
253
308
 
254
- 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.
255
310
 
256
311
  ## Contributing
257
312
 
258
- [GitHub Issues](https://github.com/suniel12/AgentCI/issues) ·
313
+ [GitHub Issues](https://github.com/suniel12/ciagent/issues) ·
259
314
  [DemoAgents](https://github.com/suniel12/DemoAgents) — working examples for OpenAI, Anthropic, and LangGraph agents
260
315
 
261
- 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.
262
317
 
263
318
  ---