whetkit 0.5.0__tar.gz → 0.6.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 (38) hide show
  1. {whetkit-0.5.0 → whetkit-0.6.0}/PKG-INFO +13 -4
  2. {whetkit-0.5.0 → whetkit-0.6.0}/README.md +12 -3
  3. {whetkit-0.5.0 → whetkit-0.6.0}/pyproject.toml +1 -1
  4. {whetkit-0.5.0 → whetkit-0.6.0}/src/whetkit/cli.py +2 -0
  5. {whetkit-0.5.0 → whetkit-0.6.0}/src/whetkit/scoring/aggregate.py +22 -0
  6. {whetkit-0.5.0 → whetkit-0.6.0}/LICENSE +0 -0
  7. {whetkit-0.5.0 → whetkit-0.6.0}/src/whetkit/__init__.py +0 -0
  8. {whetkit-0.5.0 → whetkit-0.6.0}/src/whetkit/curation/__init__.py +0 -0
  9. {whetkit-0.5.0 → whetkit-0.6.0}/src/whetkit/curation/export.py +0 -0
  10. {whetkit-0.5.0 → whetkit-0.6.0}/src/whetkit/curation/optimizer.py +0 -0
  11. {whetkit-0.5.0 → whetkit-0.6.0}/src/whetkit/curation/overlay.py +0 -0
  12. {whetkit-0.5.0 → whetkit-0.6.0}/src/whetkit/curation/plan.py +0 -0
  13. {whetkit-0.5.0 → whetkit-0.6.0}/src/whetkit/datasets/__init__.py +0 -0
  14. {whetkit-0.5.0 → whetkit-0.6.0}/src/whetkit/datasets/tasks.py +0 -0
  15. {whetkit-0.5.0 → whetkit-0.6.0}/src/whetkit/doctor.py +0 -0
  16. {whetkit-0.5.0 → whetkit-0.6.0}/src/whetkit/generate.py +0 -0
  17. {whetkit-0.5.0 → whetkit-0.6.0}/src/whetkit/llm/__init__.py +0 -0
  18. {whetkit-0.5.0 → whetkit-0.6.0}/src/whetkit/llm/anthropic_provider.py +0 -0
  19. {whetkit-0.5.0 → whetkit-0.6.0}/src/whetkit/llm/base.py +0 -0
  20. {whetkit-0.5.0 → whetkit-0.6.0}/src/whetkit/llm/openai_provider.py +0 -0
  21. {whetkit-0.5.0 → whetkit-0.6.0}/src/whetkit/llm/pricing.py +0 -0
  22. {whetkit-0.5.0 → whetkit-0.6.0}/src/whetkit/llm/registry.py +0 -0
  23. {whetkit-0.5.0 → whetkit-0.6.0}/src/whetkit/mcp/__init__.py +0 -0
  24. {whetkit-0.5.0 → whetkit-0.6.0}/src/whetkit/mcp/client.py +0 -0
  25. {whetkit-0.5.0 → whetkit-0.6.0}/src/whetkit/mcp/introspect.py +0 -0
  26. {whetkit-0.5.0 → whetkit-0.6.0}/src/whetkit/mcp/transport.py +0 -0
  27. {whetkit-0.5.0 → whetkit-0.6.0}/src/whetkit/py.typed +0 -0
  28. {whetkit-0.5.0 → whetkit-0.6.0}/src/whetkit/report/__init__.py +0 -0
  29. {whetkit-0.5.0 → whetkit-0.6.0}/src/whetkit/report/builder.py +0 -0
  30. {whetkit-0.5.0 → whetkit-0.6.0}/src/whetkit/report/html.py +0 -0
  31. {whetkit-0.5.0 → whetkit-0.6.0}/src/whetkit/runner/__init__.py +0 -0
  32. {whetkit-0.5.0 → whetkit-0.6.0}/src/whetkit/runner/agent.py +0 -0
  33. {whetkit-0.5.0 → whetkit-0.6.0}/src/whetkit/scoring/__init__.py +0 -0
  34. {whetkit-0.5.0 → whetkit-0.6.0}/src/whetkit/scoring/deterministic.py +0 -0
  35. {whetkit-0.5.0 → whetkit-0.6.0}/src/whetkit/scoring/judge.py +0 -0
  36. {whetkit-0.5.0 → whetkit-0.6.0}/src/whetkit/tracing/__init__.py +0 -0
  37. {whetkit-0.5.0 → whetkit-0.6.0}/src/whetkit/tracing/records.py +0 -0
  38. {whetkit-0.5.0 → whetkit-0.6.0}/src/whetkit/tracing/store.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: whetkit
