Skip to content

Added: Mock model infrastructure for testing with streaming support#130

Merged
Sewer56 merged 1 commit into
mainfrom
add-mocks
Jun 7, 2026
Merged

Added: Mock model infrastructure for testing with streaming support#130
Sewer56 merged 1 commit into
mainfrom
add-mocks

Conversation

@Sewer56
Copy link
Copy Markdown
Member

@Sewer56 Sewer56 commented Jun 7, 2026

Add mock model infra. Test agents without real LLM provider.

Used for hook tests and hook examples.

  • Cargo.toml - new mock feature flag
  • mock.rs - Streamed<T> wrapper makes non-streaming models streamable. tool_then_text helper: first turn calls tool, second turn returns text + real tool output
  • task.rs - model_override field + with_model_override() on AgentBuildContext. Builder picks override over catalog model when mock enabled
  • lib.rs - expose pub mod mock behind feature gate
use reloaded_code_serdesai::mock::tool_then_text;
use serde_json::json;

let model = tool_then_text("glob", json!({"pattern": "*.rs"}), "Done.");
let ctx = AgentBuildContext::new(...)
    .with_model_override(model);
let agent = ctx.build().await?;

No real provider needed. CI-safe.

- Add `mock` feature flag (gated behind `cfg(any(test, feature = "mock"))`)
- Add `Streamed<T>` wrapper converting non-streaming models to streamable
- Add `tool_then_text` helper for two-turn tool-call→text mock pattern
- Add `with_model_override` on `AgentBuildContext` to inject mock models
- Gate model override logic behind `#[cfg(any(test, feature = "mock"))]`
- Re-export `FunctionModel`, `MockModel`, `TestModel` from mock module
- Add `extract_tool_return_text` helper for rendering tool results
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 7, 2026

Review Change Stack

Warning

Review limit reached

@Sewer56, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 53 minutes and 37 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 56f6fc5b-ab45-4d5a-b756-d560211bf07c

📥 Commits

Reviewing files that changed from the base of the PR and between e672e36 and aec968f.

📒 Files selected for processing (4)
  • src/reloaded-code-serdesai/Cargo.toml
  • src/reloaded-code-serdesai/src/agent_runtime/task.rs
  • src/reloaded-code-serdesai/src/lib.rs
  • src/reloaded-code-serdesai/src/mock.rs

Walkthrough

This pull request adds mock model support to the SerdesAI agent runtime. It introduces a mock feature flag and new mock module containing a Streamed<T> adapter that wraps non-streaming models to provide streaming responses. The module also provides tool_then_text, a helper for creating two-turn mock models that emit a tool call followed by a text response. The agent builder (AgentBuildContext and TaskBuildContext) gains an optional model_override field and a with_model_override() method, allowing tests to inject custom models during agent construction. The build_agent function selects the override model when available under test/mock builds.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Description check ❓ Inconclusive The description is incomplete; it lacks adherence to the repository's template structure and doesn't include a proper explanation section or reference to contributing guidelines. Restructure the description to follow the template with a clear explanation section, and add a reference to the contributing guidelines as specified in the template.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately and specifically summarizes the main change: adding mock model infrastructure with streaming support for testing purposes.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch add-mocks

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
src/reloaded-code-serdesai/src/mock.rs (2)

8-14: 💤 Low value

Clarify the example as pseudo-code.

The example is marked as text and references an undefined agent variable. Consider either:

  • Marking it explicitly as pseudo-code in prose, or
  • Expanding it to a complete rust,no_run example that shows building an agent with AgentBuildContext.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/reloaded-code-serdesai/src/mock.rs` around lines 8 - 14, The doc example
in mock.rs uses a ```text``` block and references an undefined `agent`, which is
confusing; update the example to either label it clearly as pseudocode in prose
(e.g., add a sentence before the code saying "The following is pseudocode") or
convert it into a runnable snippet by changing the fence to `rust,no_run` and
showing how to build an agent (use `AgentBuildContext` to construct an `agent`)
before calling `agent.run_stream(...)`; ensure symbols `Streamed`,
`tool_then_text`, `agent.run_stream`, and `AgentBuildContext` are mentioned so
readers can locate the related API.

204-235: ⚖️ Poor tradeoff

Consider handling the Multiple variant explicitly.

The function doesn't explicitly extract items from the Multiple variant ({"type":"multiple","items":[...]}). It falls through to the pretty-print fallback, which works but may not produce the most readable output.

For better readability, consider iterating over the items array and recursively extracting text from each item.

💡 Optional enhancement
     // Error message field.
     if let Some(msg) = val.get("message").and_then(|v| v.as_str()) {
         return format!("[error] {msg}");
     }
 
+    // Multiple items field.
+    if let Some(items) = val.get("items").and_then(|v| v.as_array()) {
+        let extracted: Vec<String> = items
+            .iter()
+            .filter_map(|item| {
+                // Each item might have content/message fields
+                item.get("content")
+                    .and_then(|v| v.as_str())
+                    .map(|s| s.to_string())
+                    .or_else(|| {
+                        item.get("message")
+                            .and_then(|v| v.as_str())
+                            .map(|s| s.to_string())
+                    })
+            })
+            .collect();
+        if !extracted.is_empty() {
+            return extracted.join("\n");
+        }
+    }
+
     // Fallback: pretty-print the whole thing.
     serde_json::to_string_pretty(&val).unwrap_or_else(|_| format!("{:?}", tr.content))
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/reloaded-code-serdesai/src/mock.rs` around lines 204 - 235,
extract_tool_return_text currently falls back to pretty-print for the "multiple"
variant; add explicit handling for {"type":"multiple","items":[...]} by checking
val.get("items") for an array, iterating the items, and concatenating a
user-friendly representation (e.g., newline-separated) of each item’s extracted
text. Implement this by either converting each serde_json::Value item into the
same shape inspected by extract_tool_return_text (or add a small helper that
accepts a Value and reuses the existing extraction logic) so you recursively
extract text for nested items from the ToolReturnPart's content.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/reloaded-code-serdesai/src/mock.rs`:
- Around line 8-14: The doc example in mock.rs uses a ```text``` block and
references an undefined `agent`, which is confusing; update the example to
either label it clearly as pseudocode in prose (e.g., add a sentence before the
code saying "The following is pseudocode") or convert it into a runnable snippet
by changing the fence to `rust,no_run` and showing how to build an agent (use
`AgentBuildContext` to construct an `agent`) before calling
`agent.run_stream(...)`; ensure symbols `Streamed`, `tool_then_text`,
`agent.run_stream`, and `AgentBuildContext` are mentioned so readers can locate
the related API.
- Around line 204-235: extract_tool_return_text currently falls back to
pretty-print for the "multiple" variant; add explicit handling for
{"type":"multiple","items":[...]} by checking val.get("items") for an array,
iterating the items, and concatenating a user-friendly representation (e.g.,
newline-separated) of each item’s extracted text. Implement this by either
converting each serde_json::Value item into the same shape inspected by
extract_tool_return_text (or add a small helper that accepts a Value and reuses
the existing extraction logic) so you recursively extract text for nested items
from the ToolReturnPart's content.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 08060a1e-61ab-493f-bcba-fb3172301102

📥 Commits

Reviewing files that changed from the base of the PR and between d03fa49 and e672e36.

📒 Files selected for processing (4)
  • src/reloaded-code-serdesai/Cargo.toml
  • src/reloaded-code-serdesai/src/agent_runtime/task.rs
  • src/reloaded-code-serdesai/src/lib.rs
  • src/reloaded-code-serdesai/src/mock.rs

@Sewer56 Sewer56 merged commit 7fd5f6f into main Jun 7, 2026
22 checks passed
@Sewer56 Sewer56 deleted the add-mocks branch June 7, 2026 17:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant