Skip to content

refactor(agents): make the server own subagent execution - #190

Closed
Waishnav wants to merge 6 commits into
mainfrom
refactor/subagent-runtime-owner
Closed

refactor(agents): make the server own subagent execution#190
Waishnav wants to merge 6 commits into
mainfrom
refactor/subagent-runtime-owner

Conversation

@Waishnav

@Waishnav Waishnav commented Aug 12, 2026

Copy link
Copy Markdown
Owner

Subagent turns currently run from short-lived detached workers, which makes provider lifetime and per-agent turn ownership hard to reason about and prevents later runtime reuse. This moves execution under the running DevSpace server and introduces a single LocalAgentManager boundary for starting, continuing, persisting, and serializing logical agent turns. Durable session state stays in LocalAgentStore; live execution remains server-owned and disposable.\n\nThis is the bottom layer of the runtime-efficiency stack. The existing devspace agents command surface stays intact, but agent execution now requires the DevSpace server to be running so later layers can safely reuse expensive provider runtimes.

Summary by CodeRabbit

  • New Features

    • Agent runs can now be submitted through a running DevSpace server, reusing long-lived provider sessions.
    • Local agent execution supports queued, serialized runs with persistent records and response history.
    • Agent commands validate workspace, provider, and execution settings before running.
    • Agent identification supports exact IDs and unique ID prefixes.
  • Documentation

    • Added setup instructions for enabling subagent support with devspace serve before running agent commands.

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 61a054a5-71eb-45bd-969c-fd9748e79a30

📥 Commits

Reviewing files that changed from the base of the PR and between b85e354 and ab43ccf.

📒 Files selected for processing (2)
  • src/local-agent-store.test.ts
  • src/local-agent-store.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/local-agent-store.test.ts

📝 Walkthrough

Walkthrough

The PR moves local agent execution into a server-managed LocalAgentManager. A local socket or named-pipe control server accepts run requests. The CLI submits requests to this server, which queues provider turns and persists agent state.

Changes

Local agent execution

Layer / File(s) Summary
Queued agent manager
src/local-agent-manager.ts, src/local-agent-manager.test.ts
LocalAgentManager creates durable records, serializes turns per agent, invokes providers, stores results, and supports shutdown.
Local control transport
src/local-agent-control.ts, src/local-agent-control.test.ts
The control server and client exchange validated run commands and agent records through platform-specific local endpoints.
Server and CLI integration
src/server.ts, src/cli.ts, docs/configuration.md
The server starts agent control during startup. agents run submits requests instead of spawning workers. The documentation describes the required server startup.
Agent ID lookup
src/local-agent-store.ts, src/local-agent-store.test.ts
LocalAgentStore resolves exact and unique-prefix local agent IDs without matching provider session IDs.
Validation and usage coverage
package.json
The test script includes the local control integration test.

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

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant AgentsCLI
  participant DevSpaceServer
  participant LocalAgentControlServer
  participant LocalAgentManager
  participant Provider
  User->>DevSpaceServer: start devspace serve
  DevSpaceServer->>LocalAgentControlServer: start agent control
  User->>AgentsCLI: devspace agents run
  AgentsCLI->>LocalAgentControlServer: submit run command
  LocalAgentControlServer->>LocalAgentManager: enqueue command
  LocalAgentManager->>Provider: execute queued turn
  Provider-->>LocalAgentManager: return response and session data
  LocalAgentManager-->>AgentsCLI: return agent record
Loading

Possibly related PRs

Poem

A rabbit sees the agents queue,
The server sends each turn through.
Sessions rest in records bright,
Sockets close on shutdown night.
“Hop,” says the rabbit, “all is right!”

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: moving subagent execution ownership to the running server.
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 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/subagent-runtime-owner

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.

@Waishnav Waishnav changed the title refactor/subagent runtime owner refactor(agents): make the server own subagent execution Aug 12, 2026

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

Actionable comments posted: 7

🧹 Nitpick comments (1)
src/local-agent-control.ts (1)

108-132: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Add a client timeout to requestControl.

The client resolves only on end and rejects only on error. If the server accepts the connection and never responds, devspace agents run hangs with no output. Add a socket timeout so the CLI fails with a clear message.

♻️ Proposed fix
     const socket = createConnection(address);
     socket.setEncoding("utf8");
