Skip to content

Remove duplicated code found by tinyanalyzer - #312

Merged
senamakel merged 27 commits into
mainfrom
dedupe-clones
Oct 7, 2026
Merged

senamakel merged 27 commits into
mainfrom
dedupe-clones

Conversation

@senamakel

@senamakel senamakel commented Oct 7, 2026 •

Copy link
Copy Markdown
Member

Summary

Removes duplicated code found by tinyanalyzer's new clone detection (tinyhumansai/tinyanalyzer#8). The net change is about 1,600 lines removed: +463 / −2,085 across 29 files.

  • Stops copying tinyinference. The harness had private copies of replace_text_blocks (two of them), canonical_value, and the JSON-schema validator (validate_at / validate_type / matches_type). It now calls the versions tinyinference exports, so structured output and tool-call arguments are validated by one implementation. validate_value keeps its signature and error type.
  • Deletes two dead files. run_ledger/ops/team.rs and ops/rows.rs (1,092 lines) were never declared by any mod, so they were never compiled. Every function in them also exists in ops.rs; the few that differ are the older versions.
  • Session run ledger.
    • One get_logged / get_row_by_id pair replaces six copies of the "open connection, init schema, look up by id, log" code.
    • A new paging::PagedQuery replaces five copies of the "optional filters, count, LIMIT/OFFSET, map" code: list_agent_runs, list_workflow_runs, list_agent_teams, list_sessions and search_sessions_inner. Placeholder numbering now lives in one place.
  • Graph checkpoints. Checkpoint::config() and Checkpoint::parent_config() replace 12 hand-built CheckpointConfig copies across the file, sqlite and default checkpointers and compiled/boundary.rs.
  • Test builders. testkit::text_response and testkit::tool_call_response replace hand-written ModelResponse builders in the harness unit tests (agent_loop, steering, media) and in 7 integration-test files.

Measured with tinyanalyzer on this branch, production duplication goes from 10,319 to 8,609 lines (440 groups, down from 458).

Depends on

tinyhumansai/tinyinference#64, which made the three helpers public, is merged. vendor/tinyinference points at merged main (a32eec8). That commit also brings in tinyinference#60 (sanitize changes); the full suite passes with it.

API or behavior changes

  • Additive: Checkpoint::config, Checkpoint::parent_config, testkit::text_response, testkit::tool_call_response.
  • One error message changes. A structured-output value that should be an object, validated against a schema with no type, now reads … must be an object with the declared fields, got <kind>. That is the harness's existing wording, now produced by tinyinference.
  • Nothing else changes in behavior: the moved functions have identical bodies, and the SQL and parameter order of every list query are unchanged.

Validation

Run on this branch after merging upstream main (2cc3982):

  • cargo fmt --check passes
  • cargo clippy --workspace --all-targets --all-features -- -D warnings passes
  • cargo build --workspace --all-targets passes
  • cargo test --workspace --all-features passes

Some runs on this machine had flaky failures in workspace::git, providers::claude_agent_sdk and one tinyagents-runtime prefix-refresh test. All of them write to /tmp, which ran out of disk quota during the run. Each passes on rerun, and none touch code changed here.

Tests

  • New paging/mod_tests.rs: filters, total count versus page, offset numbering after the filters, blank and absent filters, custom clauses.
  • New testkit test for the canned responses.
  • Existing tests cover the rest: run-ledger, session search, checkpointer and structured-output suites all pass unchanged.

Not done, and why

  • crates/tinyagents-harness/src/tool/injected.rs, injected_test.rs and tool/test.rs (777 lines) are also never compiled. They aren't stale copies: injected.rs is an injected-tool-argument feature that was never wired in. Whether to wire it in or delete it is a product call, so it's left alone here.
  • parse_selection is copied in three integration-test and example files. Examples and tests can't share a module without #[path] tricks, so it's left as is.
  • The remaining ~120 hand-written ModelResponse literals across the test suites could move to the new testkit builders, but that's a mechanical follow-up.

