Skip to content
Closed
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
21 changes: 21 additions & 0 deletions agents/nemocua/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

ARG BASE_IMAGE
# hadolint ignore=DL3006
FROM ${BASE_IMAGE}

USER root

COPY agents/nemocua/nemocua-runtime.sh /usr/local/bin/nemocua-runtime
COPY agents/nemocua/runtime-artifacts.json /usr/local/share/nemoclaw/nemocua-runtime-artifacts.json

RUN chown root:root \
/usr/local/bin/nemocua-runtime \
/usr/local/share/nemoclaw/nemocua-runtime-artifacts.json \
&& chmod 0755 /usr/local/bin/nemocua-runtime \
&& chmod 0444 /usr/local/share/nemoclaw/nemocua-runtime-artifacts.json \
&& /usr/local/bin/nemocua-runtime version \
&& /usr/local/bin/nemocua-runtime smoke --image-build

USER sandbox
23 changes: 23 additions & 0 deletions agents/nemocua/Dockerfile.base
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# The private source coordinate is deliberately not recorded here. The image
# release lane imports the verified linux/amd64 OCI archive, tags that exact
# object as NEMOCUA_RUNTIME_IMAGE, and passes the immutable local reference.

ARG NEMOCUA_RUNTIME_IMAGE
# hadolint ignore=DL3006
FROM ${NEMOCUA_RUNTIME_IMAGE}

USER root

COPY agents/nemocua/runtime-artifacts.json /usr/local/share/nemoclaw/nemocua-runtime-artifacts.json

RUN command -v python3 \
&& test -f /app/run.py \
&& test -f /app/run_with_harness.py \
&& test -s /usr/local/share/nemoclaw/nemocua-runtime-artifacts.json \
&& chown root:root /usr/local/share/nemoclaw/nemocua-runtime-artifacts.json \
&& chmod 0444 /usr/local/share/nemoclaw/nemocua-runtime-artifacts.json

USER sandbox
42 changes: 42 additions & 0 deletions agents/nemocua/manifest.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

name: nemocua
display_name: "NemoCUA"
description: "Computer-use agent for browser, desktop, and terminal tasks"
language: python
license: Apache-2.0

binary_path: /usr/local/bin/nemocua-runtime
version_command: "nemocua-runtime version"
expected_version: "0.0.20-dev-v3"
version_scheme: semver
runtime:
kind: terminal
interactive_command: "nemocua-runtime interactive"
headless_command: "nemocua-runtime headless"
smoke_commands:
- "nemocua-runtime smoke"

config:
dir: /sandbox/.nemocua
config_file: runtime.json
format: json

# Task content and evidence remain private target/runtime material. NemoClaw
# persists only the bounded, content-free CUA lifecycle records in its host
# registry, so no NemoCUA runtime directory is part of generic backup/restore.
state_dirs: []
state_files: []
user_managed_files: []

device_pairing: false

inference:
provider_type: openai_compatible
default_model: nvidia/nemotron-3-super-120b-a12b
proxy_support: implicit

mcp:
support: disabled
reason: "The first CUA runtime slice exposes only the versioned CUA lifecycle contract."
66 changes: 66 additions & 0 deletions agents/nemocua/nemocua-runtime.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#!/usr/bin/env bash
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

set -euo pipefail

readonly NEMOCUA_RUNTIME_VERSION="0.0.20-dev-v3"
readonly NEMOCUA_APP_ROOT="/app"
readonly NEMOCUA_RUNS_DIR="/sandbox/.nemocua/runs"
readonly NEMOCUA_ARTIFACTS="/usr/local/share/nemoclaw/nemocua-runtime-artifacts.json"
NEMOCUA_PYTHON="$(command -v python3 2>/dev/null || true)"
readonly NEMOCUA_PYTHON

require_runtime() {
case "$NEMOCUA_PYTHON" in
/usr/bin/python3 | /usr/local/bin/python3) ;;
*) return 1 ;;
esac
test -f "${NEMOCUA_APP_ROOT}/run.py"
test -f "${NEMOCUA_APP_ROOT}/run_with_harness.py"
test -s "$NEMOCUA_ARTIFACTS"
}

probe_inference() {
if ! command -v curl >/dev/null 2>&1; then
printf '%s\n' "NemoCUA managed inference smoke requires curl." >&2
return 1
fi
curl --fail --silent --show-error --max-time 10 \
https://inference.local/v1/models >/dev/null
}