+    socket.setTimeout(30_000, () => {
+      socket.destroy();
+      reject(new Error("DevSpace subagent runtime did not respond in time."));
+    });
🤖 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/local-agent-control.ts` around lines 108 - 132, Update requestControl to
configure a client-side timeout on the socket after createConnection. On
timeout, destroy the socket and reject with a clear error stating that the
DevSpace subagent runtime did not respond in time, while preserving the existing
error, data, end, and connect handling.
🤖 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 `@docs/configuration.md`:
- Around line 156-158: Update the `devspace agents run` documentation to
explicitly require setting `DEVSPACE_SUBAGENTS=1` before starting `devspace
serve`, while preserving the guidance about running the agent command from
another terminal.

In `@src/local-agent-control.ts`:
- Around line 64-77: Update handleConnection to register a socket error handler
so peer disconnects or write failures do not become uncaught exceptions. Define
and use MAX_CONTROL_REQUEST_BYTES to reject or destroy connections once the
accumulated request exceeds the limit, stop processing input after the first
line, and ensure parse/handle failures cleanly destroy or close the socket
instead of leaving it paused.
- Around line 53-62: Track active client sockets in local-agent-control by
adding each socket in handleConnection and removing it on the socket’s close
event. During close(), destroy all tracked sockets before awaiting
server.close(), so idle connections cannot keep shutdown blocked.

In `@src/local-agent-manager.ts`:
- Around line 73-88: Update enqueue so the existing-agent lookup only matches
agent IDs, not provider_session_id values; use the store API or predicate that
explicitly targets the agent ID field before calling prepareExistingAgent or
createAgent. Preserve the subsequent scheduling and status update flow.
- Around line 139-153: Update the queue-tail handling around next in the local
agent manager so the promise stored in queue.tail always has a rejection
handler, preventing unhandled rejections from the status update or executeTurn
callback. Preserve the rejection details by recording the failure in the agent
record, while keeping queue.pending decrement and queue cleanup in the existing
finally flow.
- Around line 114-131: The local-agent manager must enforce allowed-root
containment for workspace paths at both creation and execution boundaries. In
src/local-agent-manager.ts:114-131, validate command.workspaceRoot before
loadLocalAgentProfiles or store.create, and validate stored agent records before
provider execution; keep src/cli.ts:352-360 unchanged and rely on server-side
validation.

In `@src/server.ts`:
- Around line 1700-1703: Update the startup flow around localAgentControl and
startAgentControl so any rejected startup closes the server before propagating
the failure. Ensure close() runs before callers exit or register shutdown
handlers, preserving normal startup and shutdown behavior.

---

Nitpick comments:
In `@src/local-agent-control.ts`:
- Around line 108-132: Update requestControl to configure a client-side timeout
on the socket after createConnection. On timeout, destroy the socket and reject
with a clear error stating that the DevSpace subagent runtime did not respond in
time, while preserving the existing error, data, end, and connect handling.
🪄 Autofix

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: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 1ad03e84-b539-46f9-8a76-3f849a33ecc5

📥 Commits

Reviewing files that changed from the base of the PR and between b5b4ab6 and 0b1e267.

📒 Files selected for processing (8)
  • docs/configuration.md
  • package.json
  • src/cli.ts
  • src/local-agent-control.test.ts
  • src/local-agent-control.ts
  • src/local-agent-manager.test.ts
  • src/local-agent-manager.ts
  • src/server.ts

Comment thread docs/configuration.md Outdated
Comment thread src/local-agent-control.ts
Comment thread src/local-agent-control.ts
Comment thread src/local-agent-manager.ts
Comment thread src/local-agent-manager.ts
Comment thread src/local-agent-manager.ts
Comment thread src/server.ts
@greptile-apps

greptile-apps Bot commented Aug 12, 2026

Copy link
Copy Markdown

Greptile Summary

The PR moves subagent execution into the long-lived DevSpace server and introduces local IPC plus per-agent turn serialization.

  • Adds a local control socket used by devspace agents run.
  • Adds a server-owned manager that serializes turns and persists provider session state.
  • Starts and closes the new runtime with the HTTP server lifecycle.
  • Adds manager and control-socket tests and documents the requirement to run devspace serve.

Confidence Score: 4/5

The PR appears safe to merge, with a non-blocking IPC hardening issue around unbounded incomplete-request buffering.

The server-owned runtime and serialized execution paths are coherent, but the new control socket retains unlimited input from a client that never sends a newline.

Files Needing Attention: src/local-agent-control.ts

Important Files Changed

Filename Overview
src/local-agent-control.ts Introduces local IPC request handling; request buffering is not bounded for clients that omit the newline terminator.
src/local-agent-manager.ts Introduces server-owned subagent queues, serialized provider execution, and durable session updates.
src/server.ts Integrates control-server startup and manager shutdown into the DevSpace server lifecycle.
src/cli.ts Replaces detached subagent workers with requests to the running server.
src/local-agent-control.test.ts Covers a successful control request but not oversized or unterminated request handling.
src/local-agent-manager.test.ts Verifies serialization and provider-session continuation across queued turns.

Sequence Diagram

sequenceDiagram
    participant CLI as devspace agents run
    participant IPC as LocalAgentControlServer
    participant Manager as LocalAgentManager
    participant Store as LocalAgentStore
    participant Provider as Agent Provider
    CLI->>IPC: run command over local socket
    IPC->>Manager: enqueue(command)
    Manager->>Store: create/update running record
    Manager-->>IPC: record
    IPC-->>CLI: record
    Manager->>Provider: execute serialized turn
    Provider-->>Manager: response and session ID
    Manager->>Store: persist idle/error state
Loading

Reviews (1): Last reviewed commit: "test(agents): cover serialized server ex..." | Re-trigger Greptile

Comment thread src/local-agent-control.ts
@Waishnav

Copy link
Copy Markdown
Owner Author

[GPT-5.6-SOL] RESPONDING ON BEHALF OF WAISHNAV

Also addressed the review nitpick about client hangs in 72be01f: requestControl now has a 30-second socket timeout and fails with a specific subagent-runtime timeout error.

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/local-agent-store.test.ts (1)

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

Cover exact local-ID resolution.

Line [27] tests only the unique-prefix query. The exact-ID query in src/local-agent-store.ts Lines [156]-[159] is a separate branch. Add an exact-ID assertion before the prefix assertion.

Proposed test addition
+  assert.equal(store.getByAgentId(created.id)?.id, created.id);
   assert.equal(store.getByAgentId(created.id.slice(0, 7))?.id, created.id);
🤖 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/local-agent-store.test.ts` at line 27, Add an assertion in the test
covering the created agent to call getByAgentId with created.id exactly and
verify it returns the created agent ID, placing it before the existing
shortened-prefix assertion so both resolution branches are covered.
🤖 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/local-agent-store.ts`:
- Around line 161-169: Update the local-agent lookup method containing the
matches query and rowToLocalAgentRecord so matches.length > 1 produces an
explicit ambiguous result or throws instead of returning undefined. Preserve
undefined only for no matches, and update the local-agent-manager flow around
createAgent so ambiguous prefixes cannot create a new agent. Add a regression
test covering multiple agents with the same prefix.

---

Nitpick comments:
In `@src/local-agent-store.test.ts`:
- Line 27: Add an assertion in the test covering the created agent to call
getByAgentId with created.id exactly and verify it returns the created agent ID,
placing it before the existing shortened-prefix assertion so both resolution
branches are covered.
🪄 Autofix

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: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2a8ac993-b409-4540-965c-b01726346590

📥 Commits

Reviewing files that changed from the base of the PR and between 0b1e267 and b85e354.

📒 Files selected for processing (8)
  • docs/configuration.md
  • src/local-agent-control.test.ts
  • src/local-agent-control.ts
  • src/local-agent-manager.test.ts
  • src/local-agent-manager.ts
  • src/local-agent-store.test.ts
  • src/local-agent-store.ts
  • src/server.ts
🚧 Files skipped from review as they are similar to previous changes (6)
  • src/local-agent-control.test.ts
  • src/local-agent-manager.test.ts
  • docs/configuration.md
  • src/local-agent-manager.ts
  • src/server.ts
  • src/local-agent-control.ts

Comment thread src/local-agent-store.ts
@Waishnav

Copy link
Copy Markdown
Owner Author

Closing this Sol stack PR in favor of the Luna-based implementation.

@Waishnav Waishnav closed this Aug 13, 2026
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