@grafana/agento11y-opencode
v0.21.0
Published
OpenCode plugin for Grafana Agent Observability
Readme
@grafana/agento11y-opencode
OpenCode plugin that sends LLM generations to Grafana Agent Observability.
By default only metadata is sent (token counts, cost, model, tool names, durations). Set AGENTO11Y_CONTENT_CAPTURE_MODE to full, no_tool_content, metadata_only, or full_with_metadata_spans to control what is sent. default is accepted as an alias for metadata_only. See Content Capture Modes for the full reference.
1. Install and launch
Quick install (Linux/macOS):
curl -fsSL https://raw.githubusercontent.com/grafana/agento11y/main/plugins/agento11y/scripts/install.sh | sh
agento11y opencodeHomebrew (macOS):
brew install grafana/grafana/agento11y
agento11y opencodeGo install (Windows, or any platform with Go 1.25+):
go install github.com/grafana/agento11y/plugins/agento11y/cmd/agento11y@latest
agento11y opencodeThe script installs agento11y to ~/.local/bin; go install uses go env GOPATH/bin (or GOBIN). Make sure that directory is on your PATH. See the agento11y binary README for all install options. The command was renamed from sigil; the old name still works but will be removed in a future release.
On first run, agento11y opencode asks where sessions go, saves the answer to ~/.config/agento11y/config.env, then installs @grafana/agento11y-opencode and launches OpenCode. Grafana Cloud asks for the credentials below. Local only sets AGENTO11Y_LOCAL=true and starts the local receiver for that launch. The question needs macOS or Linux and a terminal; see Configure for the full rules. Pass arguments to OpenCode after --, for example, agento11y opencode -- run "say hi".
opencode plugin @grafana/agento11y-opencode --global
agento11y loginThe plugin reads ~/.config/agento11y/config.env on every session start, whether you start OpenCode with agento11y opencode or plain opencode. If you only have the old ~/.config/sigil/config.env, that file is used instead.
2. Credentials
When agento11y opencode or agento11y login prompts and you pick Grafana Cloud, it asks which Grafana stack you are on, then prints that stack's coding-agent setup page (https://<your-stack>.grafana.net/a/grafana-agento11y-app/setup-coding-agent) and tries to open it in a browser. Copy the environment block that page hands out, paste it into the next prompt, and the endpoint, instance ID, token, and OTLP endpoint are all filled from it. The stack is saved, so a later run offers it back and you press Enter. Make sure Agent Observability is enabled on your stack: an administrator opens Observability → Agent Observability once and accepts the terms.
To type the values instead, press Enter on the empty paste box. They come from three Grafana Cloud pages:
Agent Observability → Configuration
- API URL →
AGENTO11Y_ENDPOINT - Instance ID →
AGENTO11Y_AUTH_TENANT_ID
- API URL →
Administration → Users and access → Cloud access policies
- Create a policy with scopes
sigil:write,metrics:write,traces:write. - Add a token. The
glc_…value is shown once →AGENTO11Y_AUTH_TOKEN.
- Create a policy with scopes
Grafana Cloud Portal → your stack → OpenTelemetry card
- OTLP endpoint URL →
AGENTO11Y_OTEL_EXPORTER_OTLP_ENDPOINT
- OTLP endpoint URL →
Run agento11y login later to update saved credentials; a rerun asks the Cloud questions again.
Create or update ~/.config/agento11y/config.env (if you already have the old ~/.config/sigil/config.env, edit that one instead):
AGENTO11Y_ENDPOINT=https://agento11y-prod-<region>.grafana.net
AGENTO11Y_AUTH_TENANT_ID=<instance-id>
AGENTO11Y_AUTH_TOKEN=glc_...
AGENTO11Y_OTEL_EXPORTER_OTLP_ENDPOINT=https://otlp-gateway-prod-<region>.grafana.net/otlpWhen AGENTO11Y_AUTH_TENANT_ID and AGENTO11Y_AUTH_TOKEN are set, the plugin uses them for Agent Observability and OTLP auth. If the OpenTelemetry card shows a different Instance ID, set OTEL_EXPORTER_OTLP_HEADERS=Authorization=Basic <base64(otlp-id:glc_token)>.
To include conversation text, add this to your config.env:
AGENTO11Y_CONTENT_CAPTURE_MODE=fullOpenCode redacts known secret formats out of assistant text, the system prompt, tool arguments, tool results, and user prompts before export. Set AGENTO11Y_REDACT_INPUT_MESSAGES=false to send prompt text without redaction; assistant and tool content stay redacted either way.
3. Verify
Run one OpenCode turn, then open Agent Observability → Conversations in Grafana Cloud. A new generation should appear within a few seconds.
If nothing shows up, set AGENTO11Y_DEBUG=true in ~/.config/agento11y/config.env, run another turn, and check OpenCode stderr.
Tagging sessions
Launch with --tag key=value (repeatable) to attach tags to every generation the plugin exports:
agento11y opencode --tag project=hackathon --tag team=ai
# forward args to opencode after `--`
agento11y opencode --tag team=ai -- run "say hi"--tag is shorthand for AGENTO11Y_TAGS; flag tags merge onto (and override) any AGENTO11Y_TAGS already in the environment or ~/.config/agento11y/config.env. The merge happens in the SDK, so user tags reach every generation without the plugin reparsing them.
The plugin attaches built-in tags of its own:
git.branch— current branch from the opencode project directory, or a 12-char short SHA on detached HEAD. Omitted when not inside a git checkout.cwd— the opencode project directory.subagent—"true"on generations from a subagent session. Omitted for ordinary sessions, and for a subagent that opencode started before the plugin loaded.
Built-in tags win collisions with user tags, matching the claude-code and cursor launchers. See Tags and Metadata for the tags the launchers share.
Subagent sessions
OpenCode runs a subagent (the task tool) in a session of its own. The plugin exports those turns into the conversation that spawned them, so the subagent's work shows up in the parent's timeline rather than as an unrelated conversation:
conversation_idon every child turn is the spawning session's id. A subagent that spawns a subagent of its own flattens the same way: every turn in the tree lands in the root session's conversation, so a grandchild'sconversation_idis the root rather than its immediate parent.- The child's first turn carries
parent_generation_idsnaming the parent turn that made thetaskcall. Later child turns chain to the child's own previous turn. opencode.parent_session_idmetadata names the session that spawned this one, so a nested subagent still reports its immediate parent rather than the root.opencode.child_session_idnames the child's own session id, which nothing else carries:conversation_idholds an ancestor's, so looking up the child session id finds no conversation.- The child sends no conversation title. Agent Observability keeps the newest title per conversation, and the child's title names the subagent, so a child landing after the parent's last turn would rename the shared conversation.
If the plugin cannot name the spawning turn, the child keeps its own conversation id and exports no parent edge. That happens when the plugin loaded after OpenCode had already started the parent's turn. The subagent tag and opencode.parent_session_id are still attached, so the relationship is recorded as metadata instead of an edge.
Guards
Guards check a request against rules you configure in Grafana and can stop or rewrite it before the model sees it. Refer to Set up guards to write the rules. This section covers what they do in OpenCode.
They are off by default:
AGENTO11Y_GUARDS_ENABLED=true agento11y opencodeWith guards on, a rule can:
- Refuse a turn. A
preflightdeny stops the turn before it reaches the model, so nothing is sent and no tokens are spent. The reason appears in the session and in OpenCode's log. - Redact what the model sees. A
preflightredact rule replaces matching text in the conversation on its way to the provider. Your own message is not rewritten. - Block or rewrite a tool call. A
postflightdeny stops the call and tells the model why. A redact rule rewrites the arguments the tool receives. OpenCode's permission prompts count as tool calls, and its permission API has no field for a reason, so a denied prompt reports none.
All options
~/.config/agento11y/config.env is the only configuration file. Every option is set via env var.
| Variable | Default | Description |
|---|---|---|
| AGENTO11Y_ENDPOINT | — | Agent Observability API URL. Find it at /plugins/grafana-agento11y-app. Empty value disables the plugin. |
| AGENTO11Y_AUTH_TENANT_ID | — | Grafana Cloud instance ID. |
| AGENTO11Y_AUTH_TOKEN | — | glc_… Cloud Access Policy Token. |
| AGENTO11Y_OTEL_EXPORTER_OTLP_ENDPOINT | — | OTLP endpoint. Without it, the Agent Observability latency and tool-call panels stay empty. Falls back to OTEL_EXPORTER_OTLP_ENDPOINT. |
| AGENTO11Y_OTEL_AUTH_TOKEN | AGENTO11Y_AUTH_TOKEN | Override the OTLP password. |
| AGENTO11Y_CONTENT_CAPTURE_MODE | metadata_only | One of full, no_tool_content, metadata_only, or full_with_metadata_spans. default is accepted as an alias for metadata_only. |
| AGENTO11Y_REDACT_INPUT_MESSAGES | true | Redact known secret formats out of user prompt text. Set to false to export prompts without redaction. |
| AGENTO11Y_EXPORT_TIMEOUT_MS | 30000 | Timeout for each generation export request. Use a base-10 integer from 1 through 2147483647 milliseconds. |
| AGENTO11Y_GUARDS_ENABLED | false | Check your prompts, the conversation sent to the model, and OpenCode tool calls against Agent Observability guards. See Guards. |
| AGENTO11Y_GUARDS_TIMEOUT_MS | 1500 | Per-evaluation guard timeout in milliseconds. |
| AGENTO11Y_GUARDS_FAIL_OPEN | true | Send the turn and allow tool calls when a guard evaluation fails. Set to false to refuse them instead. This covers evaluation failures at all three checks. A tool call is blocked under either setting when a guard returns redacted arguments that the plugin cannot write into the arguments OpenCode runs the tool with. |
| AGENTO11Y_AGENT_NAME | opencode | Agent name reported to Agent Observability. The plugin appends :<mode> for OpenCode's UI mode, such as build or plan. |
| AGENTO11Y_AGENT_VERSION | OpenCode version | Version string reported with the agent. |
| AGENTO11Y_AUTO_CODING_AGENT_TAGS | false | Opt in to client tags resolved for the session: the user, the repository, and the branch. These reach OTel metrics as agento11y_tag_* labels, unlike the per-generation built-ins. The plugin builds one client per session, so the values freeze at session start. See Tags and Metadata for the cardinality and personal-data trade-offs. |
| AGENTO11Y_AUTO_CODING_AGENT_TAGS_NAMES | all names | Narrows the switch above to a comma-separated subset of user, repo, branch (all is also accepted). Does nothing while the switch is off. |
| AGENTO11Y_DEBUG | false | Log lifecycle events to stderr. |
| AGENTO11Y_AUTO_UPDATE | true | Refresh the @grafana/agento11y-opencode plugin automatically. Set false to pin the installed version. |
File format: one KEY=value per line, # line comments, optional export prefix, optional matching single or double quotes around the value. Only AGENTO11Y_* and SIGIL_* keys plus OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_EXPORTER_OTLP_HEADERS, OTEL_EXPORTER_OTLP_INSECURE, and OTEL_SERVICE_NAME are honored — anything else (including stray PATH=… lines) is ignored.
A non-empty OS env value always wins over the file; an empty or whitespace-only OS value is treated as unset and gets filled from config.env. Missing files are silent.
Development
pnpm install
pnpm --filter @grafana/agento11y-opencode build
pnpm --filter @grafana/agento11y-opencode testThe @grafana/agento11y dependency resolves via pnpm workspace linking to js/.