senamakel and others added 23 commits October 7, 2026 07:35
Update the vendored tinyinference submodule to the latest commit.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Fixed several issues across the harness: dialect detection now handles edge cases correctly, cache hashing produces stable keys, structured output validation rejects malformed input, and tool prompts render as intended. These corrections prevent subtle mismatches that could cause incorrect agent behaviour.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Delete the SQLite row decoding helpers and the agent-team coordination
operations, which are no longer referenced now that the run ledger handles
these paths elsewhere.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Reordered the tinyinference_llm imports in dialect.rs and dropped an unused ContentBlock import, and removed a stray blank line at the end of cache/hash.rs.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Reworked the run ledger ops to reduce duplication and make the
operation flow easier to follow. Behaviour is unchanged.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Reworked the run ledger ops to reduce duplication and make the
operation flow easier to follow. Behaviour is unchanged.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The paged list functions for agent runs, workflow runs, and agent teams each
rebuilt the same filter, count, and limit/offset SQL by hand. A new ListQuery
helper now builds that query once, so the three call sites only declare their
filters and columns.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Checkpoints can now be persisted to disk and to SQLite in addition to
memory, so graph runs survive process restarts. The boundary module was
updated to route checkpoint reads and writes through the new backends.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Reformatted two `let parent_config` bindings that had been split across
lines so they fit on one line, matching the surrounding style. No
behaviour change.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Introduce a testkit module providing shared helpers for harness tests, along with unit tests covering it and the agent loop. This makes it easier to write consistent tests across the harness crate.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Reformat the tool_call_response helper so the chained with_usage call
stays within the line length limit. No behaviour change.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Add tests for the steering module to exercise its behaviour and guard
against regressions.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The media test helpers now delegate to the shared testkit response builders instead of constructing ModelResponse values by hand, keeping the fixtures consistent with the rest of the harness.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Remove the unused AssistantMessage and ContentBlock imports from the media tests, keeping only Message which is still referenced.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Adjust the integration tests and example to match the updated agent loop
and tool deferral interfaces. The changes keep the end-to-end coverage
aligned with current behaviour.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Wrap the tool_call_response helper chains across lines in the
integration test suite so they satisfy the formatter's line width
limit. No behaviour changes.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Introduce a paging module that splits session history into pages so long
conversations can be loaded incrementally instead of all at once. Tests
cover the new paging behaviour.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
The run-ledger list functions now build their queries with the shared
`PagedQuery` helper instead of a local `ListQuery` struct, which removes
the duplicated paging and filtering logic. The `paging` module is made
public so the run-ledger ops can reach it.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Paging parameters are now set on the query via a page method instead of
being passed to fetch, so callers configure the page alongside the other
filters. This keeps the fetch signature focused on the query itself and
makes the paging bounds reusable across calls.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Session listing and search now build their filters, count, and pagination
through the shared PagedQuery helper instead of hand-rolled SQL assembly.
This removes duplicated parameter-indexing logic while keeping the same
filtering and ordering behaviour.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
@coderabbitai

coderabbitai Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Warning

Review limit reached

  • Run on-demand review

This review includes 29 billable files and costs up to $7.25.

Or wait 5 minutes for your next included review.

Check out review usage here.

View limit details

Limit details: You’ve used all 2 included reviews currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: e9b39ca1-46e4-4587-bb51-58d9993cf42d
📥 Commits

Reviewing files that changed from the base of the PR and between 2cc3982 and 498b999.

📒 Files selected for processing (29)
  • crates/tinyagents-graph/src/checkpoint/file.rs
  • crates/tinyagents-graph/src/checkpoint/mod.rs
  • crates/tinyagents-graph/src/checkpoint/sqlite.rs
  • crates/tinyagents-graph/src/checkpoint/types.rs
  • crates/tinyagents-graph/src/compiled/boundary.rs
  • crates/tinyagents-harness/src/agent_loop/dialect.rs
  • crates/tinyagents-harness/src/agent_loop/mod_tests.rs
  • crates/tinyagents-harness/src/cache/hash.rs
  • crates/tinyagents-harness/src/media/mod_tests.rs
  • crates/tinyagents-harness/src/steering/mod_tests.rs
  • crates/tinyagents-harness/src/structured/validate.rs
  • crates/tinyagents-harness/src/testkit/mod.rs
  • crates/tinyagents-harness/src/testkit/mod_tests.rs
  • crates/tinyagents-harness/src/tool/prompt.rs
  • crates/tinyagents-integration-tests/examples/agent_loop_tools.rs
  • crates/tinyagents-integration-tests/tests/e2e_agent_graph.rs
  • crates/tinyagents-integration-tests/tests/e2e_graph_todos.rs
  • crates/tinyagents-integration-tests/tests/e2e_harness_mock_capabilities.rs
  • crates/tinyagents-integration-tests/tests/e2e_unknown_tool_policy.rs
  • crates/tinyagents-integration-tests/tests/harness_agent_loop.rs
  • crates/tinyagents-integration-tests/tests/tool_deferral.rs
  • crates/tinyagents-session/src/lib.rs
  • crates/tinyagents-session/src/ops.rs
  • crates/tinyagents-session/src/paging/mod.rs
  • crates/tinyagents-session/src/paging/mod_tests.rs
  • crates/tinyagents-session/src/run_ledger/ops.rs
  • crates/tinyagents-session/src/run_ledger/ops/rows.rs
  • crates/tinyagents-session/src/run_ledger/ops/team.rs
  • vendor/tinyinference
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

