Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,14 @@ uv add "nooa @ git+https://github.com/NVIDIA-NeMo/labs-OO-Agents.git@main"
```

<details>
<summary><b>Optional sub-packages</b> — CLI + TUI, memory, evaluation pipeline</summary>
<summary><b>Optional sub-packages</b> — CLI, memory, evaluation pipeline</summary>

<br />

All of these live in the same repo and are addressed with `#subdirectory=…`.

```bash
# CLI + TUI (beta): the `nooa` command, agent REPL, trace viewer, TUI
# CLI (beta): the `nooa` command, trace viewer, eval runner
uv add "nooa-cli @ git+https://github.com/NVIDIA-NeMo/labs-OO-Agents.git@main#subdirectory=packages/nooa-cli"

# Long-term memory subsystem (MemoryManager)
Expand Down
98 changes: 0 additions & 98 deletions THIRD_PARTY_NOTICES.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,90 +50,16 @@ Attribution Statements: NVIDIA includes `click` under the BSD 3-Clause License f
License Text(https://spdx.org/licenses/BSD-3-Clause.html)
Source/Homepage: https://github.com/pallets/click

ipython - BSD 3-Clause License
Attribution Statements: NVIDIA includes `ipython` under the BSD 3-Clause License for use with NVIDIA OO Agents.
License Text(https://spdx.org/licenses/BSD-3-Clause.html)
Source/Homepage: https://github.com/ipython/ipython

mcp - MIT License
Attribution Statements: NVIDIA includes `mcp` under the MIT License for use with NVIDIA OO Agents.
License Text(https://spdx.org/licenses/MIT.html)
Source/Homepage: https://github.com/modelcontextprotocol/python-sdk

nooa - Apache License 2.0
Attribution Statements: NVIDIA includes `nooa` under the Apache License 2.0 for use with NVIDIA OO Agents.
License Text(https://spdx.org/licenses/Apache-2.0.html)
Source/Homepage: https://github.com/NVIDIA-NeMo/labs-OO-Agents

prompt-toolkit - BSD 3-Clause License
Attribution Statements: NVIDIA includes `prompt-toolkit` under the BSD 3-Clause License for use with NVIDIA OO Agents.
License Text(https://spdx.org/licenses/BSD-3-Clause.html)
Source/Homepage: https://github.com/prompt-toolkit/python-prompt-toolkit

pydantic - MIT License
Attribution Statements: NVIDIA includes `pydantic` under the MIT License for use with NVIDIA OO Agents.
License Text(https://spdx.org/licenses/MIT.html)
Source/Homepage: https://github.com/pydantic/pydantic

pyyaml - MIT License
Attribution Statements: NVIDIA includes `pyyaml` under the MIT License for use with NVIDIA OO Agents.
License Text(https://spdx.org/licenses/MIT.html)
Source/Homepage: https://github.com/yaml/pyyaml

rich - MIT License
Attribution Statements: NVIDIA includes `rich` under the MIT License for use with NVIDIA OO Agents.
License Text(https://spdx.org/licenses/MIT.html)
Source/Homepage: https://github.com/Textualize/rich

---

## `nooa-tui`

click - BSD 3-Clause License
Attribution Statements: NVIDIA includes `click` under the BSD 3-Clause License for use with NVIDIA OO Agents.
License Text(https://spdx.org/licenses/BSD-3-Clause.html)
Source/Homepage: https://github.com/pallets/click

ipython - BSD 3-Clause License
Attribution Statements: NVIDIA includes `ipython` under the BSD 3-Clause License for use with NVIDIA OO Agents.
License Text(https://spdx.org/licenses/BSD-3-Clause.html)
Source/Homepage: https://github.com/ipython/ipython

mcp - MIT License
Attribution Statements: NVIDIA includes `mcp` under the MIT License for use with NVIDIA OO Agents.
License Text(https://spdx.org/licenses/MIT.html)
Source/Homepage: https://github.com/modelcontextprotocol/python-sdk

nooa - Apache License 2.0
Attribution Statements: NVIDIA includes `nooa` under the Apache License 2.0 for use with NVIDIA OO Agents.
License Text(https://spdx.org/licenses/Apache-2.0.html)
Source/Homepage: https://github.com/NVIDIA-NeMo/labs-OO-Agents

nooa-cli - Apache License 2.0
Attribution Statements: NVIDIA includes `nooa-cli` under the Apache License 2.0 for use with NVIDIA OO Agents.
License Text(https://spdx.org/licenses/Apache-2.0.html)
Source/Homepage: https://github.com/NVIDIA-NeMo/labs-OO-Agents

prompt-toolkit - BSD 3-Clause License
Attribution Statements: NVIDIA includes `prompt-toolkit` under the BSD 3-Clause License for use with NVIDIA OO Agents.
License Text(https://spdx.org/licenses/BSD-3-Clause.html)
Source/Homepage: https://github.com/prompt-toolkit/python-prompt-toolkit

pydantic - MIT License
Attribution Statements: NVIDIA includes `pydantic` under the MIT License for use with NVIDIA OO Agents.
License Text(https://spdx.org/licenses/MIT.html)
Source/Homepage: https://github.com/pydantic/pydantic

pyyaml - MIT License
Attribution Statements: NVIDIA includes `pyyaml` under the MIT License for use with NVIDIA OO Agents.
License Text(https://spdx.org/licenses/MIT.html)
Source/Homepage: https://github.com/yaml/pyyaml

rich - MIT License
Attribution Statements: NVIDIA includes `rich` under the MIT License for use with NVIDIA OO Agents.
License Text(https://spdx.org/licenses/MIT.html)
Source/Homepage: https://github.com/Textualize/rich

---

## `nemo-oo-agents-benchmarks`
Expand Down Expand Up @@ -369,30 +295,6 @@ Source/Homepage: https://github.com/scipy/scipy

---

## `nooa-cli[web]`

fastapi - MIT License
Attribution Statements: NVIDIA includes `fastapi` under the MIT License for use with NVIDIA OO Agents.
License Text(https://spdx.org/licenses/MIT.html)
Source/Homepage: https://github.com/fastapi/fastapi

nooa-cli[datascience] - Apache License 2.0
Attribution Statements: NVIDIA includes `nooa-cli[datascience]` under the Apache License 2.0 for use with NVIDIA OO Agents.
License Text(https://spdx.org/licenses/Apache-2.0.html)
Source/Homepage: https://github.com/NVIDIA-NeMo/labs-OO-Agents

ptyprocess - ISC License
Attribution Statements: NVIDIA includes `ptyprocess` under the ISC License for use with NVIDIA OO Agents.
License Text(https://spdx.org/licenses/ISC.html)
Source/Homepage: https://github.com/pexpect/ptyprocess

uvicorn - BSD 3-Clause License
Attribution Statements: NVIDIA includes `uvicorn` under the BSD 3-Clause License for use with NVIDIA OO Agents.
License Text(https://spdx.org/licenses/BSD-3-Clause.html)
Source/Homepage: https://github.com/encode/uvicorn

---

## `nemo-oo-agents-benchmarks[bigcodebench]`

beautifulsoup4 - MIT License
Expand Down
59 changes: 3 additions & 56 deletions docs/guides/config-migration.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,60 +18,7 @@ wins). Here's everything you need to move.

`NAT_CONFIG_DIR` is gone — use `NEMO_OO_USER_DIR` to relocate the user dir.

## 2. TUI settings: `config.toml` → `settings.yaml`

Project-only TOML becomes layered YAML (`<project>/.nooa/settings.yaml` or
user-global `~/.config/nooa/settings.yaml`). **Hard switch — `config.toml`
is no longer read.**

**Before — `config.toml`**
```toml
[tui]
model = "claude-opus-4-8"
python = false
vi = false
trace = ".nooa/traces"
mcp_auto_connect = ["maas"]

[tui.mcp_servers.maas]
url = "https://your-mcp-server.example.com/mcp"
transport = "streamable-http"

[tui.mcp_servers.maas.headers]
Authorization = "Bearer ${MAAS_API_KEY}"
```

**After — `settings.yaml`**
```yaml
tui:
default_model: claude-opus-4-8
show_python: false
vi_mode: false
trace_dir: .nooa/traces
mcp_auto_connect: [maas]
mcp_servers:
maas:
url: https://your-mcp-server.example.com/mcp
transport: streamable-http
headers:
Authorization: "Bearer ${MAAS_API_KEY}"
```

Key renames (YAML uses the real field names):

| `config.toml` | `settings.yaml` |
|---------------|-----------------|
| `[tui]` table | `tui:` mapping |
| `model` | `default_model` |
| `python` | `show_python` |
| `vi` | `vi_mode` |
| `trace` | `trace_dir` |
| `libs_dirs`, `mcp_auto_connect` | *(unchanged)* |
| `[tui.mcp_servers.<name>]` | `tui.mcp_servers.<name>:` |

(`/config set model …` still works — friendly keys map to the field names.)

## 3. API keys / secrets
## 2. API keys / secrets

| Before | After |
|--------|-------|
Expand All @@ -88,14 +35,14 @@ A shell `export` still wins (non-clobber), so existing exports keep working —
`secrets.yaml` just means you no longer *need* one. The installer writes this
file for you.

## 4. LLM aliases: `llm_config.yaml`
## 3. LLM aliases: `llm_config.yaml`

Same filename and format — just move it to the new dir:
`~/.config/nat/oo/llm_config.yaml` → `~/.config/nooa/llm_config.yaml`
(or `<project>/.nooa/llm_config.yaml`). `nooa config eject` regenerates
a fresh copy in the new location.

## 5. Environment variables → `NEMO_OO_` prefix
## 4. Environment variables → `NEMO_OO_` prefix

| Before | After |
|--------|-------|
Expand Down
27 changes: 1 addition & 26 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -476,32 +476,7 @@ uv run python examples/quickstart/10_skills.py

### MCP tools

MCP (Model Context Protocol) tools let your agent call external services through a standard interface. The TUI ships MCP as a hard dependency (`self.mcp` and `/mcp` are always available). In the core library, MCP is an optional extra (`uv add 'nooa[mcp]'`).

**TUI configuration** — declare MCP servers in `.nooa/settings.yaml`:

```yaml
tui:
mcp_auto_connect: ["maas-confluence-stg"]
mcp_servers:
maas-confluence-stg:
url: "https://your-mcp-server.example.com/mcp"
transport: "streamable-http"
headers:
Authorization: "Bearer ${MAAS_API_KEY}"
```

At startup the TUI attaches auto-connected servers to the agent, so `maas-confluence-stg` becomes `self.maas_confluence_stg`. A VS Code / Claude-style `.mcp.json` file is also supported via `mcp_file` or `--mcp-file`.

Inside the TUI, servers are managed through `self.mcp` (an `MCPRegistry` skill that mirrors `self.skills`):

- `self.mcp.discovered()` — configured server names
- `await self.mcp.connect(["name"])` — open a server and attach it as `self.<name>`
- `self.mcp.activate([...])` / `self.mcp.deactivate([...])` — control whether a connected server's tools are listed for the agent
- `<mcp>` context block lists every server each turn under **Active**, **Connected but inactive**, or **Configured**
- Slash commands: `/mcp list`, `/mcp connect <server>`, `/mcp disconnect <server>`

**Library use** — no `self.mcp`; call the stateless `MCPManager` factory directly:
MCP (Model Context Protocol) tools let your agent call external services through a standard interface. Install with `uv add 'nooa[mcp]'` and call the stateless `MCPManager` factory:

```python
from nooa.mcp import MCPManager
Expand Down
12 changes: 4 additions & 8 deletions packages/nooa-cli/README.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,25 @@
# nooa-cli

CLI and TUI for [nemo-oo-agents](https://github.com/NVIDIA-NeMo/labs-OO-Agents). Ships the `nooa` command (subcommands like `nooa tui`, `nooa term`, `nooa eval`, `nooa traces`) and the agent TUI (a REPL-driven CodeAct frontend).
CLI for [nemo-oo-agents](https://github.com/NVIDIA-NeMo/labs-OO-Agents). Ships the `nooa` command with subcommands for running evaluations, browsing traces, and managing config.

## Install

```bash
# CLI + TUI
uv add nooa-cli

# ...with numpy/pandas/plotly/scipy/sklearn pre-loaded into the LLM REPL
uv add "nooa-cli[datascience]"

# ...with web-served TUI (uvicorn + ptyprocess + fastapi, plus datascience)
uv add "nooa-cli[web]"
```

`nooa-cli` automatically pulls in matching `nemo-oo-agents` (the core framework). The `[datascience]` extra adds libraries the LLM can use in REPL-generated code; the `[web]` extra adds the `nooa term` web frontend.
`nooa-cli` automatically pulls in matching `nemo-oo-agents` (the core framework). The `[datascience]` extra adds libraries the LLM can use in REPL-generated code.

## Usage

```bash
nooa --help
nooa tui # interactive agent REPL
nooa term # web terminal
nooa start-dev # launch the trace viewer
nooa eval ... # eval pipeline runner
nooa traces ... # inspect/manage trace files
```

See the main repo [README](https://github.com/NVIDIA-NeMo/labs-OO-Agents/blob/main/README.md) for the framework documentation.
33 changes: 5 additions & 28 deletions packages/nooa-cli/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
name = "nooa-cli"
# Version is derived from git tags at build time by uv-dynamic-versioning.
dynamic = ["version"]
description = "CLI and TUI for nemo-oo-agents (`nooa` command, web terminal, agent REPL)"
description = "CLI for nemo-oo-agents (`nooa` command: eval runner, trace viewer, config)"
license = {text = "Apache-2.0"}
readme = "README.md"
requires-python = ">=3.12,<3.14"
Expand All @@ -12,21 +12,8 @@ dependencies = [
# wheels declare what they actually need, not what was co-released.
"nooa",
"click>=8.1.0",
"ipython>=9.12.0",
# prompt-toolkit and rich were only transitive (via ipython and litellm
# respectively); declare them explicitly so we don't break if those
# transitive paths change.
"prompt-toolkit>=3.0.41,<3.1.0",
"rich>=13.0.0",
# Used directly in tui/agent.py and tui/models.py
"pydantic>=2.5.0",
# CLI/TUI config files
# CLI config files
"pyyaml>=6.0",
# MCP is a first-class TUI capability (self.mcp / MCPRegistry, /mcp command,
# mcp_auto_connect). It stays optional in the *core* package for issue-189
# glibc<2.28 hosts, but the CLI already hard-depends on pydantic, so that
# rationale doesn't apply here — make it a hard dep of the TUI package.
"mcp>=1.0.0",
]

[project.scripts]
Expand All @@ -47,26 +34,16 @@ ast = [
"tree-sitter-rust>=0.23.0",
]
# Data-science stack pre-loaded into the agent's REPL execution namespace
# (np, pd, px, go, scipy, sklearn). Soft-imported via try/except in
# TUI agent REPLs work without these too;
# they exist purely so LLM-generated CodeAct cells can use these libs
# without first failing on a missing import.
# (np, pd, px, go, scipy, sklearn). Soft-imported via try/except; they
# exist purely so LLM-generated CodeAct cells can use these libs without
# first failing on a missing import.
datascience = [
"numpy>=1.24.0",
"pandas>=2.0.0",
"plotly>=5.0.0",
"scipy>=1.10.0",
"scikit-learn>=1.3.0",
]
# Web-served TUI (`nooa term`): uvicorn + ptyprocess + fastapi, plus
# the data-science stack so the LLM has the same REPL capabilities as
# in the local terminal.
web = [
"nooa-cli[datascience]",
"uvicorn[standard]>=0.34.0",
"ptyprocess>=0.7.0",
"fastapi>=0.123.4",
]

[tool.uv.sources]
nooa = { workspace = true }
Expand Down
18 changes: 7 additions & 11 deletions packages/nooa-cli/src/nooa_cli/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,9 @@
CONTEXT_SETTINGS = {"help_option_names": ["-h", "--help"]}


# Thin launcher subcommands that don't touch API keys in *this* process:
# `term` runs a web/PTY server and re-spawns the CLI as a child (which loads
# secrets itself via bootstrap); `completion` just emits a shell script.
# Skipping the secrets preload for them avoids importing the heavy
# ``nooa`` core (~1.5s) on startup — keeping `nooa term` fast and
# its SIGINT shutdown prompt.
_SKIP_SECRETS_PRELOAD = {"term", "completion"}
# `completion` just emits a shell script and doesn't need the ~1.5s core
# import cost or secrets preload.
_SKIP_SECRETS_PRELOAD = {"completion"}


@click.group(context_settings=CONTEXT_SETTINGS)
Expand All @@ -45,10 +41,10 @@ def oo(ctx):
if ctx.invoked_subcommand in _SKIP_SECRETS_PRELOAD:
return
# Load secrets.yaml into the process env before any subcommand runs so
# non-TUI commands (config show, eval, …) see the same API keys the TUI
# does. Non-clobbering (shell env wins) and best-effort: a broken or
# missing secrets file must never block the CLI — but log the failure at
# debug so it's recoverable rather than silently swallowed.
# all commands (config show, eval, …) see the same API keys.
# Non-clobbering (shell env wins) and best-effort: a broken or missing
# secrets file must never block the CLI — but log the failure at debug
# so it's recoverable rather than silently swallowed.
try:
from nooa.secrets import load_secrets_into_env

Expand Down
Loading
Loading