Skip to content

fix: gateway_execute args schema so callers can actually pass arguments - #107

Merged
getappz merged 3 commits into
masterfrom
fix-gateway-execute-args
Jul 8, 2026
Merged

fix: gateway_execute args schema so callers can actually pass arguments#107
getappz merged 3 commits into
masterfrom
fix-gateway-execute-args

Conversation

@getappz

@getappz getappz commented Jul 8, 2026

Copy link
Copy Markdown
Owner

Summary

  • GatewayExecuteRequest.args was typed as bare serde_json::Value, which schemars renders with no type constraint — callers had no signal to send a nested JSON object, so gateway_execute could never actually be invoked with arguments (confirmed live via dogfooding against the engram backend).
  • Retyped to Option<serde_json::Map<String, serde_json::Value>>, which schemars renders as {"type": ["object", "null"]}. Runtime semantics are unchanged (accept Object or Null, reject anything else).

Test plan

  • cargo test — 206/206 passing
  • Live dogfood: gateway_searchgateway_execute(engram, memory_context, {...}) succeeds end-to-end post-fix

Summary by CodeRabbit

  • New Features

    • Added clearer session-start guidance for on-demand memory lookup, including how to search and execute tools when needed.
  • Bug Fixes

    • Improved tool argument handling by representing tool arguments as structured object maps and correctly treating omitted arguments as null.
    • Updated and extended validation so generated request schemas match the new argument behavior.

getappz added 2 commits July 9, 2026 02:21
serde_json::Value has no fixed JSON type, so schemars emitted a typeless
schema for GatewayExecuteRequest.args — callers had no signal to send a
nested object rather than a stringified one, and mcp_stdio's call() then
rejected the stringified value. Dogfooding gateway_execute against a real
downstream server reproduced this on every non-empty args call. Switching
to Option<Map<String, Value>> makes schemars emit {"type": ["object",
"null"]}, a real hint, while the runtime behavior (Object or Null, nothing
else) is unchanged.
@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds a “Memory on-demand” line to the session-start message and updates gateway_execute so args is an optional typed object map, with matching test and schema updates.

Changes

Memory nudge and typed gateway args

Layer / File(s) Summary
Session-start memory guidance
src/hook.rs
Adds a “Memory on-demand” line to session_start_message explaining the gateway_search(query) to gateway_execute(server="engram") flow, plus a test that checks the message text.
Typed gateway_execute args
src/mcp_server.rs
Changes GatewayExecuteRequest.args to Option<serde_json::Map<String, serde_json::Value>>, converts it to Value::Object or Value::Null in gateway_execute, updates existing request tests, and adds a schema test for the object-or-null shape.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

  • getappz/agentflare#103: Also updates src/hook.rs session-start guidance and its tests around tool usage instructions.
  • getappz/agentflare#104: Closely related to the gateway_execute request shape, serialization, and schema behavior in src/mcp_server.rs.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: fixing gateway_execute args schema so callers can pass arguments.
Description check ✅ Passed The description covers Summary and Test plan well, but it omits the template's Notes for reviewers section.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix-gateway-execute-args

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

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

🧹 Nitpick comments (1)
src/mcp_server.rs (1)

73-80: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Add a schema regression test for args.

This PR’s key contract is the generated schema hint, but the updated tests only exercise runtime construction. Please lock the args schema to object/null so future type changes don’t silently reintroduce the typeless Value schema.

Example regression check
+    #[test]
+    fn gateway_execute_args_schema_is_object_or_null() {
+        let schema = schemars::schema_for!(GatewayExecuteRequest);
+        let schema_json = serde_json::to_value(&schema).unwrap();
+        let args_schema = schema_json
+            .get("properties")
+            .and_then(|properties| properties.get("args"))
+            .expect("args schema should be present");
+
+        let rendered = args_schema.to_string();
+        assert!(rendered.contains("\"object\""), "{rendered}");
+        assert!(rendered.contains("\"null\""), "{rendered}");
+    }
🤖 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/mcp_server.rs` around lines 73 - 80, Add a schema regression test for the
`args` field in `McpServer` so the generated schemars output is locked to an
object-or-null shape. Extend the existing test coverage around `args:
Option<serde_json::Map<String, serde_json::Value>>` to assert the schema
includes an object hint rather than a typeless `Value` schema, and verify the
`McpServer`/`args` contract directly so future type changes are caught.
🤖 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/mcp_server.rs`:
- Around line 73-80: Add a schema regression test for the `args` field in
`McpServer` so the generated schemars output is locked to an object-or-null
shape. Extend the existing test coverage around `args:
Option<serde_json::Map<String, serde_json::Value>>` to assert the schema
includes an object hint rather than a typeless `Value` schema, and verify the
`McpServer`/`args` contract directly so future type changes are caught.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 9503b312-1bd2-41be-a6bf-5121f63fafb4

📥 Commits

Reviewing files that changed from the base of the PR and between 2cb527a and 23e3571.

📒 Files selected for processing (2)
  • src/hook.rs
  • src/mcp_server.rs

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

🧹 Nitpick comments (1)
src/mcp_server.rs (1)

738-741: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Assert the schema type structurally.

to_string().contains(...) can pass if "object"/"null" appear outside the actual type constraint. Since this test locks the public gateway_execute.args contract, inspect the type field directly.

Proposed test tightening
-        let rendered = args_schema.to_string();
-        assert!(rendered.contains("\"object\""), "{rendered}");
-        assert!(rendered.contains("\"null\""), "{rendered}");
+        let mut types: Vec<_> = args_schema
+            .get("type")
+            .and_then(serde_json::Value::as_array)
+            .expect("args schema type array")
+            .iter()
+            .filter_map(serde_json::Value::as_str)
+            .collect();
+        types.sort_unstable();
+        assert_eq!(types, vec!["null", "object"], "{args_schema}");
🤖 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/mcp_server.rs` around lines 738 - 741, The test in the schema assertion
block is too loose because it checks the rendered JSON string for "object" and
"null" instead of validating the actual type structure. Update the assertions
around the args schema in the relevant test to inspect the schema JSON directly
via the args_schema value, specifically checking the type field (or equivalent
structural representation) for the expected object/null shape. Keep the change
localized to the test that verifies the gateway_execute.args contract.
🤖 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/mcp_server.rs`:
- Around line 738-741: The test in the schema assertion block is too loose
because it checks the rendered JSON string for "object" and "null" instead of
validating the actual type structure. Update the assertions around the args
schema in the relevant test to inspect the schema JSON directly via the
args_schema value, specifically checking the type field (or equivalent
structural representation) for the expected object/null shape. Keep the change
localized to the test that verifies the gateway_execute.args contract.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 75c60914-0468-4da5-8b92-6a0c73c7a1cd

📥 Commits

Reviewing files that changed from the base of the PR and between 23e3571 and 4eb174e.

📒 Files selected for processing (1)
  • src/mcp_server.rs

@getappz
getappz merged commit fe770fb into master Jul 8, 2026
9 checks passed
@getappz
getappz deleted the fix-gateway-execute-args branch July 8, 2026 21:12
getappz added a commit that referenced this pull request Aug 13, 2026
…task-level test (#480)

* fix(daemon): make binary-staleness watchdog failures observable, add task-level test

Item #107: a live daemon kept running for 19+ minutes after its on-disk
binary was replaced, missing ~19 BINARY_STALENESS_CHECK_INTERVAL checks,
with no log line ever indicating whether the watchdog was armed. The
comparison logic in BinarySnapshot::is_stale() already had unit coverage
and reads correctly; what was missing was any signal, at the live-daemon
level, of whether the watchdog task ever armed in the first place --
capture() failing at startup and the watchdog silently no-op'ing was
indistinguishable from "armed, nothing stale yet".

Split the polling loop out of spawn_binary_staleness_watchdog into
daemon::wait_for_stale so it has its own test coverage independent of
is_stale()'s unit tests -- exercised here with a simulated tokio clock
covering multiple ticks and a real on-disk file swap. Also log explicitly
on both the armed and disabled-at-startup paths so a silent failure to
arm shows up in daemon.log instead of looking identical to normal
operation.

Agentflare-Agent: claude-code
Agentflare-Branch: task/107-binary-staleness-watchdog-doesn-t-self-r
Agentflare-Item: 107

* chore: regenerate workspace-hack for tokio test-util feature

The new #[tokio::test(start_paused = true)] regression test in
src/daemon.rs pulled in tokio's test-util feature, changing the
workspace-wide feature union cargo hakari computes. Regenerate
agentflare-workspace-hack/Cargo.toml to match, which is what CI's
own cargo hakari generate --diff check enforces.

Agentflare-Agent: claude-code
Agentflare-Branch: task/107-binary-staleness-watchdog-doesn-t-self-r
Agentflare-Item: 107

---------

Co-authored-by: shiva <shiva@gosysinfo.tech>
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