case "${1:-}" in
version | --version)
require_runtime
printf '%s\n' "$NEMOCUA_RUNTIME_VERSION"
;;
smoke)
require_runtime
if [[ "${2:-}" != "--image-build" ]]; then
probe_inference
fi
printf '%s\n' "NEMOCUA_RUNTIME_SMOKE_OK"
;;
interactive)
shift
require_runtime
exec "$NEMOCUA_PYTHON" "${NEMOCUA_APP_ROOT}/run.py" "$@"
;;
headless)
shift
require_runtime
if (($# == 0)); then
printf '%s\n' "NemoCUA headless execution requires task text." >&2
exit 2
fi
mkdir -p "$NEMOCUA_RUNS_DIR"
task_id="nemoclaw-$(date -u +%Y%m%dT%H%M%SZ)-$$"
exec "$NEMOCUA_PYTHON" "${NEMOCUA_APP_ROOT}/run_with_harness.py" \
--runs-dir "$NEMOCUA_RUNS_DIR" start --task-id "$task_id" --query "$*"
;;
*)
printf '%s\n' "Usage: nemocua-runtime {interactive|headless|version|smoke}" >&2
exit 2
;;
esac
46 changes: 46 additions & 0 deletions agents/nemocua/policy-additions.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0

version: 1

filesystem_policy:
include_workdir: true
read_only:
- /usr
- /lib
- /app
- /proc
- /etc
read_write:
- /sandbox
- /tmp
- /dev/null
- /dev/pts
- /sandbox/.nemocua

landlock:
compatibility: best_effort

process:
run_as_user: sandbox
run_as_group: sandbox

network_policies:
managed_inference:
name: managed_inference
endpoints:
- host: inference.local
port: 443
protocol: rest
enforcement: enforce
rules:
- allow: { method: POST, path: "/v1/chat/completions" }
- allow: { method: POST, path: "/v1/responses" }
- allow: { method: GET, path: "/v1/models" }
- allow: { method: GET, path: "/v1/models/**" }
binaries:
- { path: /usr/local/bin/nemocua-runtime }
- { path: /usr/bin/python3 }
- { path: /usr/local/bin/python3 }
- { path: /usr/bin/curl }
- { path: /usr/local/bin/curl }
29 changes: 29 additions & 0 deletions agents/nemocua/runtime-artifacts.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"schemaVersion": 1,
"compatibility": {
"status": "awaiting-live-qualification",
"issue": 7755
},
"hostCli": {
"name": "nemocua",
"version": "0.0.20-dev-v3",
"filename": "nemocua_linux_amd64.tar.gz",
"sizeBytes": 12322325,
"sha256": "702d93c4fc01ba4aafdd23daaf17fd25cea8f7deab3f1caa1c91ef047f4778aa",
"sourceRevision": "d2f6b3b7bff5d6cb14eb1b5fdb255b660246762b"
},
"sandboxImage": {
"name": "nvlumina",
"version": "v0.0.5",
"platform": "linux/amd64",
"digest": "sha256:c1a577fc8f69071642b97706130df26abd8a89b8bd429a9ef37abf0ccd634e0b"
},
"targetServices": {
"name": "nemocua-services",
"version": "0.0.66-dev-v29",
"filename": "nemocua-services-linux-x86_64-v0.0.66-dev-v29.tar.gz",
"sizeBytes": 183706364,
"sha256": "6d731e02226b364daa61d3521e5903b86f1e4260e41d330b1a7daed5c3ae3b01",
"sourceRevision": "712a4e707f816c07a2158e6e3dd1ea77fd91977e"
}
}
4 changes: 2 additions & 2 deletions ci/source-architecture-budget.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"src/lib/adapters/openshell/timeouts.ts": 37,
"src/lib/agent/defs.ts": 32,
"src/lib/cli/branding.ts": 84,
"src/lib/cli/nemoclaw-oclif-command.ts": 103,
"src/lib/cli/nemoclaw-oclif-command.ts": 121,
"src/lib/cli/terminal-style.ts": 45,
"src/lib/core/json-types.ts": 37,
"src/lib/core/ports.ts": 87,
Expand All @@ -39,7 +39,7 @@
"src/lib/actions/inference-set.ts": 32,
"src/lib/actions/sandbox/connect.ts": 38,
"src/lib/actions/sandbox/destroy.ts": 29,
"src/lib/actions/sandbox/doctor.ts": 29,
"src/lib/actions/sandbox/doctor.ts": 30,
"src/lib/actions/sandbox/policy-channel.ts": 29,
"src/lib/actions/sandbox/process-recovery.ts": 22,
"src/lib/actions/sandbox/rebuild-pipeline.ts": 28,
Expand Down
Loading