Skip to content

[#1195] Simplify Command Router HTTP query execution - #1214

Open
marcocapozzoli wants to merge 11 commits into
masterfrom
masc/1195-update-endpoints
Open

[#1195] Simplify Command Router HTTP query execution#1214
marcocapozzoli wants to merge 11 commits into
masterfrom
masc/1195-update-endpoints

Conversation

@marcocapozzoli

@marcocapozzoli marcocapozzoli commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator

Summary

Simplifies how the Command Router HTTP API builds and runs query executions.

Changes

  • Build a dispatch-ready proxy per HTTP request via HttpCommandProxyFactory / ProxyParametersFromJson, applying request params directly onto that proxy.
  • Stop syncing/mutating shared peer-store state when creating query executions.
  • Reject unknown/unsupported parameters at proxy creation time.
  • Remove max_concurrent_executions; concurrency is bounded only by thread_pool_size.

@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 57c6145e-2b13-4e15-9970-789221efb90e

📥 Commits

Reviewing files that changed from the base of the PR and between d37f533 and 98914fb.

📒 Files selected for processing (1)
  • src/tests/cpp/BUILD
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/tests/cpp/BUILD

  • Changed the HTTP API to accept only { "command": "query", "params": { ... } }. Added proxy creation and JSON parameter conversion with validation and descriptive errors.
  • Changed WebSocket events to use execution_status and query_answers envelopes. Preserved caller parameters during HTTP dispatch and separated HTTP and regular command execution paths.
  • Removed max_concurrent_executions. Queue admission and pending-count release now cover shutdown and cancellation paths. Review counter handling and thread safety carefully.
  • Added token joining, type conversion, validation, and parameter copies on the HTTP request path. These operations can increase allocation and latency costs for high-volume queries.
  • Updated C++ and client tests for the new schema, event envelopes, validation, cancellation, parallel queries, parameter preservation, and WebSocket lifecycle behavior. Coverage is present in src/tests/cpp/command_router_http_api_test.cc and src/tests/scripts/command_router_http_client.py.

Walkthrough

The HTTP API now accepts {command, params} query requests. A proxy factory converts JSON parameters into router properties, processor dispatch preserves caller parameters, execution events use structured envelopes, and admission no longer rejects requests by concurrent-execution limit.

Changes

HTTP Query Router

Layer / File(s) Summary
Structured execution events
src/agents/command_router/http_api/CommandExecution.*, src/tests/cpp/command_router_http_api_test.cc, src/tests/scripts/command_router_http_client.py
CommandExecution stores command parameters and emits query_answers and execution_status envelopes. Tests validate lifecycle, answer, error, abort, and cancellation payloads.
HTTP proxy construction and parameter conversion
src/agents/command_router/http_api/ProxyParametersFromJson.*, src/agents/command_router/http_api/HttpCommandProxyFactory.*, src/agents/command_router/http_api/BUILD, src/tests/cpp/command_router_http_api_test.cc, src/tests/cpp/BUILD
The factory validates query syntax and tokens. JSON values convert to typed proxy properties, with rejection for unknown, unsupported, malformed, or empty values.
Processor parameter preservation
src/agents/command_router/BusCommandRouterProcessor.*
HTTP dispatch copies caller parameters into the processor proxy and skips peer-parameter loading. Regular commands retain peer-parameter loading.
HTTP API request and admission flow
src/agents/command_router/http_api/CommandRouterHttpAPI.*, src/agents/command_router/http_api/CommandRouterHttpAPIConfig.*, src/tests/cpp/command_router_http_api_test.cc, src/tests/scripts/command_router_http_client.py
The API accepts only query, queues admitted executions without concurrent-limit rejection, releases pending accounting, and dispatches through HttpCommandProxyFactory. Parallel and websocket tests cover request isolation and lifecycle behavior.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant CommandRouterHttpAPI
  participant HttpCommandProxyFactory
  participant ProxyParametersFromJson
  participant BusCommandRouterProcessor
  Client->>CommandRouterHttpAPI: Submit command and params
  CommandRouterHttpAPI->>HttpCommandProxyFactory: Create query proxy
  HttpCommandProxyFactory->>ProxyParametersFromJson: Set proxy properties
  CommandRouterHttpAPI->>BusCommandRouterProcessor: Dispatch query with copied parameters
  BusCommandRouterProcessor-->>CommandRouterHttpAPI: Publish execution events
  CommandRouterHttpAPI-->>Client: Return status and answer envelopes
Loading

Possibly related PRs

  • singnet/das#1156: Introduced the HTTP command-router infrastructure updated here.
  • singnet/das#1165: Updated the same execution, API, and HTTP test components.
  • singnet/das#1188: Modified processor HTTP dispatch and parameter synchronization.

Suggested reviewers: andre-senna, ccgsnet

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: simplifying Command Router HTTP query execution.
Description check ✅ Passed The description directly explains the proxy creation, parameter handling, shared-state changes, and concurrency configuration updates.
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.
Tests For Behavior Changes ✅ Passed Production HTTP/router behavior changed, and src/tests/cpp/command_router_http_api_test.cc adds coverage for factory validation, parameter preservation, request validation, event envelopes, cancell...
✨ 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 masc/1195-update-endpoints

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.

@marcocapozzoli marcocapozzoli changed the title [#1195] Draft [#1195] Simplify Command Router HTTP query execution Jul 31, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (7)
src/agents/command_router/http_api/CommandExecution.h (1)

38-41: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Consider taking params by value to allow a move.

The constructor copies the whole params object. The HTTP layer parses the request body and does not need it afterwards. A by-value parameter plus std::move removes one deep copy of the JSON tree per execution.

♻️ Proposed signature change
     CommandExecution(const string& execution_id,
                      const string& command,
-                     const json& params,
+                     json params,
                      size_t max_events = DEFAULT_MAX_EVENTS);

Then in CommandExecution.cc:

CommandExecution::CommandExecution(const string& execution_id,
                                   const string& command,
                                   json params,
                                   size_t max_events)
    : execution_id(execution_id),
      command(command),
      params(std::move(params)),
      max_events(max_events) {
🤖 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/agents/command_router/http_api/CommandExecution.h` around lines 38 - 41,
Update the CommandExecution constructor declaration and definition to accept
params by value, then move it into the member initializer for params. Preserve
the existing behavior for callers that pass lvalues while allowing HTTP
request-owned JSON objects to avoid an extra deep copy.
src/tests/cpp/command_router_http_api_test.cc (1)

815-832: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Optional: exit the polling loop early.

The loop always runs all 100 attempts, so it issues 400 HTTP requests and sleeps about 5 seconds even after every execution reaches a terminal state. Break once max_observed_running reaches kThreadPoolSize and all executions are terminal.

🤖 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/tests/cpp/command_router_http_api_test.cc` around lines 815 - 832, Update
the polling loop around max_observed_running to exit early once
max_observed_running reaches kThreadPoolSize and every execution has reached a
terminal state. Track or derive terminal completion while iterating
execution_ids, preserve the existing assertions and final expectations, and
retain the sleep only when another polling attempt is needed.
src/agents/command_router/http_api/CommandExecution.cc (2)

197-210: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Optional: fold the repeated status-envelope emission into one helper.

The same three-step sequence (build status params, add extras, publish envelope) now appears in mark_running, mark_completed, mark_error, mark_aborted, mark_error_unless_terminal, and mark_aborted_unless_terminal. A single private helper keeps the envelope shape in one place, so a future field addition cannot miss one path.

♻️ Sketch
void CommandExecution::publish_status_locked(json extra) {
    json params = this->status_params_locked();
    for (auto& [key, value] : extra.items()) {
        params[key] = value;
    }
    this->publish_event_locked(this->make_envelope_locked(COMMAND_EXECUTION_STATUS, std::move(params)));
}
🤖 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/agents/command_router/http_api/CommandExecution.cc` around lines 197 -
210, Optionally add a private CommandExecution helper such as
publish_status_locked to centralize status parameter construction, merging any
extra fields, and COMMAND_EXECUTION_STATUS envelope publication. Replace the
repeated emission sequences in mark_running, mark_completed, mark_error,
mark_aborted, mark_error_unless_terminal, and mark_aborted_unless_terminal with
this helper while preserving each method’s existing status updates and extras.

125-127: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Avoid the extra copy in object construction from the initializer list.

make_envelope_locked creates const std::pair elements for the initializer list, so std::move(params) only moves into that temporary pair. nlohmann::json then copies the pair into the new object before publish_chunk dumps the envelope while still holding mtx_. Build the envelope first, assign params, and return it.

♻️ Proposed fix
 json CommandExecution::make_envelope_locked(const string& command, json params) const {
-    return {{"command", command}, {"params", std::move(params)}};
+    json envelope = json::object();
+    envelope["command"] = command;
+    envelope["params"] = std::move(params);
+    return envelope;
 }
🤖 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/agents/command_router/http_api/CommandExecution.cc` around lines 125 -
127, Update CommandExecution::make_envelope_locked to construct the JSON
envelope first, then assign the moved params to its "params" member before
returning it. Replace the initializer-list construction so std::move(params)
transfers directly into the JSON object without the intermediate pair copy.
src/agents/command_router/http_api/ProxyParametersFromJson.cc (1)

10-207: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add section banners to group the conversion helpers.

This file has six static methods and no section banners. The coding guideline for .cc files under src/**/*.cc requires grouping methods with banners like // ---.... Add a banner between the private per-type converters (set_bool through set_string) and the public set dispatcher.

Based on coding guidelines ("Group C++ methods in .cc files with section banners") and path instructions (".cc files use section banners like // ---... between API groups"), which apply to this file.

🤖 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/agents/command_router/http_api/ProxyParametersFromJson.cc` around lines
10 - 207, Add a section banner comment between the private conversion helpers
ending with set_string and the public set dispatcher, using the repository’s
established // ---... banner style. Do not alter the conversion logic or
dispatcher behavior.

Sources: Coding guidelines, Path instructions

src/agents/command_router/http_api/CommandRouterHttpAPI.cc (1)

120-147: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Move body["params"] instead of copying it.

body is not used again after line 128. Move body["params"] into the local params variable instead of copying it, to avoid a full JSON deep copy for every scheduled execution (this can matter when tokens arrays are large).

Based on path instructions ("Flag unnecessary copies of large objects (Properties, vector, string, maps) — prefer const ref, std::move()"), which applies to this hot request-handling path.

♻️ Proposed fix to move the params JSON instead of copying it
             const string command = body["command"].get<string>();
-            const json params = body["params"];
+            json params = std::move(body["params"]);
🤖 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/agents/command_router/http_api/CommandRouterHttpAPI.cc` around lines 120
- 147, Update the local params initialization in the command scheduling flow to
move body["params"] rather than copy the JSON value, since body is not used
afterward. Preserve the existing validation and pass the moved params to
CommandExecution.

Source: Path instructions

src/agents/command_router/BusCommandRouterProcessor.cc (1)

86-90: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Move parameters into processor_proxy for the in-process dispatch path.

BusCommandRouterProxy::parameters is inherited from BaseQueryProxy, not a BusCommandRouterProxy field; poll_stream reads parameters from the router proxy it receives. Use processor_proxy->parameters = std::move(caller_proxy->parameters) so the HTTP path avoids one redundant copy while keeping the streamed parameters populated.

🤖 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/agents/command_router/BusCommandRouterProcessor.cc` around lines 86 - 90,
Update the in-process dispatch assignments in BusCommandRouterProcessor to move
parameters from caller_proxy into processor_proxy, matching the existing command
and args moves. Preserve the populated parameters state consumed by poll_stream
while avoiding the redundant copy.
🤖 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.

Inline comments:
In `@src/tests/cpp/command_router_http_api_test.cc`:
- Around line 380-383: Make static initialization consistent in the HTTP
command-router tests: ensure CommandRouterHttpClient is registered before port
allocation while retaining BUS_COMMAND_ROUTER and the 49400–49499 range. Update
initialize_test_service_bus_statics_once or the surrounding
initialize_http_command setup, or initialize both command types together before
these tests run.

In `@src/tests/scripts/command_router_http_client.py`:
- Around line 76-87: Update the query request configuration in the
command-router HTTP client test so the cancellation scenario remains valid:
increase max_answers above 1 to keep execution running long enough for
cancellation, or adjust the later status assertions and wait_for_status call to
accept both aborted and completed terminal outcomes.

---

Nitpick comments:
In `@src/agents/command_router/BusCommandRouterProcessor.cc`:
- Around line 86-90: Update the in-process dispatch assignments in
BusCommandRouterProcessor to move parameters from caller_proxy into
processor_proxy, matching the existing command and args moves. Preserve the
populated parameters state consumed by poll_stream while avoiding the redundant
copy.

In `@src/agents/command_router/http_api/CommandExecution.cc`:
- Around line 197-210: Optionally add a private CommandExecution helper such as
publish_status_locked to centralize status parameter construction, merging any
extra fields, and COMMAND_EXECUTION_STATUS envelope publication. Replace the
repeated emission sequences in mark_running, mark_completed, mark_error,
mark_aborted, mark_error_unless_terminal, and mark_aborted_unless_terminal with
this helper while preserving each method’s existing status updates and extras.
- Around line 125-127: Update CommandExecution::make_envelope_locked to
construct the JSON envelope first, then assign the moved params to its "params"
member before returning it. Replace the initializer-list construction so
std::move(params) transfers directly into the JSON object without the
intermediate pair copy.

In `@src/agents/command_router/http_api/CommandExecution.h`:
- Around line 38-41: Update the CommandExecution constructor declaration and
definition to accept params by value, then move it into the member initializer
for params. Preserve the existing behavior for callers that pass lvalues while
allowing HTTP request-owned JSON objects to avoid an extra deep copy.

In `@src/agents/command_router/http_api/CommandRouterHttpAPI.cc`:
- Around line 120-147: Update the local params initialization in the command
scheduling flow to move body["params"] rather than copy the JSON value, since
body is not used afterward. Preserve the existing validation and pass the moved
params to CommandExecution.

In `@src/agents/command_router/http_api/ProxyParametersFromJson.cc`:
- Around line 10-207: Add a section banner comment between the private
conversion helpers ending with set_string and the public set dispatcher, using
the repository’s established // ---... banner style. Do not alter the conversion
logic or dispatcher behavior.

In `@src/tests/cpp/command_router_http_api_test.cc`:
- Around line 815-832: Update the polling loop around max_observed_running to
exit early once max_observed_running reaches kThreadPoolSize and every execution
has reached a terminal state. Track or derive terminal completion while
iterating execution_ids, preserve the existing assertions and final
expectations, and retain the sleep only when another polling attempt is needed.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: f496abbe-9d1d-48a5-a416-7d9b6f730b64

📥 Commits

Reviewing files that changed from the base of the PR and between 1be99f7 and d9506b7.

📒 Files selected for processing (16)
  • src/agents/command_router/BusCommandRouterProcessor.cc
  • src/agents/command_router/BusCommandRouterProcessor.h
  • src/agents/command_router/http_api/BUILD
  • src/agents/command_router/http_api/CommandExecution.cc
  • src/agents/command_router/http_api/CommandExecution.h
  • src/agents/command_router/http_api/CommandRouterHttpAPI.cc
  • src/agents/command_router/http_api/CommandRouterHttpAPI.h
  • src/agents/command_router/http_api/CommandRouterHttpAPIConfig.cc
  • src/agents/command_router/http_api/CommandRouterHttpAPIConfig.h
  • src/agents/command_router/http_api/HttpCommandProxyFactory.cc
  • src/agents/command_router/http_api/HttpCommandProxyFactory.h
  • src/agents/command_router/http_api/ProxyParametersFromJson.cc
  • src/agents/command_router/http_api/ProxyParametersFromJson.h
  • src/tests/cpp/BUILD
  • src/tests/cpp/command_router_http_api_test.cc
  • src/tests/scripts/command_router_http_client.py
💤 Files with no reviewable changes (1)
  • src/agents/command_router/http_api/CommandRouterHttpAPIConfig.cc

Comment thread src/tests/cpp/command_router_http_api_test.cc
Comment thread src/tests/scripts/command_router_http_client.py
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