Add GQL response format to Orbit queries

What does this MR do and why?

REST callers of POST /api/v4/orbit/query and POST /api/v4/orbit/query/:name, and MCP callers of query_graph, can now pass response_format: "gql" (MCP: format: "gql"). Results come back as a plain-text table with one column per returned alias. REST responds with text/plain; MCP responds with text content.

The format is gated by the per-user orbit_gql_queries flag, the same flag that enables GQL query input (!256465 (merged)). With the flag off, gql is rejected with 400 "GQL response format is not enabled"; MCP returns a tool error with the same text. raw and llm are unchanged in both flag states. raw stays the REST default; llm stays the MCP default. Other Orbit endpoints, such as the schema endpoint, still accept only raw and llm.

Workhorse maps gql to the new protobuf response format and writes it the same way it writes llm. Workhorse does not check for an older backend, so deploy the Orbit backend before enabling the flag. No changelog entry: the feature is behind a default-off flag.

workhorse/go.mod pins the Orbit protobuf client to v0.137.0, the first release with the GQL format from gitlab-org/orbit/knowledge-graph!2661 (merged).

References

Screenshots or screen recordings

No UI changes. The GDK response for a user-group traversal:

+------------------------------------------------------------------------------------+
| u                                             | g                                  |
+------------------------------------------------------------------------------------+
| (:User {id: 1, username: "root"})             | (:Group {id: 22, name: "Toolbox"}) |
| (:User {id: 6, username: "georgine_keebler"}) | (:Group {id: 22, name: "Toolbox"}) |
+------------------------------------------------------------------------------------+

2 rows, more available

How to set up and validate locally

  1. Run Orbit from knowledge-graph main at or after the merge of gitlab-org/orbit/knowledge-graph!2661 (merged).

  2. Check out this branch in GDK, run make -C workhorse, and restart rails-web and gitlab-workhorse.

  3. In a Rails console: Feature.enable(:orbit_gql_queries, user). Restart rails-web (Rails caches flag values per process for about a minute).

  4. Send:

    curl --request POST \
      --header "PRIVATE-TOKEN: <your_access_token>" \
      --header "Content-Type: application/json" \
      --data '{"query":"MATCH (p:Project) WHERE p.id IS NOT NULL RETURN p ORDER BY p.id LIMIT 3","response_format":"gql"}' \
      --url "http://127.0.0.1:3000/api/v4/orbit/query"
  5. Disable the flag, restart rails-web, and send the same request with a JSON DSL query. Expect HTTP 400.

Validation results and GDK setup
  • Rails request and unit specs: 346 examples, 0 failures, 26 pending shared examples. Workhorse Orbit package tests pass, including with -race. RuboCop, Vale, and markdownlint pass.
  • The new flag-off specs and Workhorse GQL tests fail against the code before this MR.
  • 49 HTTP checks pass across three local GDK runs, with real Rails auth and no mocks:
    • Flag on (17): REST query and named query return JSON for raw, text for llm, a table for gql, and raw by default. MCP returns all three formats and llm by default. Empty results and aggregates render as tables.
    • Flag off (15): raw and llm work with JSON queries. gql is rejected on REST, named queries, and MCP.
    • Both states: an invalid format returns 400, the schema endpoint still rejects gql, and a missing token returns 401. The third run repeated the flag-on checks after restoring the flag.
  • Setup: GDK at commit 11884e338e19 with Workhorse rebuilt. Orbit at knowledge-graph main 5f507a706, which includes the backend MR, against existing local v100 graph data. The flag was toggled for the root user and then restored.

MR acceptance checklist

Evaluated against the MR acceptance checklist.

  • Specs cover the flag gate and the gql format on REST, named queries, and MCP.
  • Verified end to end on local GDK with the flag on and off.
  • raw and llm behavior unchanged.
  • Orbit release that includes the GQL format published (v0.137.0) and go.mod pin bumped to it.
  • Orbit backend deployed before the flag is enabled.
Edited by Aaron Algutifan

Merge request reports

Loading
Loading