Update the vendored tinyinference submodule to a newer revision.

Auto-committed-on: dragonfly
Co-authored-by: Medulla <medulla@tinyhumans.ai>
@senamakel senamakel self-assigned this Oct 7, 2026
@senamakel
senamakel marked this pull request as ready for review October 7, 2026 04:58
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 7, 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-10-07T05:24:29.507115Z 498b999 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.

@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: b3460271ae

ℹ️ 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/tinyagents-session/src/paging/mod_tests.rs Outdated
Comment thread crates/tinyagents-session/src/paging/mod.rs Outdated
Co-authored-by: Medulla <medulla@tinyhumans.ai>
@tinysweeper

tinysweeper Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Tiny Sweeper review

Tiny Sweeper completed its review; deterministic results follow.

State: Changes requested
Priority: critical
Reviewed head: 498b9992dc8a
Updated: 1791351996 (Unix time)

Review snapshot

Change surface Files Review signal Count
Production 15 Active findings 2
Tests 13 Noted findings 0
Documentation 0 Resolved findings 117
Configuration 0 Pending checks/questions 0

Completeness: Complete
Test assessment: Test coverage is assessed from changed tests and lane evidence; execution is not claimed without trusted check data.

What changed

No supported behavioral explanation was produced.

Features

  • Added — Checkpoint config helpers: pub fn config() and pub fn parent_config() on Checkpoint (crates/tinyagents-graph/src/checkpoint/types.rs) become the single source of checkpoint addressing, replacing hand-built CheckpointConfig literals in checkpoint/file.rs, checkpoint/mod.rs, checkpoint/sqlite.rs, and compiled/boundary.rs. Behavior is preserved; reduces risk of divergent copies of the thread-id/namespace/parent wiring. (crates/tinyagents-graph/src/checkpoint/types.rs#pub struct BarrierArrivals {, crates/tinyagents-graph/src/checkpoint/file.rs#fn io_err(context: &str, err: impl std::fmt::Display) -> TinyAgentsError {, crates/tinyagents-graph/src/checkpoint/mod.rs#where, crates/tinyagents-graph/src/checkpoint/sqlite.rs#where, crates/tinyagents-graph/src/compiled/boundary.rs#where)
  • Internal refactor — Consolidated run-ledger row lookups: The duplicated row-mapping and connection-scoped get_*_inner helpers previously split across run_ledger/ops/rows.rs and run_ledger/ops/team.rs are folded into run_ledger/ops.rs behind new shared helpers get_logged (entry/exit tracing around with_connection) and get_row_by_id (SELECT ... WHERE id = ?1 with optional row mapping). Getters such as get_workflow_run, get_agent_team, get_agent_team_member, and get_agent_team_task delegate to get_logged. (crates/tinyagents-session/src/run_ledger/ops.rs#pub fn release_agent_team_task(workspace_dir: &Path, team_id: &str, task_id: &st, crates/tinyagents-session/src/run_ledger/ops.rs#pub fn upsert_agent_team(workspace_dir: &Path, upsert: AgentTeamUpsert) -> Resul, crates/tinyagents-session/src/run_ledger/ops.rs#fn map_agent_team_task_row(row: &rusqlite::Row<'_>) -> rusqlite::Result<AgentTea, crates/tinyagents-session/src/run_ledger/ops/rows.rs, crates/tinyagents-session/src/run_ledger/ops/team.rs)
  • Added — Testkit canned model responses: Public text_response and tool_call_response builders in crates/tinyagents-harness/src/testkit/mod.rs give scripted model doubles a single definition: text responses finish with stop, tool-call responses carry exactly one call, no text, and a msg-{call id} message id; both chain with ModelResponse::with_usage for token counts. Test and example files across the harness and integration crates now construct responses through these builders instead of inlining ModelResponse struct literals. (crates/tinyagents-harness/src/testkit/mod.rs#use tinytools::{Tool, ToolResult};, crates/tinyagents-harness/src/tool/prompt.rs#pub fn apply_prompt_tool_calls(mut response: ModelResponse) -> ModelResponse {, crates/tinyagents-harness/src/agent_loop/mod_tests.rs#fn text_response(text: &str, input: u64, output: u64) -> ModelResponse {, crates/tinyagents-integration-tests/examples/agent_loop_tools.rs#impl Tool for CalculatorTool {, crates/tinyagents-integration-tests/tests/harness_agent_loop.rs#fn trajectory(listener: &Arc<RecordingListener>) -> Trajectory {)
  • Internal refactor — Structured-output validation delegated to the tool boundary validator: validate_value in crates/tinyagents-harness/src/structured/validate.rs now delegates to tinyinference_llm::tool::validate_json_value and maps tinyinference_llm::Error::Validation messages into TinyAgentsError::StructuredOutput, deleting the module's own recursive enum/type/required/properties/items checker. The stated effect is one supported-subset definition shared by structured outputs and tool calls, with the existing error contract of naming the first failing instance path retained in the doc comment. (crates/tinyagents-harness/src/structured/validate.rs#use crate::error::{Result, TinyAgentsError};)
  • Removed — Deduplicated tinyinference_llm helpers: The private copies of replace_text_blocks in agent_loop/dialect.rs and tool/prompt.rs and canonical_value in cache/hash.rs are deleted in favor of the exported tinyinference_llm implementations, keeping one canonical implementation of text-block substitution and canonical JSON key ordering. (crates/tinyagents-harness/src/agent_loop/dialect.rs#pub(super) fn recover_text_calls(, crates/tinyagents-harness/src/tool/prompt.rs#pub fn apply_prompt_tool_calls(mut response: ModelResponse) -> ModelResponse {, crates/tinyagents-harness/src/cache/hash.rs#pub(super) fn fnv1a_hex(data: &[u8]) -> String {)

Tests

  • unit — New test canned_responses_carry_their_finish_reason_and_content in crates/tinyagents-harness/src/testkit/mod_tests.rs asserts the shared text_response/tool_call_response constructors produce the expected finish reason, message id (msg-{call id}), empty content for tool-call responses, usage propagation to both message and response, and the single tool call.: Covers the newly shared canned-response contract that many test files now depend on; behavior-focused rather than a file inventory. Execution status not verified in this review. (crates/tinyagents-harness/src/testkit/mod_tests.rs#async fn schema_driven_model_with_no_tools_returns_final_response_immediately())

Findings

  • critical · critique · Add the paging module implementation — This declaration requires `crates/tinyagents-session/src/paging.rs` (or an equivalent module declaration), but that file is absent at this commit. Existing callers already referenc (crates/tinyagents\-session/src/lib\.rs:88)
  • medium · critique · Reject overflowing agent-run pagination offsets — A `u64` offset greater than `i64::MAX` wraps to a negative `i64` here. SQLite then receives an invalid pagination offset, so an otherwise valid request can return an error or incor (crates/tinyagents\-session/src/run\_ledger/ops\.rs:649)

Resolved this pass

  • Keep pagination parameters out of reusable query state
  • Add the paging module implementation
  • Reject negative pagination values
  • Keep pagination parameters out of reusable query state
  • Add the paging module implementation
  • Reject negative pagination values
  • Keep pagination parameters out of reusable query state
  • Add the paging module implementation
  • Reject negative pagination values
  • Keep pagination parameters out of reusable query state
  • Add the paging module implementation
  • Reject negative pagination values
  • Keep pagination parameters out of reusable query state
  • Add the paging module implementation
  • Reject negative pagination values
  • Keep pagination parameters out of reusable query state
  • Add the paging module implementation
  • Reject negative pagination values
  • Keep pagination parameters out of reusable query state
  • Add the paging module implementation
  • Reject negative pagination values
  • Keep pagination parameters out of reusable query state
  • Add the paging module implementation
  • Reject negative pagination values
  • Keep pagination parameters out of reusable query state
  • Add the paging module implementation
  • Reject negative pagination values
  • Keep pagination parameters out of reusable query state
  • Reject negative pagination values
  • Add the paging module implementation
  • Keep pagination parameters out of reusable query state
  • critical — Add the paging module implementation
  • Reject negative pagination values
  • Keep pagination parameters out of reusable query state
  • Add the paging module implementation
  • Reject negative pagination values
  • Keep pagination parameters out of reusable query state
  • Add the paging module implementation
  • Reject negative pagination values
  • Keep pagination parameters out of reusable query state
  • Add the paging module implementation
  • Reject negative pagination values
  • Keep pagination parameters out of reusable query state
  • critical — Add the paging module implementation
  • Reject negative pagination values
  • Keep pagination parameters out of reusable query state
  • Keep pagination parameters out of reusable query state
  • Keep pagination parameters out of reusable query state
  • Add the paging module implementation
  • Reject negative pagination values
  • medium — Keep pagination parameters out of reusable query state
  • medium — Reject negative pagination values
  • medium — Keep pagination parameters out of reusable query state
  • medium — Keep pagination parameters out of reusable query state
  • Keep pagination parameters out of reusable query state
  • Add the paging module implementation
  • Reject negative pagination values
  • Keep pagination parameters out of reusable query state
  • Add the paging module implementation
  • Reject negative pagination values
  • Keep pagination parameters out of reusable query state
  • Add the paging module implementation
  • Keep pagination parameters out of reusable query state
  • Add the paging module implementation
  • Reject negative pagination values
  • Keep pagination parameters out of reusable query state
  • Add the paging module implementation
  • Reject negative pagination values
  • Keep pagination parameters out of reusable query state
  • Add the paging module implementation
  • Reject negative pagination values
  • Keep pagination parameters out of reusable query state
  • Add the paging module implementation
  • Reject negative pagination values
  • Keep pagination parameters out of reusable query state
  • Add the paging module implementation
  • Reject negative pagination values
  • Keep pagination parameters out of reusable query state
  • Add the paging module implementation
  • Reject negative pagination values
  • Keep pagination parameters out of reusable query state
  • Add the paging module implementation
  • Reject negative pagination values
  • Keep pagination parameters out of reusable query state
  • Add the paging module implementation
  • Reject negative pagination values
  • Keep pagination parameters out of reusable query state
  • Add the paging module implementation
  • Reject negative pagination values
  • Keep pagination parameters out of reusable query state
  • critical — Add the paging module implementation
  • Reject negative pagination values
  • Keep pagination parameters out of reusable query state
  • Keep pagination parameters out of reusable query state
  • Keep pagination parameters out of reusable query state
  • Add the paging module implementation
  • Reject negative pagination values
  • Keep pagination parameters out of reusable query state
  • Add the paging module implementation
  • Reject negative pagination values
  • Keep pagination parameters out of reusable query state
  • Add the paging module implementation
  • Reject negative pagination values
  • Keep pagination parameters out of reusable query state
  • Add the paging module implementation
  • Reject negative pagination values
  • Keep pagination parameters out of reusable query state
  • Add the paging module implementation
  • Reject negative pagination values
  • Add the paging module implementation
  • Keep pagination parameters out of reusable query state
  • Reject negative pagination values
  • Keep pagination parameters out of reusable query state
  • Add the paging module implementation
  • Reject negative pagination values
  • Keep pagination parameters out of reusable query state
  • Keep pagination parameters out of reusable query state

Before merge

  • Address Add the paging module implementation (crates/tinyagents\-session/src/lib\.rs).

How this fits together

flowchart LR
  n0["invoke_default"]:::impacted
  n1["invoke_in_context"]:::impacted
  n2["..._node_drives_harness_agent_with_tool_loop"]:::impacted
  n3["CaptureMiddleware"]:::impacted
  n4["...i_step_tool_loop_calls_tool_then_finishes"]:::impacted
  n5["...rn_response_completes_with_one_model_call"]:::impacted
  n2 -->|calls| n1
  n2 -->|tests| n1
  n4 -->|calls| n0
  n4 -->|tests| n0
  n4 -->|uses| n3
  n5 -->|calls| n0
  n5 -->|tests| n0
  n5 -->|uses| n3
  classDef changed fill:#0d4429,stroke:#238636,color:#e6edf3
  classDef impacted fill:#161b22,stroke:#6e7681,color:#c9d1d9
  classDef flagged fill:#5a1e02,stroke:#d93f0b,color:#ffffff
  classDef blocking fill:#67060c,stroke:#f85149,color:#ffffff
Loading
Agent review details

critique

  • Conclusion: Failure
  • Scope reviewed: all assigned evidence
  • Positive: The prior critique finding about the missing paging implementation is resolved: crates/tinyagents-session/src/paging/mod.rs exists with a full implementation and the pagination parameters are no longer accumulated in reusable query state.
  • Positive: One critique-lane finding remains open: reject negative pagination values (rule: validate-pagination-bounds) in crates/tinyagents-session/src/paging/mod.rs.
  • Lane summary: Reviewed 26 files; 2 findings. _Code retrieval was unavailable (model: ladder embeddings returned 400 Bad Request: {"error":{"message":"unknown ladder vectors; known ladders are flash (also chat-v1, flash-v1), instant (also no-think, instant-v1), reasoning (also deepseek), max-reasoning (also max-reasoning-v1), deepseek-flash (also reasoning-v1, agentic-v1), deep (also luna), scribe, uncensored, vectors-oai3 (also embeddings-oai3-v1), vision (also vision-v1, multimodal-v1), image (also images-v1, image-v1), vi), so this review saw the diff alone._ _Memory was unavailable (model: cortex: v1/recall: error sending request for url (http://cortexdb:3141/v1/recall\)\), so this review ran without it._
  • Evidence: crates/tinyagents\-session/src/lib\.rs — Add the paging module implementation
  • Evidence: crates/tinyagents\-session/src/run\_ledger/ops\.rs — Reject overflowing agent-run pagination offsets

security

  • Conclusion: Failure
  • Scope reviewed: all assigned evidence
  • Positive: The security lane considers the change safe to merge; PagedQuery builds fresh parameter lists per fetch and callers pass only hardcoded table/column/order strings, with earlier security findings still tracked as open in history.
  • Lane summary: Reviewed 26 files; 2 findings. (1 already reported on an earlier push) _Code retrieval was unavailable (model: ladder embeddings returned 400 Bad Request: {"error":{"message":"unknown ladder vectors; known ladders are flash (also chat-v1, flash-v1), instant (also no-think, instant-v1), reasoning (also deepseek), max-reasoning (also max-reasoning-v1), deepseek-flash (also reasoning-v1, agentic-v1), deep (also luna), scribe, uncensored, vectors-oai3 (also embeddings-oai3-v1), vision (also vision-v1, multimodal-v1), image (also images-v1, image-v1), vi), so this review saw the diff alone._ _Memory was unavailable (model: cortex: v1/recall: error sending request for url (http://cortexdb:3141/v1/recall\)\), so this review ran without it._

tests

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Positive: The tests lane confirms the earlier findings are resolved: the paging module exists with a full implementation and repeated-fetch no longer accumulates parameters, pinned by the dedicated test, with call sites preserving previous clause ordering and blank-filter semantics.
  • Lane summary: This revision is a consolidation pass: three duplicated implementations (checkpoint config construction, canned `ModelResponse` builders, JSON validation logic) are collapsed into shared helpers, and the session crate's pagination is unified behind a new `PagedQuery` module. The new module is properly tested against real in-memory SQLite, covering filter application, placeholder numbering, pagination and negative-value rejection. Refactors are behavior-preserving and the new code paths are exercised where it matters; safe to merge. _Code retrieval was unavailable (model: ladder embeddings returned 400 Bad Request: {"error":{"message":"unknown ladder vectors; known ladders are flash (also chat-v1, flash-v1), instant (also no-think, instant-v1), reasoning (also deepseek), max-reasoning (also max-reasoning-v1), deepseek-flash (also reasoning-v1, agentic-v1), deep (also luna), scribe, uncensored, vectors-oai3 (also embeddings-oai3-v1), vision (also vision-v1, multimodal-v1), image (also images-v1, image-v1), vi), so this review saw the diff alone._ _Memory was unavailable (model: cortex: v1/recall: error sending request for url (http://cortexdb:3141/v1/recall\)\), so this review ran without it._

commits

  • Conclusion: Neutral
  • Scope reviewed: all assigned evidence
  • Lane summary: Nothing sensitive found in what this pull request commits.

description

  • Conclusion: Success
  • Scope reviewed: all assigned evidence
  • Positive: The description lane confirms the review looks sound: the new PagedQuery builds fresh parameter lists per fetch, callers pass only hardcoded strings, and behavior matches the description.
  • Lane summary: The diff does what the description says: it deletes dead files, swaps private copies of tinyinference helpers for the exported ones, and consolidates checkpoint-config, run-ledger lookup and paged-query code behind shared helpers, with tests for the new paging module. All three earlier findings are fixed. I could not re-verify the tinyinference API surface (`prompt_tools::replace_text_blocks`, `cache::canonical_value`, `tool::validate_json_value`) since the vendor dependency is outside this diff, but the branch's stated validation runs pass and the call sites are consistent with the exports described. One behaviour note is documented in the PR itself and is not a defect. Safe to merge. _Code retrieval was unavailable (model: ladder embeddings returned 400 Bad Request: {"error":{"message":"unknown ladder vectors; known ladders are flash (also chat-v1, flash-v1), instant (also no-think, instant-v1), reasoning (also deepseek), max-reasoning (also max-reasoning-v1), deepseek-flash (also reasoning-v1, agentic-v1), deep (also luna), scribe, uncensored, vectors-oai3 (also embeddings-oai3-v1), vision (also vision-v1, multimodal-v1), image (also images-v1, image-v1), vi), so this review saw the diff alone._ _Memory was unavailable (model: cortex: v1/recall: error sending request for url (http://cortexdb:3141/v1/recall\)\), so this review ran without it._

e2e

  • Conclusion: Neutral
  • Scope reviewed: all assigned evidence
  • Lane summary: No end-to-end harness in this repository: no e2e test files and no e2e workflow.
Evidence and run details
  • Models: gpt-5.6-luna, glm-5.3-flash
  • Spend: $0.059292
  • Tokens: 1166361 input · 58582 output · 112284 cached · 0 embedding
  • Continuity: summary cache chain restarted at the storage ceiling.
Head State Pass summary
b317d36874b0 changes requested 2 active finding(s), 0 resolved finding(s) (at 1791349699)
540cceacc33f ready for maintainer review 1 active finding(s), 8 resolved finding(s) (at 1791350353)
498b9992dc8a ready for maintainer review 3 active finding(s), 22 resolved finding(s) (at 1791351210)
498b9992dc8a changes requested 2 active finding(s), 117 resolved finding(s) (at 1791351996)

tinysweeper 0.1.0

@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: 1 lane(s) blocking, worst finding is critical.

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.0480 · 1,076,373 in / 40,775 out · 91,632 cached (9%)  · gpt-5.6-luna, glm-5.3-flash
critique:    $0.0225 · 425,259 in   / 18,009 out · 47,499 cached (11%) · gpt-5.6-luna, glm-5.3-flash
security:    $0.0238 · 449,752 in   / 15,871 out · 37,669 cached (8%)  · gpt-5.6-luna
tests:       $0.0010 · 120,184 in   / 3,624 out  · 4,928 cached (4%)   · glm-5.3-flash
description: $0.0003 · 38,795 in    / 299 out    · 1,408 cached (4%)   · glm-5.3-flash

Comment thread crates/tinyagents-session/src/paging/mod.rs Outdated
Comment thread crates/tinyagents-session/src/lib.rs
@tinysweeper tinysweeper Bot added the priority: p0 Drop what you are doing. Data loss, a live break, or an exploitable hole. label Oct 7, 2026
Co-authored-by: Medulla <medulla@tinyhumans.ai>

@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.

The previously-blocking findings are resolved. Clearing the changes request.

             $0.0053 · 213,138 in / 8,621 out · 14,578 cached (7%) · gpt-5.6-luna, glm-5.3-flash
critique:    $0.0023 · 52,559 in  / 3,367 out · 8,968 cached (17%) · gpt-5.6-luna, glm-5.3-flash
security:    $0.0019 · 39,102 in  / 1,114 out · 5,610 cached (14%) · gpt-5.6-luna
tests:       $0.0003 · 39,270 in  / 291 out   · 0 cached (0%)      · glm-5.3-flash
description: $0.0003 · 39,373 in  / 246 out   · 0 cached (0%)      · glm-5.3-flash

Comment thread crates/tinyagents-session/src/paging/mod.rs Outdated
@tinysweeper tinysweeper Bot added priority: p2 Soon. Real but survivable — a rough edge, a gap, a thing that will bite later. and removed priority: p0 Drop what you are doing. Data loss, a live break, or an exploitable hole. labels Oct 7, 2026
Co-authored-by: Medulla <medulla@tinyhumans.ai>
@senamakel
senamakel merged commit b8c4e9e into main Oct 7, 2026
10 checks passed
@senamakel
senamakel deleted the dedupe-clones branch October 7, 2026 05:25

@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.

tinysweeper found nothing blocking. Approving.

             $0.0067 · 491,174 in / 20,079 out · 43,857 cached (9%)  · gpt-5.6-luna, glm-5.3-flash
critique:    $0.0025 · 159,186 in / 6,921 out  · 20,847 cached (13%) · gpt-5.6-luna, glm-5.3-flash
security:    $0.0035 · 208,786 in / 9,769 out  · 21,474 cached (10%) · gpt-5.6-luna
tests:       $0.0001 · 39,441 in  / 539 out    · 0 cached (0%)       · glm-5.3-flash
description: $0.0003 · 39,596 in  / 410 out    · 1,408 cached (4%)   · glm-5.3-flash

let (sessions, total) = crate::paging::PagedQuery::default()
.eq("status", status.map(str::to_owned))
.eq("parent_session_id", parent_id.map(str::to_owned))
.page(lim, off)?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

priority medium security confident

Keep pagination parameters out of reusable query state

page stores the request's limit and offset inside the reusable PagedQuery builder. Any later fetch through the same builder inherits that pagination, making query reuse prone to silently returning the wrong page. Keep pagination as fetch-time arguments (or otherwise make it per-fetch state) rather than storing it on the reusable filter builder.

[RULE] stateful-pagination ·

.eq_nonblank("kind", request.kind.as_deref())
.eq_nonblank("parent_run_id", request.parent_run_id.as_deref())
.eq_nonblank("parent_thread_id", request.parent_thread_id.as_deref())
.page(limit, offset)?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

priority medium security confident

Keep pagination parameters out of reusable query state

PagedQuery still stores limit and offset as builder fields, and these list operations pass pagination into that reusable query state. This couples filtering and pagination and allows a query builder reused or extended for another fetch to carry stale paging parameters. Keep pagination as fetch-time arguments rather than fields on the reusable filter builder, so only the final fetch applies the page.


Additional critique observation

priority medium likely

Keep pagination parameters out of reusable query state

[RULE] pagination-state-isolation

The shared PagedQuery is a reusable query builder, but this call stores limit and offset in the same builder state as the filters before fetch executes. If a builder is reused or extended for another page, the pagination values remain attached and can silently affect the later query. Keep page arguments local to fetch, or otherwise ensure pagination state is consumed and cleared when fetching.

[RULE] pagination-state ·

@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 critical.

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.0593 · 1,166,361 in / 58,582 out · 112,284 cached (10%) · gpt-5.6-luna, glm-5.3-flash
critique:    $0.0288 · 509,177 in   / 29,440 out · 53,110 cached (10%)  · gpt-5.6-luna, glm-5.3-flash
security:    $0.0293 · 534,057 in   / 25,436 out · 59,174 cached (11%)  · gpt-5.6-luna
tests:       $0.0004 · 39,431 in    / 126 out    · 0 cached (0%)        · glm-5.3-flash
description: $0.0004 · 39,534 in    / 188 out    · 0 cached (0%)        · glm-5.3-flash

pub mod entry_tree;
mod migrations;
pub mod ops;
mod paging;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

priority critical critique confident

Add the paging module implementation

This declaration requires crates/tinyagents-session/src/paging.rs (or an equivalent module declaration), but that file is absent at this commit. Existing callers already reference crate::paging::PagedQuery, so the crate fails to compile with a missing module error.

[RULE] missing-module ·

})? as usize;

let limit = request.limit.unwrap_or(50).min(500) as i64;
let offset = request.offset.unwrap_or(0) as i64;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

priority medium critique confident

Reject overflowing agent-run pagination offsets

A u64 offset greater than i64::MAX wraps to a negative i64 here. SQLite then receives an invalid pagination offset, so an otherwise valid request can return an error or incorrect results. Use the same checked conversion already applied to workflow runs and teams.

[RULE] integer-overflow ·

@tinysweeper tinysweeper Bot added priority: p0 Drop what you are doing. Data loss, a live break, or an exploitable hole. and removed priority: p2 Soon. Real but survivable — a rough edge, a gap, a thing that will bite later. labels Oct 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

priority: p0 Drop what you are doing. Data loss, a live break, or an exploitable hole.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant