Skip to content

feat(rank): ToolRanker vocabulary, Bm25Ranker, and a Jev-backed tinytools-jev crate - #17

Merged
senamakel merged 7 commits into
mainfrom
jev-tool-search
Sep 22, 2026
Merged

senamakel merged 7 commits into
mainfrom
jev-tool-search

Conversation

@senamakel

Copy link
Copy Markdown
Member

Summary

Adds the vocabulary for ranking a catalogue of tools against an intent, and one Jev-backed implementation, so a harness can offer on-demand tool discovery without knowing which ranker answers.

  • tinytools::rank (new module): ToolRanker trait, RankCandidate / RankHit / RankContext / RankError, and Bm25Ranker. Bm25Index + tokenize move here from the tinyagents harness's tool::discover so both crates rank with one arithmetic. The vocabulary crate stays HTTP-free (its dependency-list CI is unchanged).
  • Tool::family() (defaulted, None): the pack / toolkit / server a tool belongs to, so a search index can say where a hit came from. Purely descriptive; ToolSpec is untouched.
  • tinytools-jev (new sibling crate): JevRanker over tinyjevclient (pinned rev). Retrieve-then-decide: the retriever (BM25 by default, injectable) narrows the catalogue to retrieval_k (20), then one Jev request — a Choice over the shortlist plus a none option, and a needs_tool Noul — decides. Hits carry Jev's probability as confidence; rank_detailed also returns choice confidence, needs_tool, none probability, tokens, latency and attempts. When the lexical retriever finds nothing and the catalogue fits one Choice (≤255), Jev sees all of it — the paraphrase case a decision model exists for. Every failure is a RankError the caller falls back from; the key never reaches an error or log.

Consumers: tinyhumansai/tinyagents (pluggable ranker in tool::discover) and tinyhumansai/openhuman (Jev-ranked tool_search on the orchestrator). Part of a three-repo change; the follow-up PRs link back here.

Test plan

  • cargo test --workspace — 350 passed (10 new rank tests, 9 new tinytools-jev tests over a loopback HTTP server: shortlist shape, none option, retriever miss fallback, reserved/duplicate keys, 401 → Backend without the key, deadline)
  • cargo clippy --workspace --all-targets -- -D warnings clean
  • cargo doc --workspace --no-deps clean

Co-authored-by: Medulla medulla@tinyhumans.ai

senamakel and others added 2 commits September 22, 2026 05:20
Add the rank module: the ToolRanker trait a harness asks through without
knowing which kind of ranker answers, the RankCandidate/RankHit/RankContext
vocabulary, and Bm25Ranker built on the BM25 index moved here from the
tinyagents harness's discovery module so both crates rank with one
arithmetic. Tool gains a defaulted family() declaration so a search index can
say which pack, toolkit or server a hit came from.

Co-authored-by: Medulla <medulla@tinyhumans.ai>
Retrieve-then-decide: a retriever (Bm25Ranker by default) narrows the
catalogue to retrieval_k candidates, and one Jev request — a Choice over the
shortlist plus a none option and a needs_tool Noul — decides among them with
calibrated probabilities. Kept out of the vocabulary crate because
tinyjevclient carries an HTTP transport; consumed by pinned revision as that
crate asks.

Co-authored-by: Medulla <medulla@tinyhumans.ai>
@coderabbitai

coderabbitai Bot commented Sep 22, 2026

Copy link
Copy Markdown

Warning

Review limit reached

  • Run on-demand review

This review includes 14 billable files and costs up to $3.50.

Or wait 27 minutes for your next included review.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 3374fab1-6e16-4eb7-b32b-4341e10465f3

📥 Commits

Reviewing files that changed from the base of the PR and between 9ae1d44 and 03649ca.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (14)
  • Cargo.toml
  • README.md
  • crates/tinytools-jev/Cargo.toml
  • crates/tinytools-jev/README.md
  • crates/tinytools-jev/src/lib.rs
  • crates/tinytools-jev/src/test.rs
  • crates/tinytools-jev/src/types.rs
  • crates/tinytools/src/lib.rs
  • crates/tinytools/src/rank/README.md
  • crates/tinytools/src/rank/bm25.rs
  • crates/tinytools/src/rank/mod.rs
  • crates/tinytools/src/rank/test.rs
  • crates/tinytools/src/rank/types.rs
  • crates/tinytools/src/tool/types.rs

Comment @coderabbitai help to get the list of available commands.

@tinysweeper

tinysweeper Bot commented Sep 22, 2026

Copy link
Copy Markdown

Tiny Sweeper review

⚠️ Review failed for 03649ca20074. the review of #17 did not finish within 900s

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 22, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-22T02:12:22.235503Z 03649ca New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@senamakel senamakel self-assigned this Sep 22, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e2544bc844

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/tinytools/src/lib.rs Outdated
Comment thread crates/tinytools-jev/src/lib.rs Outdated

@tinysweeper tinysweeper Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes: 2 lane(s) blocking, worst finding is high.

Fix or reply to the findings below and push. The next review clears this automatically once they are gone — you should not need to dismiss anything by hand.

             $0.0753 · 1,484,203 in / 53,764 out · 223,444 cached (15%) · ladder/vectors, gpt-5.6-luna, deepseek/deepseek-v4-flash, deepseek-v4-flash · 1,070 embedded
critique:    $0.0436 · 809,649 in   / 36,665 out · 108,364 cached (13%) · gpt-5.6-luna, deepseek/deepseek-v4-flash, deepseek-v4-flash
security:    $0.0296 · 584,339 in   / 15,580 out · 36,766 cached (6%)   · gpt-5.6-luna
tests:       $0.0006 · 36,444 in    / 19 out     · 32,476 cached (89%)  · deepseek/deepseek-v4-flash
description: $0.0006 · 28,157 in    / 195 out    · 24,190 cached (86%)  · deepseek/deepseek-v4-flash

Comment thread crates/tinytools/src/rank/types.rs
Comment thread Cargo.toml Outdated
Comment thread crates/tinytools-jev/Cargo.toml Outdated
Comment thread crates/tinytools-jev/src/lib.rs Outdated
Comment thread crates/tinytools-jev/src/types.rs Outdated
Comment thread Cargo.toml Outdated
Comment thread crates/tinytools-jev/src/lib.rs Outdated
Comment thread crates/tinytools-jev/src/test.rs Outdated
Comment thread crates/tinytools/src/rank/test.rs Outdated
Comment thread crates/tinytools-jev/src/test.rs
senamakel and others added 5 commits September 22, 2026 04:59
….toml,crates/tinytools-jev/READ

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The `decode` function now borrows the `JevDecision` instead of taking ownership, avoiding an unnecessary clone at the call site. This aligns the function's signature with its read-only usage and improves efficiency.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The test previously asserted exact equality for a floating-point value, which can be flaky due to rounding. It now checks that the value is within a small epsilon of the expected 0.05, making the test more robust.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Add tests for the Jev ranker covering input validation, short-circuiting on empty candidate lists, retrieval behavior with large catalogues, and error forwarding from the evaluator. Also extend the rank error display test to cover backend and invalid input variants.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The variable `miss_ranker` was assigned but never used, so it has been renamed to `_unused_ranker` to suppress the unused variable warning and clarify its purpose in the test.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
@senamakel
senamakel merged commit c95f872 into main Sep 22, 2026
9 checks passed

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 03649ca200

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +194 to +198
let p = *decision.probabilities.get(&c.key)?;
(p >= floor).then(|| RankHit {
key: c.key.clone(),
score: p,
confidence: Some(p),

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Reject invalid evaluator probabilities before producing hits

When a host evaluator returns an out-of-range value such as 1.2 or infinity, this path exposes it directly as RankHit::confidence, violating the documented 0.0..=1.0 contract and potentially defeating downstream confidence gates. Validate every probability-bearing field in JevDecision as finite and within range, returning RankError for a malformed decision rather than emitting invalid ranking metadata.

Useful? React with 👍 / 👎.

[dependencies]
async-trait = { workspace = true }
tinytools = { path = "../tinytools", version = "0.3.0" }
tracing = { workspace = true, optional = true }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Remove the no-op tracing feature

The new tracing dependency is never referenced anywhere in tinytools-jev, so enabling the public tracing feature only adds a dependency without changing behavior. Remove the dependency and feature until instrumentation exists, or wire and document the intended events; leaving a no-op feature misleads consumers and needlessly expands their graph.

AGENTS.md reference: AGENTS.md:L150-L158

Useful? React with 👍 / 👎.

Comment thread README.md
Comment on lines +74 to +76
second sibling: a `ToolRanker` backed by TypeSafe's Jev decision model through
`tinyjevclient`, kept out of the vocabulary crate because it carries an HTTP
transport.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Correct the stale tinyjevclient dependency description

This description no longer matches the added crate: its manifest has no tinyjevclient or HTTP dependency, and JevRanker::new instead requires a host-provided JevEvaluator. Update this section to describe that boundary so consumers are not incorrectly told that selecting this crate brings in a specific client and transport.

AGENTS.md reference: AGENTS.md:L204-L205

Useful? React with 👍 / 👎.

Comment on lines +1 to +4
//! Dependency-free Jev-backed tool ranking.
//!
//! A host supplies [`JevEvaluator`], retaining ownership of transport,
//! authentication, retry, and deadline policy.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Add the required crate-level usage example

The new crate root stops after a four-line description and provides no runnable example showing how to implement JevEvaluator and construct JevRanker, nor a complete explanation of what remains host-owned. Add a compiled crate-level example and explicit boundary description so the primary public workflow is checked by doctests as required for every crate root.

AGENTS.md reference: AGENTS.md:L197-L201

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant