Repository navigation
Conversation
The estimate counted one atom per two spans, and left out the verify, shorten, carrier and classify calls and the retention oracle's escalations. Against the five standard runs in the skill scan it came in 37-69% under. - The atom count is the larger of spans/2 and tokens/25, capped as before. - expected_calls counts the stages, every probe, and half the oracle pairs, split by role in by_role. total_calls and the every-pair-escalates total are unchanged. - expected_usd prices those calls at litellm list prices with a token profile fitted on the five runs; null when a role's model has no price. dokimi.llm.list_cost_usd is the price lookup the estimate uses. On the six measured runs the calls land within 20% of the counted total, the standard-run dollars within 25%. Triage dollars run low: its extraction writes about 1,700 tokens per call, which the profile does not model. The parity golden keeps main's output; the estimate cases compare the parts a tier or flag decides, and the bill is the intended change. Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
- Constants fitted on 13 of the 25 measured runs; the other 12 are MEASURED_RUNS. Held-out worst error: calls 13%, atoms 11%, dollars 33%, all within TOLERANCE (35%). One tolerance figure now in tests, comments, docs and changelog. - Extractor output per call priced per tier (triage 2,359 tokens, standard 195), with a bounded triage-USD test. - Parity test compares the whole estimate payload, dropping only the bill keys. - _estimate_usd no longer swallows SystemExit: it prints to stderr why USD is unavailable. - Drop the task id from comments; re-wrap the long paragraph in docs/skill-novelty.md. Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #166 +/- ##
==========================================
+ Coverage 91.98% 92.01% +0.02%
==========================================
Files 223 224 +1
Lines 27743 27810 +67
Branches 4560 4567 +7
==========================================
+ Hits 25520 25589 +69
+ Misses 1574 1572 -2
Partials 649 649
🚀 New features to boost your workflow:
|
The held-out dollar checks priced the projection through litellm's bundled price map. The locked litellm (1.105.0) has no entry for us.anthropic.claude-haiku-5-5, so the answerer priced to None on every CI Python and the checks failed; a newer local litellm passed. conftest keeps litellm on its bundled map, so the figures depended on the installed release. Pin the two models' list prices in the test with monkeypatch. The pinned figures equal the bundled 1.106.2 entries, so the projection and the 35% tolerance are unchanged. Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
antonwolfy
left a comment
There was a problem hiding this comment.
Review at 6e01b78. The projection math holds up and the CLI handles unpriced and unresolvable models cleanly, but one published claim is false and two behaviours the PR adds are not pinned by its tests. Four things are worth fixing before merge, plus two nits inline.
What I ran, on a Linux review host at 6e01b78:
make ci-local: 20 passed, 7 skipped, 8 failed. The 8 failures are steps whose tool is missing from my venv (exit 127):make devstops at the tools install on this base, which #179 fixed onmain. Static checks, mypy and the strict docs build pass on GitHub's CI at this head. The test step and the changed-line coverage step pass.- Recomputed the held-out errors from
MEASURED_RUNSwith the PR's ownestimate()andestimate_usd()and the pinned prices. - A mutation run of the new tests (
test_novelty_tiers.py,test_novelty_settings_parity.py): 14 mutants, 2 of which pass both files. - CLI repros with the LLM transport blocked: unknown extractor/judge model, bad provider, zero-token artifact,
--all-atoms,--max-atoms 1.
Findings that cannot be anchored inline:
docs/skill-novelty-walkthrough.mdstill describes the old estimate. Lines 65-71 name onlytotal_callsandtotal_calls_if_every_pair_escalates, and line 71 says "The bill is in calls, not dollars". The estimate now printsexpected_callsandexpected_usd. The docs-review-triggers step flags the page: it depends oncommands/novelty.pyandnovelty/tiers.py, which changed, and it was not updated. Suggestion: describeexpected_calls,by_roleandexpected_usdthere, and keep the--max-usdadvice.
Checked, no issues
- Calls and atoms: held-out errors are +13.3% max for calls (held-01, 111 vs 98) and -11.1% max for atoms (held-02, 16 vs 18), as the PR states. Three of the 12 runs are standard.
- Dollar magnitude: the worst held-out dollar error is 33.0% (held-12), inside the 35% tolerance. Only its sign claim is wrong, see inline.
- Models and prices: an unknown extractor or judge model gives
expected_usd: nullwith a stderr note naming only the unpriced roles. A judge provider thatdefault_judgerejects gives null plus a note instead of aborting. Free local models price to 0.0, unknown ones to None. - Edge inputs: a zero-token artifact,
--all-atoms(200 atoms) and--max-atoms 1give sane figures, and--arms pairedis refused as before. - Consumers:
estimate()andestimate_calls()are used only bycommands/novelty.pyand tests, and no schema describes the payload. The added keys are additive. The_clientsrefactor behaves as before.
Signed-off-by: Anton Volkov <antonwolfy@gmail.com>
Signed-off-by: Anton Volkov <antonwolfy@gmail.com>
|
Review-body item 1 (walkthrough still describes the old estimate): fixed in 88d697a. docs/skill-novelty-walkthrough.md now describes expected_calls, by_role and expected_usd, keeps the --max-usd advice, and says expected_usd is a projection, not a ceiling. |
…and no-price branches The held-out dollar projections ran high on 5 runs and low on 7 (worst -33%). Update the walkthrough page for expected_calls, by_role and expected_usd. Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
antonwolfy
left a comment
There was a problem hiding this comment.
I pushed a commit per nit, up to de6c34f, which fix the two nits from my review:
5dd7057:dokimi/docs/skill-novelty.md:794: re-wrapped the override sentence so the paragraph lines stay near 92 characters.de6c34f:dokimi/docs/skill-novelty.md:787: noted that pricing imports litellm, which tries a price-map fetch before using the bundled copy, and thatLITELLM_LOCAL_MODEL_COST_MAP=Trueskips it.
make ci-local at de6c34f: 20 passed, 8 failed (host: tool missing, exit 127), 7 skipped.
Not approving yet. Still open: the four risks from my review.
antonwolfy
left a comment
There was a problem hiding this comment.
Review at 88d697a. The three threads from my earlier review are fixed: the dollar-direction claim, the CLI tier pin and the no-price-entry branch each have the right text or test now. One new bug: --estimate-only can print non-JSON on stdout for a model litellm cannot route. Two smaller points inline.
What I ran, on a Linux review host at 88d697a:
make ci-local: 27 passed, 1 failed, 7 skipped. The failure ispip-audit(a new gitpython 3.2.0 advisory, CVE-2026-114145); the PR does not touch the lock files, so I do not count it against the PR.- Recomputed the 12 held-out rows with
estimate()andestimate_usd()at the pinned prices. - A mutation run of
test_novelty_tiers.pyandtest_novelty_settings_parity.py: 13 mutants, 1 of which passes both files. Reproductions for the code finding, with the LLM transport mocked.
Checked, no issues
- Dollar claim: held-out dollar errors are +28.7% to -33.0%, high on 5 runs and low on 7, as the docs and changelog now say. The PR description still says every dollar projection came out high. Calls (max 13.3%) and atoms (max 11.1%) match.
- New tests: replacing
settings.tierwithNonefails only the new triage CLI test. Changing thereturn Nonefor a missing price entry toreturn 0.0fails only the newlist_cost_usdtest. Eight other mutants ofestimate_usdandcall_tokensare caught. - Existing keys:
total_callsandtotal_calls_if_every_pair_escalatesare unchanged.
Signed-off-by: Anton Volkov <antonwolfy@gmail.com>
…JSON; pin the call_tokens floor Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…s baseline; chore(growth): raise commands/novelty.py for W2 Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…m_pricing in the foundation layer Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
…ount total_calls and total_calls_if_every_pair_escalates keep their formula, but n_atoms now takes the token rule, so both rise wherever the span rule left the count under the tier cap and the token rule gives more. Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>
--estimate-only catches the SystemExit from _role_models and prints expected_usd null with a note; nothing reached that branch, so catching the wrong exception aborted the preview with every test green. Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>
…arms Every fit row and test used two arms, so replacing n_arms with 2 in estimate_calls' by_role passed the suite while --arms with a third arm under-counted the answerer and judge bill by a third. Signed-off-by: Alexander Rybkin <alexander.rybkin@intel.com>
|
antonwolfy
left a comment
There was a problem hiding this comment.
Review at 76a567c. The fixes for my three threads hold: the banner stays off stdout, the max(0, ...) floor is pinned, and the walkthrough paragraph is re-wrapped. Two test gaps inline are worth closing before merge, and @xaleryb's two points are still open.
I agree with @xaleryb on the three-arm answerer pricing and the large-artifact extrapolation. New evidence: with --arms no_artifact,full,shuffled at 6,723 tokens the answerer term is about 21% low, and at 19k tokens no model mix lands both triage and study near the walkthrough's $1.80 and $14.50 (where triage matches within 1%, study is +86%).
What I ran, on a Linux review host at 76a567c:
make ci-local: 28 passed, 1 failed, 7 skipped. The failure ispip-audit(gitpython 3.2.0 advisory); the PR does not touch the lock files, so I do not count it. The test step passes.- A mutation run of
test_novelty_tiers.pyandtest_novelty_settings_parity.py: 37 mutants, 9 of which pass both files. Two are inline. - CLI runs with the LLM transport mocked and the network blocked: unroutable, unpriced and unresolvable models, all three tiers,
--armsvariants,--all-atoms,--max-atoms 1, empty and tiny artifacts.
Checked, no issues
- Stdout:
json.loads(stdout)succeeds in every case that produces an estimate, including--model foo-bar-9 --provider openai; the litellm banner goes to stderr. _has_price_entryrefactor: 14 x 15 (routed name, model) pairs give the same answer as the base.- Held-out figures: recomputed with the pinned prices: calls max 13.3%, atoms max 11.1%, dollars +28.7% to -33.0%, as the docs say.
- Import architecture: the
cost_per_tokenwrapper keeps litellm insidedokimi.llm; the architecture tests pass.
| # and the escalations, which is how the measured runs split their calls. | ||
| by_role = { | ||
| "extractor": stage_calls + escalated, | ||
| "answerer": (paired + reversals) * n_arms, |
There was a problem hiding this comment.
The reversals term in by_role for the answerer and judge is not pinned by any test.
Mutation check: replacing (paired + reversals) * n_arms with paired * n_arms for both answerer and judge passes test_novelty_tiers.py and test_novelty_settings_parity.py in full (86 passed). Every fixture in MEASURED_RUNS is a triage or standard run, and both have reversals off, so the term is always 0 in the tests. A study run (reversals on) would then lose n_atoms * n_arms calls per role from expected_calls and expected_usd with nothing failing.
Suggestion: add a test with resolve_settings("study", {}) that asserts by_role["answerer"] == by_role["judge"] == (paired_probes + reversal_probes) * n_arms and reversal_probes > 0.
There was a problem hiding this comment.
Added in ee809ec: test_a_study_run_counts_its_reversal_probes_in_the_answerer_and_judge_calls asserts reversal_probes > 0 and by_role answerer == judge == (paired + reversal) * n_arms for the study tier. Verified it fails with the reversals term dropped.
| except SystemExit as exc: | ||
| print(f"The USD estimate is unavailable: {exc}", file=sys.stderr) | ||
| return None | ||
| usd = estimate_usd(by_role, n_tokens, models, tier) |
There was a problem hiding this comment.
Nothing pins that the CLI passes the artifact's token count to estimate_usd.
Mutation check: replacing n_tokens with 0 here passes both new-test files in full (86 passed). The CLI tests compare expected_usd only to > 0, or to another estimate_usd call that uses the same tier. A refactor that drops the count would make the figure stop scaling with the artifact, which is the main input to the dollar projection, and no test would notice.
Suggestion: in the triage CLI test, assert expected_usd == estimate_usd(by_role, payload["tokens"], models, "triage") with payload["tokens"] > 0, and that it differs from the figure at n_tokens=0.
There was a problem hiding this comment.
Fixed in ee809ec: test_the_cli_prices_a_triage_estimate_with_the_triage_extractor_profile now uses an artifact large enough that the max(0, ...) floor does not hide the token count, asserts payload tokens > 100 and that expected_usd differs from estimate_usd at n_tokens=0. Verified it fails with n_tokens replaced by 0 in the CLI.
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com> # Conflicts: # dokimi/scripts/growth_baseline.json
…stimates, pin the estimate inputs The answerer's artifact term now scales with the arms that carry the artifact, and an artifact above the largest measured one sets usd_extrapolated. Tests pin the reversal term of by_role and the artifact token count passed to estimate_usd. Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com>
|
Review-body items from @xaleryb's comment, in ee809ec: (1) large artifacts: the payload now sets usd_extrapolated and warns on stderr above 6,723 tokens (the largest measured artifact), and the docs state the range and that the triage projection ran low as the artifact grew. I did not refit the profiles. (2) three-arm answerer: the answerer's per-token term now scales with the share of arms that carry the artifact (factor 1 at the default two arms, 1.5 at four); a --placebo-text of another length is still not read, and the docs say so (test_the_answerer_artifact_term_scales_with_the_arms_that_carry_it, test_the_cli_prices_three_context_arms_above_two). (3) PR body claims: deferred, I did not edit the description; it still says every dollar projection came out high and that total_calls is unchanged. |
Signed-off-by: Nikolay Petrov <nikolay.a.petrov@intel.com> # Conflicts: # dokimi/scripts/growth_baseline.json
Part of #4.
Summary
novelty analyze --estimate-onlynow projects the calls the run will make and what they will cost, not only the calls the estimator could count before.expected_callssits between the existing no-escalation and full-escalation totals.expected_usdis the run's own price map applied to a token profile fitted per tier: a triage extraction packs the capped atom set into each call, and a standard extraction does not.Evidence
The constants were fitted on 13 of the 25 measured skill-scan runs. The other 12 are held out, and the regression tests check every projection against them. Each run's figures are in
MEASURED_RUNSintests/test_novelty_tiers.pyas numbers only.Fail on
intel/main:The other new tests import names that do not exist on
intel/main(estimate_usd,call_tokens,TOKENS_PER_ATOM,CALL_TOKENS), so againstintel/mainthey cannot run at all. The tier-level behaviour is covered by those tests rather than by the CLI test alone.Local checks on the rebased head:
Merge Danger
Door: two-way. The change is to a projection, not to a run:
--estimate-onlystill makes no client and spends nothing. The output keys are added, and the existingtotal_callsfigures are unchanged.Blast Radius: low for runs, but the numbers people read change.
atomsandexpected_callsnow reflect the token rule, so an estimate for a long artifact with short spans is higher than before. Scripts that read the estimate will seetokens,by_role,expected_callsandexpected_usd.expected_usdis list price applied to fitted token profiles. It ran high on 5 held-out runs and low on 7 (worst -33%), so it is not a ceiling. It is not a bill, and it isnullwhen any role's model has no list price in the litellm map.TOKENS_PER_ATOM,ESCALATION_SHARE,CALL_TOKENSandEXTRACTOR_TOKENSlive innovelty/tiers.py. Changing them changes every estimate.Checklist
pytestpassesruff,mypy, and schema checks passdocs/skill-novelty.md(--estimate-onlysection)🤖 Generated with Claude Code