Skip to content
Open
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ $RECYCLE.BIN/
/.cursor/
.env
benchmarks/
**/.nemoflow/

# Local third-party upstream checkouts. These are bootstrapped from
# third_party/sources.lock and are intentionally excluded from the tracked
Expand Down
1 change: 1 addition & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ Advanced Guide: Handle Non-Serializable Data <integrate-frameworks/non-serializa
Advanced Guide: Using Codecs <integrate-frameworks/using-codecs>
Advanced Guide: Provider Codecs <integrate-frameworks/provider-codecs>
Advanced Guide: Provider Response Codecs <integrate-frameworks/provider-response-codecs>
OpenCode Plugin <integrate-frameworks/opencode>
Code Examples <integrate-frameworks/code-examples>
```

Expand Down
1 change: 1 addition & 0 deletions docs/integrate-frameworks/about.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ Use these guide links to move from the overview into task-specific instructions.
- [Advanced Guide: Using Codecs](using-codecs.md) explains typed value codecs for framework-facing wrappers.
- [Advanced Guide: Provider Codecs](provider-codecs.md) explains provider request and response codecs for normalized middleware and event annotations.
- [Advanced Guide: Provider Response Codecs](provider-response-codecs.md) focuses on response-only annotations for subscribers and exporters.
- [OpenCode Plugin](opencode.md) explains how to install and configure the standalone OpenCode observability plugin.
- [Code Examples](code-examples.md) collects fallback APIs, mark events, and repository patch workflow examples.

Start by identifying the framework's stable tool and LLM boundaries. Prefer
Expand Down
146 changes: 146 additions & 0 deletions docs/integrate-frameworks/opencode.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
<!--
SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
SPDX-License-Identifier: Apache-2.0
-->

# OpenCode Plugin

NeMo Flow integrates with OpenCode through the `nemo-flow-opencode` server
plugin. The plugin uses OpenCode's public plugin hooks and does not require a
patched OpenCode checkout.

Use this plugin when you want NeMo Flow observability for OpenCode sessions,
LLM calls, successful tool calls, and session errors. The plugin maps OpenCode
hook payloads into NeMo Flow session, LLM, and tool spans. The generic NeMo
Flow `observability` component controls ATOF, ATIF, OpenTelemetry, and
OpenInference export.

## Requirements

- OpenCode with server plugin support.
- Node.js 20 or newer.
- A NeMo Flow Node.js binding package compatible with `nemo-flow-opencode`.
- Provider credentials configured in OpenCode.

## Install

Install the plugin with the OpenCode CLI:

```bash
opencode plugin nemo-flow-opencode
```

You can also install the package in the Node.js environment where OpenCode
loads plugins:

```bash
npm install nemo-flow-opencode
```

OpenCode uses the package name `nemo-flow-opencode` in the `plugin` array.

## Enable and Configure the Plugin

Create or update `opencode.json` in the OpenCode project directory:

```json
{
"plugin": [
[
"nemo-flow-opencode",
{
"enabled": true,
"logPath": "./.nemoflow/opencode-plugin.log",
"plugins": {
"version": 1,
"components": [
{
"kind": "observability",
"enabled": true,
"config": {
"version": 1,
"atof": {
"enabled": true,
"output_directory": "./.nemoflow",
"filename": "opencode.atof.jsonl",
"mode": "overwrite"
},
"atif": {
"enabled": true,
"agent_name": "opencode",
"output_directory": "./.nemoflow",
"filename_template": "opencode-{session_id}.atif.json"
},
"opentelemetry": {
"enabled": false,
"transport": "http_binary",
"endpoint": "http://localhost:4318/v1/traces",
"service_name": "opencode-nemo-flow"
},
"openinference": {
"enabled": false,
"transport": "http_binary",
"endpoint": "http://localhost:6006/v1/traces",
"service_name": "opencode-nemo-flow"
}
}
}
]
}
}
]
]
}
```

This example enables filesystem ATOF and ATIF export and leaves OTLP exporters
disabled until you point them at a collector or Phoenix endpoint. Remove
exporter sections you do not use, or set their `enabled` fields to `false`.

- `plugin[][0]` is the OpenCode plugin package name. Use
`nemo-flow-opencode`.
- `enabled` disables or enables the NeMo Flow OpenCode wrapper without removing
the plugin entry.
- `logPath` writes JSONL diagnostics for plugin initialization and
pass-through behavior.
- `plugins` is the generic NeMo Flow plugin configuration document. Use this
object to configure built-in components such as `observability`.
- `plugins.components[].config.atof` writes raw ATOF JSONL lifecycle events.
- `plugins.components[].config.atif` writes ATIF trajectory JSON files.
- `plugins.components[].config.opentelemetry` sends generic OTLP spans to an
OpenTelemetry collector when `enabled` is `true`.
- `plugins.components[].config.openinference` sends OpenInference OTLP spans to
Phoenix or another OpenInference-compatible collector when `enabled` is
`true`.

## Configuration Key Names

OpenCode wrapper fields use JavaScript-style names, such as `logPath`.

The top-level `plugins` object inside the wrapper is the generic NeMo Flow
plugin config. Fields inside this object use NeMo Flow generic plugin names, so
they are `snake_case` in every binding.

Missing observability sections are disabled. Plugin-host validation or
initialization failures leave OpenCode in pass-through mode and write a warning
to `logPath`.

The ATIF filename placeholder `{session_id}` is the NeMo Flow top-level agent
scope UUID. The OpenCode session ID is recorded in event metadata.

See [Configure the Observability Plugin](../export-observability-data/observability-plugin.md)
for the complete `observability` component schema and exporter-specific fields.

The plugin is passive. It records observability output but does not rewrite
prompts, tool arguments, model requests, or OpenCode execution behavior.

OpenCode streaming message events are used internally to reconstruct concise
LLM responses. They are not exported as individual ATIF steps.

## Known Limitations

The current OpenCode plugin API is enough for passive observability. It is not
enough for NeMo Flow request intercepts, execution intercepts, conditional
blocking, or complete tool error spans because OpenCode does not yet expose
around-style LLM or tool hooks. Future work should add generic OpenCode plugin
hooks upstream before enabling those behaviors.
94 changes: 94 additions & 0 deletions integrations/opencode/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<!--
SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved.
SPDX-License-Identifier: Apache-2.0
-->

# NeMo Flow OpenCode Plugin

`nemo-flow-opencode` is a standalone OpenCode server plugin for NeMo Flow
observability. It uses OpenCode's public plugin API and does not require
patching OpenCode. It maps OpenCode activity into NeMo Flow session, LLM, and
tool spans for the generic observability plugin.

For the full guide, see `docs/integrate-frameworks/opencode.md` in the NeMo
Flow documentation.

## Install

Install the plugin with the OpenCode CLI:

```bash
opencode plugin nemo-flow-opencode
```

You can also install the package in the Node.js environment where OpenCode
loads plugins:

```bash
npm install nemo-flow-opencode
```

## Configure

Use the package name in `opencode.json`:

```json
{
"plugin": [
[
"nemo-flow-opencode",
{
"enabled": true,
"logPath": "./.nemoflow/opencode-plugin.log",
"plugins": {
"version": 1,
"components": [
{
"kind": "observability",
"enabled": true,
"config": {
"version": 1,
"atof": {
"enabled": true,
"output_directory": "./.nemoflow",
"filename": "opencode.atof.jsonl"
},
"atif": {
"enabled": true,
"agent_name": "opencode",
"output_directory": "./.nemoflow",
"filename_template": "opencode-{session_id}.atif.json"
}
}
}
]
}
}
]
]
}
```

Fields inside `plugins` are NeMo Flow generic plugin configuration, so they use
`snake_case`. The OpenCode wrapper fields use JavaScript-style names, such as
`logPath`.

## Output

Configure the built-in `observability` component to write:

- ATOF JSONL events with `plugins.components[].config.atof`.
- ATIF trajectory files with `plugins.components[].config.atif`.
- Optional OpenTelemetry or OpenInference traces with
`plugins.components[].config.opentelemetry` or `openinference`.
Comment thread
billxbf marked this conversation as resolved.
- JSONL plugin diagnostics with the OpenCode wrapper `logPath` field.

OpenCode streaming message events are used internally to reconstruct concise
LLM responses. They are not exported as individual ATIF steps.

## Current Limitations

This plugin uses only existing OpenCode hooks. OpenCode does not yet expose an
around-style LLM stream hook or tool execution hook, so the plugin cannot record
exact LLM stream duration, tool error spans for every failure path, request
intercepts, execution intercepts, or conditional guardrail blocking.
52 changes: 52 additions & 0 deletions integrations/opencode/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"name": "nemo-flow-opencode",
"version": "0.2.0",
"description": "OpenCode server plugin that maps OpenCode activity into NeMo Flow observability.",
"type": "module",
"main": "./server.js",
"exports": {
".": {
"default": "./server.js"
},
"./server": {
"default": "./server.js"
}
},
Comment thread
billxbf marked this conversation as resolved.
"files": [
"README.md",
"server.js"
],
"scripts": {
"test": "node --test test/*.mjs"
},
"keywords": [
"opencode",
"nemo-flow",
"observability",
"atif",
"atof",
"plugin"
],
"homepage": "https://github.com/NVIDIA/NeMo-Flow/blob/main/docs/integrate-frameworks/opencode.md",
"bugs": {
"url": "https://github.com/NVIDIA/NeMo-Flow/issues"
},
"repository": {
"type": "git",
"url": "git+https://github.com/NVIDIA/NeMo-Flow.git",
"directory": "integrations/opencode"
},
"license": "Apache-2.0",
"engines": {
"node": ">=20.0.0"
},
"dependencies": {
"nemo-flow-node": ">0.1.0 <1.0.0"
},
Comment thread
billxbf marked this conversation as resolved.
"peerDependencies": {
"@opencode-ai/plugin": ">=1.14.40"
},
"devDependencies": {
"@opencode-ai/plugin": "^1.14.40"
}
}
Loading