This is a quickstart guide to getting NOOA running in VSCode and using a DGX Spark for GPU inference.
We’ll get NOOA running from a fresh checkout, wired to Ollama models hosted on a remote DGX Spark, and driven from inside VS Code via an Agent Client Protocol (ACP) extension.
What is NOOA?
NOOA is the NVIDIA (currently NVIDIA-labs) Object Oriented Agents project.
It is a model-agnostic framework or harness for reliable AI Agent-assisted software development. Although written in Python, it can be used to develop in any popular programming language.
NOOA forces the model to work better on code repos by using pass-by-reference execution and native abstract syntax trees. This is said to increase the SWE Bench Pro score for a model typically by around 10 percentage points and improve throughput by 4.5x to 16x depending on the task. Sounds too good to be true.
Prerequsites
- VS Code (either running on Ubuntu Linux 22 or 24, or Windows with wsl extension and Ubuntu Linux 22 or 24). Other Linux and MacOSX will probably work (untested).
- Ideally at least glibc 2.39+ (e.g. Ubuntu 24.04+). Workarounds provided for Ubuntu 22.
- Checkout of GitHub - NVIDIA-NeMo/labs-OO-Agents: NVIDIA Object Oriented Agents: the Pythonic way to build AI Agents. · GitHub
- A DGX Spark running Ollama on local subnet or VPN e.g. a Tailscale tailnet
uvinstalled (curl -LsSf ``https://astral.sh/uv/install.sh`` | sh)
1. Install the project
uv sync --all-extras
uv sync --all-extras installs every optional extra (cli, memory, bench, acp, arc, tracing, viewer, sandbox, mcp, nemo-relay) — but it fails on Ubuntu 22.04 with:
error: Distribution `openshell==0.0.75` can't be installed because it
doesn't have a source distribution or wheel for the current platform
The sandbox extra’s openshell wheel requires glibc ≥ 2.39 (manylinux_2_39_x86_64). Ubuntu 22.04 (jammy) ships glibc 2.35 — check with ldd --version. Don’t try to upgrade glibc in place; it will break the OS. Options:
-
Skip
sandbox(recommended) — sync everything else explicitly:uv sync --extra cli --extra memory --extra bench --extra acp \ --extra arc --extra tracing --extra viewer --extra mcp \ --extra nemo-relay -
Or use Ubuntu 24.04+ (glibc 2.39), e.g. a fresh WSL distro:
wsl --install Ubuntu-24.04from PowerShell, or the Microsoft Store listing.
The uv error hints at tool.uv.required-environments, but that only fixes lockfile resolution — PEP 508 markers can’t express glibc version, so the wheel still won’t run on glibc 2.35.
2. Verify the install
uv run python -c "import nooa; print(nooa.__version__)"
3. Verify the DGX Spark Ollama endpoint
If Ollama on the Spark is bound to the tailnet interface, it is reachable at http://<spark-hostname>.<tailnet>.ts.net:11434. Check it and list models:
curl -s http://<spark-hostname>.<tailnet>.ts.net:11434/api/tags \
| python3 -c "import json,sys; print('\n'.join(m['name'] for m in json.load(sys.stdin)['models']))"
Example output from a DGX Spark:
gpt-oss:120b
qwen3.6:35b-a3b
qwen3-coder:30b
qwen3.5:27b
nemotron-3-nano:30b
nemotron-3-nano:4b
...
4. List the client types
cd /home/<User>/source/NOOA && uv run python -c "
from nooa.unifiedllm.registry import get_llm_client
for alias in ('dgx-coder', 'dgx-general', 'dgx-fast', 'dgx-big'):
try:
client = get_llm_client(alias)
print(f'{alias}: OK -> {type(client).__name__}')
except Exception as e:
print(f'{alias}: FAIL -> {e}')
"
dgx-coder: OK -> CompletionClient
dgx-general: OK -> CompletionClient
dgx-fast: OK -> CompletionClient
dgx-big: OK -> CompletionClient
5. Register the DGX models as NOOA aliases
NOOA resolves LiteLLM model strings through get_llm_client() (see local-models.md). Ollama uses the ollama_chat/<model> route, base URL without /v1, and no API key.
Create .nooa/llm_config.yaml in the project root:
models:
dgx-coder:
model_name: ollama_chat/qwen3-coder:30b
api_base: http://<spark-hostname>.<tailnet>.ts.net:11434
dgx-general:
model_name: ollama_chat/qwen3.6:35b-a3b
api_base: http://<spark-hostname>.<tailnet>.ts.net:11434
dgx-fast:
model_name: ollama_chat/nemotron-3-nano:4b
api_base: http://<spark-hostname>.<tailnet>.ts.net:11434
dgx-big:
model_name: ollama_chat/gpt-oss:120b
api_base: http://<spark-hostname>.<tailnet>.ts.net:11434
Project-local config sits on the discovery chain (bundled < user-global < project-local < NEMO_OO_LLM_CONFIG env var), so it is picked up automatically. Confirm with the CLI:
uv run nooa config show
# Project config (.../.nooa/llm_config.yaml): present (4 aliases)
Smoke-test a live round-trip:
uv run python - <<'EOF'
from nooa.unifiedllm.registry import get_llm_client
llm = get_llm_client("dgx-fast")
resp = llm.call(messages=[{"role": "user", "content": "Reply with exactly: PONG"}])
print(resp.content) # -> PONG
EOF
Note: LLMResponse has a terse repr — the text is on .content, so print(resp) looks empty even on success.
6. The CLI and the ACP server
The nooa CLI comes from the nooa-cli workspace package:
uv run nooa --help
Relevant commands: acp (stdio agent server), config (inspect the config chain), connect (guided model setup), start-dev (trace viewer on port 5001), traces, eval.
Test that the ACP server starts and answers a JSON-RPC initialize handshake:
uv run nooa acp --model dgx-fast
then type/paste one line into its stdin:
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":1,"clientCapabilities":{}}}
Expected response:
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentCapabilities":{...},"agentInfo":{"name":"nooa-acp","title":"NVIDIA Labs Object Oriented Agents (NOOA)",...}}}
Ctrl-C to stop. There is no default model — --model (or NOOA_MODEL) is required, and any configured alias works.
7. Drive it from VS Code
VS Code has no native ACP support, but there are multiple ACP client extensions available from the Microsoft Marketplace, and this guide covers two of them: ACP Client and ACP Pro. The steps below show how to configure each one for the same NOOA DGX/Tailscale models.
7.1 ACP Client
Install ACP Client by Jun Han (formulahendry.acp-client) from the Microsoft Marketplace.
The extension reads an acp.agents settings object: each key is an agent name, and each value has command, args, and env. In this environment, this is configured in the VS Code Machine settings file for the remote VS Code server (for example, /home/<User>/.vscode-server/data/Machine/settings.json), not in the repository’s project settings file.
Use this configuration in that Machine settings JSON:
"acp.agents": {
"NOOA (DGX qwen3-coder)": {
"command": "uv",
"args": [
"run", "--project", "/home/<User>/source/NOOA",
"nooa", "acp", "--model", "dgx-coder"
],
"env": {}
},
"NOOA (DGX gpt-oss 120b)": {
"command": "uv",
"args": [
"run", "--project", "/home/<User>/source/NOOA",
"nooa", "acp", "--model", "dgx-big"
],
"env": {}
}
}
(Adjust the --project path to your checkout.)
Reload the VS Code window, open the ACP Client panel, and pick a NOOA agent from its agent selector. The extension spawns the server over stdio — the same handshake tested in step 4.
Useful extension settings:
acp.autoApprovePermissions:"ask"(default) prompts before file edits/terminal commands;"allowAll"for autonomous runs.acp.logTraffic:true(default) logs all ACP protocol traffic to the output channel — the first place to look if an agent fails to appear.
No credentials are needed in env if using tailnet — the DGX Ollama endpoint is unauthenticated on the tailnet. For hosted providers, put the key in env (e.g. NVIDIA_API_KEY) or use a secret-manager wrapper as the command.
7.2 ACP Pro
Install ACP Pro by duclvz.acp-pro from the Microsoft Marketplace.
Configure it in the VS Code Machine settings JSON for the current remote environment, not the repository’s project settings file. The ACP Pro entries should sit alongside the existing acp.agents block in that same settings file.
Add the following acpPro.agents configuration:
{
"acpPro.agents": [
{
"name": "NOOA (DGX qwen3-coder)",
"command": "uv",
"args": [
"run",
"--project",
"/home/<User>/source/NOOA",
"nooa",
"acp",
"--model",
"dgx-coder"
],
"env": {}
},
{
"name": "NOOA (DGX qwen3-general)",
"command": "uv",
"args": [
"run",
"--project",
"/home/<User>/source/NOOA",
"nooa",
"acp",
"--model",
"dgx-general"
],
"env": {}
},
{
"name": "NOOA (DGX fast)",
"command": "uv",
"args": [
"run",
"--project",
"/home/<User>/source/NOOA",
"nooa",
"acp",
"--model",
"dgx-fast"
],
"env": {}
},
{
"name": "NOOA (DGX big)",
"command": "uv",
"args": [
"run",
"--project",
"/home/<User>/source/NOOA",
"nooa",
"acp",
"--model",
"dgx-big"
],
"env": {}
}
],
"acpPro.defaultAgent": "NOOA (DGX qwen3-coder)",
"acpPro.defaultModel": "dgx-coder"
}
Reload the window and select the ACP Pro agent from the extension’s selector. The agent starts the same NOOA ACP stdio server and uses the same DGX/Tailscale model aliases as ACP Client.
(Adjust the --project path to your actual checkout.)
Reload the VS Code window, open the ACP Pro activity panel, and pick a NOOA agent from the list. The extension starts the stdio ACP server in the same way as ACP Client, and the server performs the same initialize handshake as in step 4.
No credentials are needed in env when the DGX endpoint is reachable through Tailscale. If you are targeting a hosted provider instead, place its key in env or wrap the command in a helper that injects the required secret.
8. Using the ACP Client
Connect the Chat to the ACP agent - pick one of the models you configured in the previous step.
Try a simple textual prompt such as hello or ping.
Now try a prompt such as:
Run `ls examples/quickstart/` and tell me what's there
It should show you the results of the ls command and show that it ran two tool calls.
Now try editing a file:
Add a comment "# tested via ACP" to the top of examples/README.md
That too should succeed.
| Step | Status |
|---|---|
| Agent appears in ACP Client | ✅ (you selected it) |
| Initialize handshake | ✅ (server started, agent responded) |
| Chat round-trip | ✅ (answered prompts) |
| Terminal command execution | ✅ (ls ran and returned output) |
| File editing | ✅ (File is modified after permission is granted) |
What’s next?
NOOA shows a lot of promise. NVIDIA describes it as a framework, I think of it as a harness. But compared to VSCode’s own harness, or Clause, or Oh My Pi, it is currently rudamentary.
NVIDIA and the community are working hard to add in the same kinds of advanced tools as those other harnesses provide (for instance, a recent pull request provides a basic Language Server Protocol implementation in NOOA; others are working on DAP / debugger, persistent shell, subagents, OWASP SCS and so on.
Personally, I’m interested in NOOA for its ability to define workflow graphs, evaluation gates, state transitions, completion semantics, and retry and error handling in deterministic software whilst the LLM gets to reson inside one bounded step to produce that step’s output, running narrow tools by contract.
Troubleshooting
| Symptom | Cause / fix | |||
|---|---|---|---|---|
uv sync --all-extras fails on openshell |
glibc < 2.39; skip the sandbox extra (step 1) |
|||
nooa acp exits with a usage error |
No model set — pass --model or NOOA_MODEL |
|||
| Agent missing from the ACP panel | Reload the window; check the ACP Client output channel (acp.logTraffic) |

