Skip to content

Add OpenCode + NVIDIA Nemotron custom app - #473

Open
samhornstein wants to merge 5 commits into
masterfrom
BENCH-9850-opencode-nemotron
Open

Add OpenCode + NVIDIA Nemotron custom app#473
samhornstein wants to merge 5 commits into
masterfrom
BENCH-9850-opencode-nemotron

Conversation

@samhornstein

@samhornstein samhornstein commented Aug 24, 2026

Copy link
Copy Markdown

Adds src/opencode-nemotron: code-server with the opencode agent driving a local NVIDIA Nemotron model on Ollama. Nothing leaves the VM. For the NVIDIA dev day demo. Derived from feature/applegath/ollama_gemma-4-26B-A4B.

This PR:

  • Serves code-server on 8443 and Ollama on 11434 (container-local). Pins opencode 1.18.22.
  • Defaults to nemotron-3.5-lightning:30b — 30B MoE, tool calling, 25 GB of weights. Needs an A100 40 GB.
  • Writes ~/.config/opencode/opencode.json on create and restart, with share: "disabled" so sessions never reach opencode's hosted sharing service.
  • Sets OLLAMA_CONTEXT_LENGTH=32768. Tool calls are unreliable below ~16k.

Two deviations worth review:

  • Model tag lives in docker-compose.yaml, not a template option. The VM substitutes only login, cloud, containerImage, containerPort, shmSize, and memoryLimit (startupscript/butane/050-parse-devcontainer.sh). A custom option stays literal and breaks docker-compose config.
  • OpenJDK 17 comes from apt, not ghcr.io/devcontainers/features/java. That feature is currently broken for all 13 apps that use it, including vscode-with-llm and nemo_jupyter: Microsoft's Java 17 SDKMAN identifier is now 17.0.20+1-ms, and the feature's regex rejects the +1 segment. Upstream: java: major-only version fails to resolve once a vendor publishes a four-component release (21.0.12.1 → 21.0.12+1-ms) devcontainers/features#1712, fix in #1713. Pinning the digest does not help — the lookup is against SDKMAN's live catalog. The other apps need a separate ticket. This app stays unaffected by the upstream outcome either way; install-java.sh only needs /usr/bin/java.

Testing

Deployed to samh-sandbox on a2-highgpu-1g (1x A100 40 GB, us-central1-c):

  • ollama psnemotron-3.5-lightning:30b, 25 GB, 100% GPU, context 32768.
  • opencode run "Read hello.txt and tell me exactly how many lines it has" → agent called its read tool and answered correctly.
  • java 17.0.19 and wb on the PATH, so post-startup.sh succeeds. code-server answers on 8443.

Not registered in test-pr.yaml: CI runs devcontainer up, which would pull 25 GB on a GPU-less runner.

BENCH-9850

@samhornstein
samhornstein requested review from a team as code owners August 24, 2026 21:53
@samhornstein
samhornstein marked this pull request as draft August 24, 2026 22:05
@samhornstein
samhornstein requested a review from PeterSu92 August 24, 2026 22:18
@samhornstein
samhornstein marked this pull request as ready for review August 24, 2026 22:25
@pantherman594

Copy link
Copy Markdown
Contributor

If this is for a NVIDIA demo, would it be fine staying in/running from a branch? Does it need to be merged into master?

@samhornstein

Copy link
Copy Markdown
Author

If this is for a NVIDIA demo, would it be fine staying in/running from a branch? Does it need to be merged into master?

@pantherman594 Technically speaking, we can pull in a custom app from a feature branch, so we don't need to merge into master. The question then is if we want this in master or not. Thoughts?

@samhornstein

Copy link
Copy Markdown
Author

Decision: Wait on merge until after demo

messages=[{"role": "user", "content": "Hello!"}],
max_tokens=100,
)
print(response.choices[0].message.content)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

did you test this? When I tried, using response.choices[0].message.content didn't work, but response.choices[0].message.reasoning} did - apparently this is a characteristic of the Nemotron model's output format?


## Changing the Model

The model tag lives in `OLLAMA_MODEL` in `docker-compose.yaml`. Edit it in your

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: it would be great if this was more configurable than having to edit the docker-compose.yaml file before app creation, especially bc you can change the config of a Workbnech app after it's stopped, so if you wanted to move from A100 -> L4, it'd break

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.

3 participants