Skip to content

Fix: Add NERVE_AGENT_WORKSPACES config for custom agent workspace paths#202

Open
gregb100 wants to merge 1 commit intodaggerhashimoto:masterfrom
gregb100:fix/memory-tab-workspace-detection
Open

Fix: Add NERVE_AGENT_WORKSPACES config for custom agent workspace paths#202
gregb100 wants to merge 1 commit intodaggerhashimoto:masterfrom
gregb100:fix/memory-tab-workspace-detection

Conversation

@gregb100
Copy link
Copy Markdown
Contributor

@gregb100 gregb100 commented Mar 30, 2026

What

Adds NERVE_AGENT_WORKSPACES environment variable to map agent IDs to custom workspace paths. This allows Nerve to detect and access workspaces located at non-standard paths (e.g., /home/clawhost/projects/otto instead of ~/.openclaw/workspace-otto).

Why

Fixes the Memory tab incorrectly showing "Sandboxed Workspace" when the workspace exists locally but at a non-standard path. Related to #145 — builds on the remote workspace detection to support custom workspace paths beyond the default ~/.openclaw/workspace-{agentId} convention.

How

• Added agentWorkspaces config parser in server/lib/config.ts that reads NERVE_AGENT_WORKSPACES env var (format: agentId:/path,agentId2:/path2)
• Modified server/lib/agent-workspace.ts to check for custom workspace path before falling back to default ~/.openclaw/workspace-{agentId}
• Example config: NERVE_AGENT_WORKSPACES={agentId}:/home/projects/{agentId}

Type of Change

• [x] 🐛 Bug fix (non-breaking change that fixes an issue)
• [ ] ✨ New feature (non-breaking change that adds functionality)
• [ ] 💥 Breaking change (fix or feature that would cause existing functionality to change)
• [ ] 📝 Documentation update
• [ ] 🔧 Refactor / chore (no functional change)

Checklist

• [x] npm run lint passes
• [x] npm run build && npm run build:server succeeds
• [ ] npm test -- --run passes
• [ ] New features include tests
• [ ] UI changes include a screenshot or screen recording

Screenshots

N/A — backend-only fix

Summary by CodeRabbit

  • New Features
    • Added support for custom workspace path configuration for agents, enabling flexible management of agent storage locations. Individual agents can be assigned custom paths when configured. Full backward compatibility is maintained—agents automatically use default workspace locations when no custom configuration is specified.

Allows mapping specific agent IDs to custom workspace locations via
environment variable (e.g., NERVE_AGENT_WORKSPACES=otto:/path/to/workspace).
This fixes the Memory tab showing 'Sandboxed Workspace' incorrectly
when the workspace exists locally but at a non-standard path.

Related to daggerhashimoto#145 - builds on the remote workspace detection to support
custom workspace paths beyond the default ~/.openclaw/workspace-{agentId} convention.
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 30, 2026

📝 Walkthrough

Walkthrough

The changes add support for per-agent workspace path customization via the NERVE_AGENT_WORKSPACES environment variable. A new config.agentWorkspaces property parses comma-separated agentId:/path/to/workspace pairs, enabling resolveAgentWorkspace() to use custom paths when configured, falling back to defaults otherwise.

Changes

Cohort / File(s) Summary
Configuration
server/lib/config.ts
Added new exported config.agentWorkspaces property that parses NERVE_AGENT_WORKSPACES environment variable as comma-separated agent ID and workspace path pairs into a Record<string, string> mapping.
Workspace Resolution
server/lib/agent-workspace.ts
Modified resolveAgentWorkspace() to consult config.agentWorkspaces for optional per-agent workspace path overrides before using the default computed workspace path.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 Each agent seeks their dwelling place,
A custom root in cyberspace,
Through env vars we grant their choice,
Let config give each one a voice!
Workspace paths now dance with care,
Finding homes beyond compare. 🏠✨

🚥 Pre-merge checks | ✅ 2 | ❌ 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 (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and accurately describes the main change: adding a NERVE_AGENT_WORKSPACES config option to support custom agent workspace paths.
Description check ✅ Passed The description covers all required template sections with sufficient detail: What, Why, How, Type of Change with checkbox marked, and Checklist with appropriate items marked.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@server/lib/config.ts`:
- Around line 97-99: The parsing currently uses pair.split(':') which splits on
every colon and truncates workspacePath (e.g., Windows paths); change the logic
that builds result (where pair is parsed and result[agentId.trim()] =
workspacePath.trim()) to only split on the first ':' — e.g., find the first
colon with pair.indexOf(':') and set agentId = pair.slice(0, idx) and
workspacePath = pair.slice(idx + 1) (or use pair.split(':', 2)) so workspacePath
preserves any remaining colons, then trim and assign as before.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: ec42c249-b0c4-4a3f-b81c-f075dba49d9e

📥 Commits

Reviewing files that changed from the base of the PR and between 7c444db and f78ff46.

📒 Files selected for processing (2)
  • server/lib/agent-workspace.ts
  • server/lib/config.ts

Comment on lines +97 to +99
const [agentId, workspacePath] = pair.split(':');
if (agentId && workspacePath) {
result[agentId.trim()] = workspacePath.trim();
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat -n server/lib/config.ts | sed -n '80,110p'

Repository: daggerhashimoto/openclaw-nerve

Length of output: 1831


🏁 Script executed:

# Search for test cases or examples related to agentWorkspaces format
rg -i "agentworkspace|agent.*workspace" --type ts --type js -B 2 -A 2 server/ | head -100

Repository: daggerhashimoto/openclaw-nerve

Length of output: 5904


🏁 Script executed:

# Check the agent-workspace.ts file to understand how the parsed config is used
cat -n server/lib/agent-workspace.ts | head -50

Repository: daggerhashimoto/openclaw-nerve

Length of output: 1964


Split only on the first : to avoid truncating workspace paths.

Using pair.split(':') breaks values like agent1:C:\work\space (Windows drive letters and any path containing :) because destructuring [agentId, workspacePath] = split_result captures only the first two array elements. This truncates workspacePath to just C, causing incorrect workspace resolution in agent-workspace.ts line 44.

🔧 Proposed fix
   for (const pair of pairs) {
-    const [agentId, workspacePath] = pair.split(':');
-    if (agentId && workspacePath) {
-      result[agentId.trim()] = workspacePath.trim();
-    }
+    const idx = pair.indexOf(':');
+    if (idx <= 0 || idx === pair.length - 1) continue;
+
+    const agentId = pair.slice(0, idx).trim();
+    const workspacePath = pair.slice(idx + 1).trim();
+    if (agentId && workspacePath) {
+      result[agentId] = workspacePath;
+    }
   }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const [agentId, workspacePath] = pair.split(':');
if (agentId && workspacePath) {
result[agentId.trim()] = workspacePath.trim();
const idx = pair.indexOf(':');
if (idx <= 0 || idx === pair.length - 1) continue;
const agentId = pair.slice(0, idx).trim();
const workspacePath = pair.slice(idx + 1).trim();
if (agentId && workspacePath) {
result[agentId] = workspacePath;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@server/lib/config.ts` around lines 97 - 99, The parsing currently uses
pair.split(':') which splits on every colon and truncates workspacePath (e.g.,
Windows paths); change the logic that builds result (where pair is parsed and
result[agentId.trim()] = workspacePath.trim()) to only split on the first ':' —
e.g., find the first colon with pair.indexOf(':') and set agentId =
pair.slice(0, idx) and workspacePath = pair.slice(idx + 1) (or use
pair.split(':', 2)) so workspacePath preserves any remaining colons, then trim
and assign as before.

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