3
- Version: 0.5.0
3
+ Version: 0.6.0
4
4
  Summary: Measure and improve how well LLM agents select and use the tools exposed by an MCP server
5
5
  Keywords: mcp,model-context-protocol,llm,agents,evals,tool-use,tool-selection,benchmark
6
6
  Author: Mohammed Benlamlih
@@ -163,12 +163,21 @@ back to the original world.
163
163
  |---|---|
164
164
  | `whetkit doctor` | Lint the tool surface: vague descriptions, cryptic names, near-duplicates, context bloat. `--json`; `--fail-on warn` for CI. |
165
165
  | `whetkit inspect` | Tool inventory: names, params, description tokens, schema complexity. |
166
- | `whetkit generate` | Draft eval tasks from the inventory; validated, review-before-trust YAML. |
167
- | `whetkit run` | Agentic eval loop with real tool execution; scored results + traces. `--plan` scores a curated view. |
168
- | `whetkit curate` | Baseline → LLM-proposed overlay plan → curated eval → before/after report. |
166
+ | `whetkit generate` | Draft eval tasks from the inventory (server-context aware, read-only unless `--allow-writes`); review-before-trust YAML. |
167
+ | `whetkit run` | Agentic eval with real tool execution. `--runs N` for mean±range and flaky-task detection, `--concurrency` for independent tasks, `--reset-cmd` for stateful fixtures, `--plan` to score a curated view, `--summary-json` for machine-readable results (with cost estimates). |
168
+ | `whetkit curate` | Baseline → LLM-proposed overlay plan → curated eval → before/after report. `--prune-unused` for the cost play. |
169
+ | `whetkit fix` | Self-correcting curation: propose → eval → feed regressions back → revise, up to `--max-iterations`; keeps the best plan by measured results. |
170
+ | `whetkit plan-init` | Scaffold a view plan: `--keep a,b`, `--from-tasks tasks/`, `--from-traces traces.sqlite3` — hide everything else. |
171
+ | `whetkit diff` | Compare two `--summary-json` files: metric deltas + per-task PASS/MISS/FLAKY transitions. |
172
+ | `whetkit export` | Share a plan: `--to markdown` (upstream-PR fix table) or `--to json` (gateway overrides). |
169
173
  | `whetkit report` | Rebuild the HTML/JSON report from stored traces. |
170
174
  | `whetkit overlay` | Serve the curated view as a stdio MCP server. |
171
175
 
176
+ Authenticated servers: any string in `server.json` may reference `${ENV_VARS}`
177
+ (e.g. an `Authorization` header) — credentials never live in the file.
178
+ Summaries flag probable task-spec gaps, errored runs, and failed tool calls
179
+ so a bad score always says why.
180
+
172
181
  ## How scoring works
173
182
 
174
183
  - **Deterministic tool-match**: each task lists the expected tool calls
@@ -132,12 +132,21 @@ back to the original world.
132
132
  |---|---|
133
133
  | `whetkit doctor` | Lint the tool surface: vague descriptions, cryptic names, near-duplicates, context bloat. `--json`; `--fail-on warn` for CI. |
134
134
  | `whetkit inspect` | Tool inventory: names, params, description tokens, schema complexity. |
135
- | `whetkit generate` | Draft eval tasks from the inventory; validated, review-before-trust YAML. |
136
- | `whetkit run` | Agentic eval loop with real tool execution; scored results + traces. `--plan` scores a curated view. |
137
- | `whetkit curate` | Baseline → LLM-proposed overlay plan → curated eval → before/after report. |
135
+ | `whetkit generate` | Draft eval tasks from the inventory (server-context aware, read-only unless `--allow-writes`); review-before-trust YAML. |
136
+ | `whetkit run` | Agentic eval with real tool execution. `--runs N` for mean±range and flaky-task detection, `--concurrency` for independent tasks, `--reset-cmd` for stateful fixtures, `--plan` to score a curated view, `--summary-json` for machine-readable results (with cost estimates). |
137
+ | `whetkit curate` | Baseline → LLM-proposed overlay plan → curated eval → before/after report. `--prune-unused` for the cost play. |
138
+ | `whetkit fix` | Self-correcting curation: propose → eval → feed regressions back → revise, up to `--max-iterations`; keeps the best plan by measured results. |
139
+ | `whetkit plan-init` | Scaffold a view plan: `--keep a,b`, `--from-tasks tasks/`, `--from-traces traces.sqlite3` — hide everything else. |
140
+ | `whetkit diff` | Compare two `--summary-json` files: metric deltas + per-task PASS/MISS/FLAKY transitions. |
141
+ | `whetkit export` | Share a plan: `--to markdown` (upstream-PR fix table) or `--to json` (gateway overrides). |
138
142
  | `whetkit report` | Rebuild the HTML/JSON report from stored traces. |
