whetkit 0.4.0__tar.gz → 0.5.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.
- {whetkit-0.4.0 → whetkit-0.5.0}/PKG-INFO +1 -1
- {whetkit-0.4.0 → whetkit-0.5.0}/pyproject.toml +1 -1
- {whetkit-0.4.0 → whetkit-0.5.0}/src/whetkit/cli.py +48 -7
- {whetkit-0.4.0 → whetkit-0.5.0}/src/whetkit/generate.py +5 -1
- {whetkit-0.4.0 → whetkit-0.5.0}/LICENSE +0 -0
- {whetkit-0.4.0 → whetkit-0.5.0}/README.md +0 -0
- {whetkit-0.4.0 → whetkit-0.5.0}/src/whetkit/__init__.py +0 -0
- {whetkit-0.4.0 → whetkit-0.5.0}/src/whetkit/curation/__init__.py +0 -0
- {whetkit-0.4.0 → whetkit-0.5.0}/src/whetkit/curation/export.py +0 -0
- {whetkit-0.4.0 → whetkit-0.5.0}/src/whetkit/curation/optimizer.py +0 -0
- {whetkit-0.4.0 → whetkit-0.5.0}/src/whetkit/curation/overlay.py +0 -0
- {whetkit-0.4.0 → whetkit-0.5.0}/src/whetkit/curation/plan.py +0 -0
- {whetkit-0.4.0 → whetkit-0.5.0}/src/whetkit/datasets/__init__.py +0 -0
- {whetkit-0.4.0 → whetkit-0.5.0}/src/whetkit/datasets/tasks.py +0 -0
- {whetkit-0.4.0 → whetkit-0.5.0}/src/whetkit/doctor.py +0 -0
- {whetkit-0.4.0 → whetkit-0.5.0}/src/whetkit/llm/__init__.py +0 -0
- {whetkit-0.4.0 → whetkit-0.5.0}/src/whetkit/llm/anthropic_provider.py +0 -0
- {whetkit-0.4.0 → whetkit-0.5.0}/src/whetkit/llm/base.py +0 -0
- {whetkit-0.4.0 → whetkit-0.5.0}/src/whetkit/llm/openai_provider.py +0 -0
- {whetkit-0.4.0 → whetkit-0.5.0}/src/whetkit/llm/pricing.py +0 -0
- {whetkit-0.4.0 → whetkit-0.5.0}/src/whetkit/llm/registry.py +0 -0
- {whetkit-0.4.0 → whetkit-0.5.0}/src/whetkit/mcp/__init__.py +0 -0
- {whetkit-0.4.0 → whetkit-0.5.0}/src/whetkit/mcp/client.py +0 -0
- {whetkit-0.4.0 → whetkit-0.5.0}/src/whetkit/mcp/introspect.py +0 -0
- {whetkit-0.4.0 → whetkit-0.5.0}/src/whetkit/mcp/transport.py +0 -0
- {whetkit-0.4.0 → whetkit-0.5.0}/src/whetkit/py.typed +0 -0
- {whetkit-0.4.0 → whetkit-0.5.0}/src/whetkit/report/__init__.py +0 -0
- {whetkit-0.4.0 → whetkit-0.5.0}/src/whetkit/report/builder.py +0 -0
- {whetkit-0.4.0 → whetkit-0.5.0}/src/whetkit/report/html.py +0 -0
- {whetkit-0.4.0 → whetkit-0.5.0}/src/whetkit/runner/__init__.py +0 -0
- {whetkit-0.4.0 → whetkit-0.5.0}/src/whetkit/runner/agent.py +0 -0
- {whetkit-0.4.0 → whetkit-0.5.0}/src/whetkit/scoring/__init__.py +0 -0
- {whetkit-0.4.0 → whetkit-0.5.0}/src/whetkit/scoring/aggregate.py +0 -0
- {whetkit-0.4.0 → whetkit-0.5.0}/src/whetkit/scoring/deterministic.py +0 -0
- {whetkit-0.4.0 → whetkit-0.5.0}/src/whetkit/scoring/judge.py +0 -0
- {whetkit-0.4.0 → whetkit-0.5.0}/src/whetkit/tracing/__init__.py +0 -0
- {whetkit-0.4.0 → whetkit-0.5.0}/src/whetkit/tracing/records.py +0 -0
- {whetkit-0.4.0 → whetkit-0.5.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.
|
|
3
|
+
Version: 0.5.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
|
|
@@ -271,6 +271,20 @@ def plan_init(
|
|
|
271
271
|
help="Also keep every tool referenced by these tasks' expected_tools",
|
|
272
272
|
),
|
|
273
273
|
] = None,
|
|
274
|
+
from_traces: Annotated[
|
|
275
|
+
str | None,
|
|
276
|
+
typer.Option(
|
|
277
|
+
"--from-traces",
|
|
278
|
+
help=(
|
|
279
|
+
"Also keep every tool actually called in this trace store "
|
|
280
|
+
"(what real runs used, including tools no spec lists)"
|
|
281
|
+
),
|
|
282
|
+
),
|
|
283
|
+
] = None,
|
|
284
|
+
traces_group: Annotated[
|
|
285
|
+
str | None,
|
|
286
|
+
typer.Option("--traces-group", help="Restrict --from-traces to one run group"),
|
|
287
|
+
] = None,
|
|
274
288
|
out: Annotated[
|
|
275
289
|
str, typer.Option("--out", help="Where to write the plan YAML")
|
|
276
290
|
] = ".whetkit/curation-plan.yaml",
|
|
@@ -286,8 +300,18 @@ def plan_init(
|
|
|
286
300
|
for task in load_tasks(from_tasks):
|
|
287
301
|
for slot in task.expected_tool_slots:
|
|
288
302
|
keep_set.update(slot)
|
|
303
|
+
if from_traces:
|
|
304
|
+
from whetkit.tracing import TraceStore
|
|
305
|
+
|
|
306
|
+
if not Path(from_traces).is_file():
|
|
307
|
+
raise typer.BadParameter(f"no trace store at {from_traces}")
|
|
308
|
+
with TraceStore(from_traces) as trace_store:
|
|
309
|
+
for run in trace_store.load_runs(traces_group):
|
|
310
|
+
keep_set.update(run.called_tool_names)
|
|
289
311
|
if not keep_set:
|
|
290
|
-
raise typer.BadParameter(
|
|
312
|
+
raise typer.BadParameter(
|
|
313
|
+
"nothing to keep — pass --keep, --from-tasks, and/or --from-traces"
|
|
314
|
+
)
|
|
291
315
|
|
|
292
316
|
spec = _resolve_server(server, http_mode)
|
|
293
317
|
inventory = asyncio.run(inspect_server(spec))
|
|
@@ -480,6 +504,17 @@ def run(
|
|
|
480
504
|
help="Write a machine-readable summary (metrics + per-task outcomes) to this path",
|
|
481
505
|
),
|
|
482
506
|
] = None,
|
|
507
|
+
concurrency: Annotated[
|
|
508
|
+
int,
|
|
509
|
+
typer.Option(
|
|
510
|
+
"--concurrency",
|
|
511
|
+
help=(
|
|
512
|
+
"Run up to N tasks of a repetition in parallel (each gets its own "
|
|
513
|
+
"server connection). Only safe when tasks are independent — writes "
|
|
514
|
+
"to shared state should stay at 1."
|
|
515
|
+
),
|
|
516
|
+
),
|
|
517
|
+
] = 1,
|
|
483
518
|
reset_cmd: Annotated[
|
|
484
519
|
str | None,
|
|
485
520
|
typer.Option(
|
|
@@ -500,6 +535,8 @@ def run(
|
|
|
500
535
|
|
|
501
536
|
if runs < 1:
|
|
502
537
|
raise typer.BadParameter("--runs must be at least 1")
|
|
538
|
+
if concurrency < 1:
|
|
539
|
+
raise typer.BadParameter("--concurrency must be at least 1")
|
|
503
540
|
|
|
504
541
|
task_list = load_tasks(tasks)
|
|
505
542
|
servers = _resolve_task_servers(task_list, server, http_mode)
|
|
@@ -523,12 +560,16 @@ def run(
|
|
|
523
560
|
name_map = curation_plan.rename_map()
|
|
524
561
|
|
|
525
562
|
async def _run_once(group_name: str, cache: JudgeCache):
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
563
|
+
semaphore = asyncio.Semaphore(concurrency)
|
|
564
|
+
|
|
565
|
+
async def _one(task):
|
|
566
|
+
async with semaphore:
|
|
567
|
+
typer.echo(f"running {task.id} ...", err=True)
|
|
568
|
+
return await run_task(
|
|
569
|
+
task, servers[task.server], config, client_factory=client_factory
|
|
570
|
+
)
|
|
571
|
+
|
|
572
|
+
task_runs = list(await asyncio.gather(*(_one(task) for task in task_list)))
|
|
532
573
|
|
|
533
574
|
with TraceStore(store_path) as trace_store:
|
|
534
575
|
trace_store.save_runs(task_runs, run_group=group_name)
|
|
@@ -31,7 +31,11 @@ Rules for every task:
|
|
|
31
31
|
is either one tool name, or a list of genuinely interchangeable
|
|
32
32
|
alternatives for that step. Use ONLY tool names from the given list.
|
|
33
33
|
- success_criteria is one or two concrete, checkable sentences a grader can
|
|
34
|
-
verify from the agent's final answer alone.
|
|
34
|
+
verify from the agent's final answer alone. When the data source is live
|
|
35
|
+
or changing (news pages, network traffic, timestamps, prices), grade the
|
|
36
|
+
SHAPE of the answer ("names the current top story", "lists the requests
|
|
37
|
+
that were observed"), never a specific volatile value — a criterion that
|
|
38
|
+
is wrong an hour later is a flaky eval, not a strict one.
|
|
35
39
|
{writes_rule}
|
|
36
40
|
- Set "ordered": true only when the steps must happen in sequence.
|
|
37
41
|
- ids are short kebab-case slugs, unique across the set.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|