feat(devtools): add Reasoning Engine server compatibility routes and headers parser (Agent Engine Deployment Artifact registry fix part 1)#440
Open
AmaadMartin wants to merge 3 commits into
Conversation
added 2 commits
June 16, 2026 12:11
…oning Engine routes
8 tasks
kalenkevich
reviewed
Jun 16, 2026
Comment on lines
+784
to
+804
| let session = await this.sessionService.getSession({ | ||
| appName, | ||
| userId, | ||
| sessionId, | ||
| }); | ||
| if (!session) { | ||
| this.logger.info( | ||
| `Session ${sessionId} not found. Creating it automatically.`, | ||
| ); | ||
| session = await this.sessionService.createSession({ | ||
| appName, | ||
| userId, | ||
| sessionId, | ||
| state: {}, | ||
| }); | ||
| } | ||
| await using agentFile = await this.agentLoader.getAgentFile(appName); | ||
| const agent = await agentFile.load(); | ||
| const runner = await this.getRunner(agent, appName); | ||
| const events: Event[] = []; | ||
| const abortController = new AbortController(); |
Collaborator
There was a problem hiding this comment.
we have getOrCreateSession
Collaborator
Author
There was a problem hiding this comment.
Good point. Refactored to use the existing getOrCreateSession helper.
Comment on lines
+800
to
+821
| await using agentFile = await this.agentLoader.getAgentFile(appName); | ||
| const agent = await agentFile.load(); | ||
| const runner = await this.getRunner(agent, appName); | ||
| const events: Event[] = []; | ||
| const abortController = new AbortController(); | ||
| req.on('close', () => { | ||
| abortController.abort(); | ||
| }); | ||
| for await (const e of runner.runAsync({ | ||
| userId, | ||
| sessionId, | ||
| newMessage, | ||
| stateDelta, | ||
| abortSignal: abortController.signal, | ||
| })) { | ||
| events.push(e); | ||
| } | ||
| res.json({output: events}); | ||
| } catch (e: unknown) { | ||
| const error = `Failed to run agent via Reasoning Engine API: ${e}`; | ||
| res.status(500).json({error}); | ||
| this.logger.error(error); |
Collaborator
There was a problem hiding this comment.
very similar to run_sse can we move the common logic to the same place?
Collaborator
Author
There was a problem hiding this comment.
Refactored the core execution block (agent load, runner fetch, run loop, and event streaming) into a shared executeAgentRun helper. This helper is now reused in /run, /run_sse, and the Reasoning Engine query endpoints to keep them clean and consistent.
…xecution helper in api server
9 tasks
kalenkevich
reviewed
Jun 18, 2026
| return this.runnerCache[appName]; | ||
| } | ||
|
|
||
| private async executeAgentRun(options: { |
Collaborator
There was a problem hiding this comment.
make it as generator and then no need to introduce a onEvent callback.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Please ensure you have read the contribution guide https://google.github.io/adk-docs/contributing-guide/ before creating a pull request.
Link to Issue or Description of Change
• Closes: #none
• Related: #none
Problem:
Vertex AI's Reasoning Engine execution gateway and liveness checks impose two key constraints:
/and/healthwithout redirects (Vertex AI kills containers that return 3xx codes, which broke ADK because it redirected/to/dev-ui).Content-Type: application/json,application/json), which causes Express's standard body-parser to skip parsing and results in empty request bodies{}.Solution:
Implemented native routing in
adk_api_server.tsfor/healthand/endpoints to return200 OKwhen the Debug UI is disabled. Added a custom raw-body fallback stream listener on thePOST /api/reasoning_enginequery endpoint to parse incoming payloads manually if standard body-parser was skipped.Testing Plan
Unit Tests:
Summary of passed test results:
✓ |unit:dev| dev/test/server/adk_api_server_test.ts (45 tests) 3797ms
✓ AdkWebServer > Reasoning Engine > should return 200 OK on health endpoints when debug UI is disabled 99ms
✓ AdkWebServer > Reasoning Engine > should query the agent using reasoning_engine route with valid JSON 42ms
✓ AdkWebServer > Reasoning Engine > should auto-create session if not exists on reasoning_engine query 56ms
✓ AdkWebServer > Reasoning Engine > should support raw body query and parse headers workaround 83ms
✓ AdkWebServer > Reasoning Engine > should return 400 if appName is missing 36ms
✓ AdkWebServer > Reasoning Engine > should return 500 if execution fails 34ms
Files tested:
• dev/test/server/adk_api_server_test.ts
Manual End-to-End (E2E) Tests:
Manually deployed and verified querying the weather tool agent on Vertex AI Reasoning Engines with unmocked traffic.
Checklist
Additional context
None.