139
143
  | `whetkit overlay` | Serve the curated view as a stdio MCP server. |
140
144
 
145
+ Authenticated servers: any string in `server.json` may reference `${ENV_VARS}`
146
+ (e.g. an `Authorization` header) — credentials never live in the file.
147
+ Summaries flag probable task-spec gaps, errored runs, and failed tool calls
148
+ so a bad score always says why.
149
+
141
150
  ## How scoring works
142
151
 
143
152
  - **Deterministic tool-match**: each task lists the expected tool calls
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "whetkit"
3
- version = "0.5.0"
3
+ version = "0.6.0"
4
4
  description = "Measure and improve how well LLM agents select and use the tools exposed by an MCP server"
5
5
  readme = "README.md"
6
6
  license = "Apache-2.0"
@@ -79,6 +79,8 @@ def _summary_payload(group_name: str, summary, task_runs: list) -> dict:
79
79
  "tool_hit": score.tool_hit,
80
80
  "judge_passed": score.judge.passed if score.judge else None,
81
81
  "spec_gap": score.spec_gap,
82
+ "run_status": str(score.run_status),
83
+ "tool_errors": score.tool_errors,
82
84
  "called": score.tool_match.called,
83
85
  "missing": score.tool_match.missing_slots,
84
86
  "extra_calls": score.tool_match.extra_calls,
@@ -15,6 +15,7 @@ class TaskScore(BaseModel):
15
15
  run_status: RunStatus
16
16
  tool_match: ToolMatchResult
17
17
  judge: JudgeVerdict | None = None
18
+ tool_errors: int = 0
18
19
 
19
20
  @property
20
21
  def tool_hit(self) -> bool:
@@ -82,6 +83,14 @@ class EvalSummary(BaseModel):
82
83
  return 0.0
83
84
  return sum(len(s.tool_match.extra_calls) for s in self.scores) / len(self.scores)
84
85
 
86
+ @property
87
+ def error_run_count(self) -> int:
88
+ return sum(s.run_status == RunStatus.ERROR for s in self.scores)
89
+
90
+ @property
91
+ def total_tool_errors(self) -> int:
92
+ return sum(s.tool_errors for s in self.scores)
93
+
85
94
  def summary_lines(self) -> list[str]:
86
95
  lines = [
87
96
  f"Tasks: {self.task_count}",
@@ -93,6 +102,17 @@ class EvalSummary(BaseModel):
93
102
  ]
94
103
  if (rate := self.judge_pass_rate) is not None:
95
104
  lines.insert(2, f"Judge pass-rate: {rate:.0%}")
105
+ if self.error_run_count:
106
+ lines.append(
107
+ f"⚠ Errored runs: {self.error_run_count}/{self.task_count} — the agent "
108
+ "loop failed (connection/provider); scores below reflect failures, "
109
+ "not tool selection"
110
+ )
111
+ if self.total_tool_errors:
112
+ lines.append(
113
+ f"⚠ Failed tool calls: {self.total_tool_errors} — agents received "
114
+ "errors from the server; read the traces before trusting the scores"
115
+ )
96
116
  return lines
97
117
 
98
118
 
@@ -175,12 +195,14 @@ async def score_runs(
175
195
  called = run.called_tool_names
176
196
  if name_map:
177
197
  called = [name_map.get(name, name) for name in called]
198
+ tool_errors = sum(call.is_error for turn in run.turns for call in turn.tool_calls)
178
199
  scores.append(
179
200
  TaskScore(
180
201
  task_id=task.id,
181
202
  run_status=run.status,
182
203
  tool_match=score_tool_match(task, called, mode),
183
204
  judge=verdict,
205
+ tool_errors=tool_errors,
184
206
  )
185
207
  )
186
208
  return EvalSummary(scores=scores)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes