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
2 changes: 1 addition & 1 deletion .agents/skills/review-doc-style/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ and NeMo Fabric repo conventions.
- `README.md`
- `docs/index.yml`
- Package or crate READMEs
- Adapter and integration READMEs such as `adapters/codex-cli/README.md` or `integrations/harbor/README.md`
- Adapter and integration READMEs such as `adapters/codex/README.md` or `integrations/harbor/README.md`
4. Start with `assets/nvidia-style-guide.md`, then open only the focused support document needed for the issue under review.
5. Scan for high-signal style issues in headings, links, code formatting, terminology, procedures, and plain-English readability.
6. Report findings in severity order with file references and concrete rewrites.
Expand Down
22 changes: 21 additions & 1 deletion ATTRIBUTIONS-Python.md
Original file line number Diff line number Diff line change
Expand Up @@ -1281,7 +1281,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
```

## claude-agent-sdk (0.2.114)
## claude-agent-sdk (0.2.120)

### Licenses
License: `MIT`
Expand Down Expand Up @@ -6225,6 +6225,26 @@ Apache License
limitations under the License.
```

## openai-codex (0.1.0b3)

### Licenses
License: `Apache-2.0`

- `LICENSE`:
```
(No license file found in locked artifact for openai-codex; see package metadata or PyPI.)
```
Comment thread
coderabbitai[bot] marked this conversation as resolved.

## openai-codex-cli-bin (0.137.0a4)

### Licenses
License: `Apache-2.0`

- `LICENSE`:
```
(No license file found in locked artifact for openai-codex-cli-bin; see package metadata or PyPI.)
```

## orjson (3.11.9)

### Licenses
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,8 @@ authentication, and execution details.
`disallowed_tools`, Deep Agents enforces them with middleware, and adapters
without a native deny mechanism route the policy as unsupported.
- **Adapters:** harness-specific integrations selected by `harness.adapter_id`.
The Hermes adapter lives under `adapters/hermes/`; the Codex CLI
adapter lives under `adapters/codex-cli/`; the
The Hermes adapter lives under `adapters/hermes/`; the Codex SDK
adapter lives under `adapters/codex/`; the
[Claude adapter](adapters/claude/README.md)
lives under `adapters/claude/`; the LangChain Deep Agents adapter lives under
`adapters/deepagents/`. Harness-specific extensions belong under
Expand Down Expand Up @@ -192,7 +192,7 @@ the [Python SDK guide](docs/sdk/python.mdx). Exact signatures are in the
[multi-harness demo](examples/harbor/demo/README.md): ownership,
installation, and complete command matrices.
- Adapter guides: [Hermes](adapters/hermes/README.md),
[Codex CLI](adapters/codex-cli/README.md), and
[Codex SDK](adapters/codex/README.md), and
[Deep Agents](adapters/deepagents/README.md).

## Tests
Expand Down
28 changes: 28 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<!--
SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
SPDX-License-Identifier: Apache-2.0
-->

# Temporary Workarounds

Track repository workarounds that must be removed after an upstream dependency
ships. Each entry must identify an upstream reference, removal condition, and
cleanup validation.

## NeMo Relay 0.6.x Request Decoding Release

- **Status:** Waiting for an upstream release
- **Added:** July 16, 2026
- **Affected documentation:** `adapters/codex/README.md` and
`docs/integrations/codex.mdx`
- **Reason:** Released NeMo Relay versions do not yet decode the
`zstd`-compressed request bodies emitted by the Codex SDK, so semantic Relay
artifacts require a source installation.
- **Upstream resolution:**
[NVIDIA/NeMo-Relay#452](https://github.com/NVIDIA/NeMo-Relay/pull/452), merged
as `fe144d0d23e483c8216537118304e306abc20837`
- **Removal condition:** A published `nemo-relay-cli` version in Fabric's
supported `>=0.6.0,<0.7.0` range contains the merged request-decoding fix.
- **Cleanup:** Replace the pinned source-install instructions with the released
CLI installation, run the Codex Relay end-to-end test, update both affected
documentation files, and remove this entry.
13 changes: 11 additions & 2 deletions adapters/claude/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ The `nvidia.fabric.claude` adapter uses the official Claude Agent SDK for
Python behind Fabric's normalized invocation contract. The SDK is an
implementation detail; consumers select the Claude harness by adapter ID.

This adapter pins `claude-agent-sdk==0.2.120`. The SDK supplies its compatible
Claude Code runtime unless `harness.settings.cli_path` explicitly selects
another executable.

## Install

```bash
Expand Down Expand Up @@ -40,8 +44,8 @@ Refer to the [Claude adapter authentication guide](https://nvidia-nemo-fabric.do
for mode selection, required WIF variables, and the Relay boundary. Package
installation is verified by the adapter wheel and module-entrypoint tests.

Relay-enabled runs also require the external `nemo-relay` CLI. Install the CLI
separately:
Relay-enabled runs also require the external `nemo-relay` CLI. Fabric accepts
CLI versions `>=0.6.0,<0.7.0`. Install the CLI separately:

```bash
cargo install nemo-relay-cli
Expand Down Expand Up @@ -217,3 +221,8 @@ RUN_FABRIC_CLAUDE_RELAY_INTEGRATION=1 uv run --no-sync pytest tests/e2e/test_cla
```

The first command uses the mock Claude client and does not require credentials.
Set `FABRIC_TEST_CLAUDE_MODEL` to override the default live-test model,
`claude-sonnet-4-5`.
The live Relay test applies the same semantic artifact contract as Codex: ATOF
must contain structured LLM requests and token usage, and ATIF must contain the
expected agent response.
2 changes: 1 addition & 1 deletion adapters/claude/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ readme = "README.md"
requires-python = ">=3.11"
dependencies = [
"nemo-fabric-adapters-common == 0.1.0",
"claude-agent-sdk==0.2.114",
"claude-agent-sdk==0.2.120",
"tomli-w~=1.2",
]

Expand Down
26 changes: 21 additions & 5 deletions adapters/claude/src/nemo_fabric_adapters/claude/adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import asyncio
import json
import logging
import math
import os
import shlex
Expand All @@ -32,6 +33,8 @@
from nemo_fabric_adapters.common import relay_hooks
from nemo_fabric_adapters.common import utils as common_utils

LOGGER = logging.getLogger(__name__)

PERMISSION_MODES = {
"default",
"acceptEdits",
Expand Down Expand Up @@ -80,6 +83,7 @@
"TEMP",
"TMP",
"TMPDIR",
"USER",
"USERPROFILE",
"XDG_CACHE_HOME",
"XDG_CONFIG_HOME",
Expand Down Expand Up @@ -389,14 +393,12 @@ def prepare_claude_relay(payload: dict[str, Any]) -> ClaudeRelaySettings | None:
) from error

try:
observability_version = relay_gateway.relay_cli_observability_version(
executable
)
relay_contract = relay_gateway.relay_cli_contract(executable)
plugin_config = common_utils.load_relay_plugin_config(payload)
config_path, plugin_config_path = common_utils.write_relay_configs(
relay_config={"agents": {"claude": {"command": "claude"}}},
plugin_config=plugin_config,
observability_version=observability_version,
observability_version=relay_contract.observability_version,
)
except (
OSError,
Expand Down Expand Up @@ -594,9 +596,15 @@ def normalize_message(message: Message) -> dict[str, Any]:
return {"type": type(message).__name__, "message": _json_safe(message)}


def _result_failed(result: ResultMessage) -> bool:
return bool(result.is_error) or (
isinstance(result.subtype, str) and result.subtype.startswith("error_")
)


def normalize_result(payload: dict[str, Any], messages: list[Message], result: ResultMessage) -> dict[str, Any]:
del payload
failed = bool(result.is_error) or (isinstance(result.subtype, str) and result.subtype.startswith("error_"))
failed = _result_failed(result)
error = None
if failed:
error = {
Expand Down Expand Up @@ -743,6 +751,14 @@ async def run_claude(payload: dict[str, Any]) -> dict[str, Any]:
messages.append(message)
except (TimeoutError, ClaudeSDKError) as error:
output = sdk_failure(error)
except Exception:
# Claude Agent SDK 0.2.120 can yield an error ResultMessage and then
# raise a plain Exception while closing the query stream. Preserve
# the typed terminal result, but do not hide unrelated exceptions.
if result is None or not _result_failed(result):
raise
LOGGER.exception("Claude SDK stream raised after a failed terminal result")
output = normalize_result(payload, messages, result)
else:
if result is None:
output = _failure(
Expand Down
16 changes: 8 additions & 8 deletions adapters/claude/uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

56 changes: 0 additions & 56 deletions adapters/codex-cli/README.md

This file was deleted.

Loading
Loading