Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
203 commits
Select commit Hold shift + click to select a range
0afb363
Create plan.md
Hona Jan 2, 2026
5fc301a
feat(otel): add @opentelemetry/api dependency for Aspire Dashboard in…
Hona Jan 2, 2026
466f629
feat(otel): add @opentelemetry/api-logs dependency for structured log…
Hona Jan 2, 2026
1530771
docs: mark @opentelemetry/api-logs dependency as complete in plan.md
Hona Jan 2, 2026
d18935b
feat(otel): add @opentelemetry/sdk-node dependency for telemetry SDK
Hona Jan 2, 2026
44b6734
feat(otel): add @opentelemetry/sdk-logs dependency for logging SDK
Hona Jan 2, 2026
67b08e0
feat(otel): add @opentelemetry/resources dependency for resource attr…
Hona Jan 2, 2026
8b9fbb6
docs: mark @opentelemetry/resources dependency as complete in plan.md
Hona Jan 2, 2026
ea9c6e3
feat(otel): add @opentelemetry/semantic-conventions dependency for st…
Hona Jan 2, 2026
ad92664
feat(otel): add npm scripts for Aspire Dashboard integration
Hona Jan 2, 2026
210f7b1
feat(otel): add @opentelemetry/exporter-trace-otlp-grpc dependency fo…
Hona Jan 2, 2026
192f806
feat(otel): add @opentelemetry/exporter-logs-otlp-grpc dependency for…
Hona Jan 2, 2026
65812b7
docs: mark exporter-logs-otlp-grpc dependency and bun install as comp…
Hona Jan 2, 2026
1557b55
feat(otel): extend openTelemetry config to support endpoint option
Hona Jan 2, 2026
43a94a6
feat(otel): implement Telemetry module with OpenTelemetry SDK integra…
Hona Jan 2, 2026
e3d50d7
feat(otel): add OTEL logging bridge to emit logs to OpenTelemetry
Hona Jan 2, 2026
9df7253
feat(otel): add startup integration for telemetry initialization
Hona Jan 2, 2026
c591620
feat(otel): instrument Bash tool with OpenTelemetry spans
Hona Jan 2, 2026
a7ce76f
feat(otel): instrument Read tool with OpenTelemetry spans
Hona Jan 2, 2026
645ed5d
feat(otel): instrument Edit tool with OpenTelemetry spans
Hona Jan 2, 2026
83e5ebe
feat(otel): instrument Write tool with OpenTelemetry spans
Hona Jan 2, 2026
d4d2cee
feat(otel): instrument Glob tool with OpenTelemetry spans
Hona Jan 2, 2026
875ac44
docs: mark Glob tool instrumentation complete in plan.md
Hona Jan 2, 2026
5c1f2d4
feat(otel): instrument Grep tool with OpenTelemetry spans
Hona Jan 2, 2026
8de56f7
feat(otel): instrument WebFetch tool with OpenTelemetry spans
Hona Jan 2, 2026
a4dcae2
feat(otel): instrument WebSearch tool with OpenTelemetry spans
Hona Jan 2, 2026
d1bc5f0
docs: mark WebSearch tool instrumentation complete in plan.md
Hona Jan 2, 2026
b806142
feat(otel): instrument CodeSearch tool with OpenTelemetry spans
Hona Jan 2, 2026
4139766
feat(otel): instrument Task tool with OpenTelemetry spans
Hona Jan 2, 2026
6673d29
docs: mark Task tool instrumentation complete in plan.md
Hona Jan 2, 2026
40bcd6c
feat(otel): instrument LSP tool with OpenTelemetry spans
Hona Jan 2, 2026
9879948
feat(otel): instrument Skill tool with OpenTelemetry spans
Hona Jan 2, 2026
38cca9a
docs: mark Skill tool instrumentation complete in plan.md
Hona Jan 2, 2026
a111a47
feat(otel): instrument List tool with OpenTelemetry spans
Hona Jan 2, 2026
1577081
docs: mark List tool instrumentation complete in plan.md
Hona Jan 2, 2026
427dee1
feat(otel): instrument Batch tool with OpenTelemetry spans
Hona Jan 2, 2026
0dc18b9
feat(otel): instrument MultiEdit tool with OpenTelemetry spans
Hona Jan 2, 2026
3783cf5
feat(otel): instrument TodoWrite and TodoRead tools with OpenTelemetr…
Hona Jan 2, 2026
7fd5849
feat(otel): instrument MCP client connect with OpenTelemetry spans
Hona Jan 2, 2026
86f4677
feat(otel): instrument MCP tool call with OpenTelemetry spans
Hona Jan 2, 2026
91cc68f
docs: mark MCP tool call instrumentation complete in plan.md
Hona Jan 2, 2026
26a3a8f
feat(otel): instrument MCP listTools with OpenTelemetry spans
Hona Jan 2, 2026
39b82d0
docs: mark MCP listTools instrumentation complete in plan.md
Hona Jan 2, 2026
c0d24e6
feat(otel): instrument MCP listPrompts with OpenTelemetry spans
Hona Jan 2, 2026
d26bac7
docs: mark MCP listPrompts instrumentation complete in plan.md
Hona Jan 2, 2026
209f1a1
feat(otel): instrument MCP getPrompt with OpenTelemetry spans
Hona Jan 2, 2026
d27c84e
feat(otel): instrument LLM stream with OpenTelemetry spans
Hona Jan 2, 2026
dcc9bd6
docs: mark LLM stream instrumentation complete in plan.md
Hona Jan 2, 2026
0f00d05
feat(otel): instrument session processor with OpenTelemetry spans
Hona Jan 2, 2026
54e504a
docs: mark session processor instrumentation complete in plan.md
Hona Jan 2, 2026
782acdc
feat(otel): add telemetry instrumentation to session prompt
Hona Jan 2, 2026
c137468
feat(otel): instrument session.prompt.loop with OpenTelemetry tracing
Hona Jan 2, 2026
1e3cbd6
docs: mark session.prompt.loop instrumentation complete in plan.md
Hona Jan 2, 2026
3448c8a
feat(otel): instrument session compaction with OpenTelemetry tracing
Hona Jan 2, 2026
656cbac
docs: mark session compaction instrumentation complete in plan.md
Hona Jan 2, 2026
d9c56cd
feat(otel): instrument session summary with OpenTelemetry tracing
Hona Jan 2, 2026
79447f2
docs: mark session summary instrumentation complete in plan.md
Hona Jan 2, 2026
a9a1d05
feat(otel): instrument LSP client create with OpenTelemetry tracing
Hona Jan 2, 2026
7489809
feat(otel): instrument LSP initialize request with OpenTelemetry tracing
Hona Jan 2, 2026
cb1fe4a
feat(otel): instrument LSP touchFile with OpenTelemetry tracing
Hona Jan 2, 2026
a69f7f8
feat(otel): instrument LSP definition request with OpenTelemetry tracing
Hona Jan 2, 2026
ad88f51
docs: mark LSP definition instrumentation complete in plan.md
Hona Jan 2, 2026
74f82e3
feat(otel): instrument LSP references request with OpenTelemetry tracing
Hona Jan 2, 2026
b2b7cca
docs: mark LSP references instrumentation complete in plan.md
Hona Jan 2, 2026
612e440
feat(otel): instrument LSP hover request with OpenTelemetry tracing
Hona Jan 2, 2026
a3e4c75
feat(otel): instrument Agent.generate with OpenTelemetry tracing
Hona Jan 2, 2026
fb00b8f
feat(otel): instrument Plugin trigger with OpenTelemetry tracing
Hona Jan 2, 2026
ae6bfa3
docs: mark Plugin trigger instrumentation complete in plan.md
Hona Jan 2, 2026
79bf266
feat(otel): instrument Snapshot.track with OpenTelemetry tracing
Hona Jan 2, 2026
cd31a82
docs: mark Snapshot.track instrumentation complete in plan.md
Hona Jan 2, 2026
86e6d81
feat(otel): instrument Snapshot.restore with OpenTelemetry tracing
Hona Jan 2, 2026
e6a046b
better name + wire up ai sdk otel
Hona Jan 2, 2026
b270e50
wip (i dont think either of these changes did anything)
Hona Jan 2, 2026
f2e9343
log format is weird and exceptions
Hona Jan 2, 2026
bb09006
we're done the plan
Hona Jan 2, 2026
41b6169
refactor plan
Hona Jan 3, 2026
f844532
add flattenAttributes() utility for auto-capturing span attributes
Hona Jan 3, 2026
145b717
add span() function with `using` support and export NOOP_SPAN
Hona Jan 3, 2026
e681ac3
mark tasks 1.1.2 and 1.1.3 complete in plan.md
Hona Jan 3, 2026
0c5b9d1
add traced() higher-order function for function-level telemetry wrapping
Hona Jan 3, 2026
1a2b9d6
add auto-instrumentation to Tool.define() for telemetry span wrapping
Hona Jan 3, 2026
a28d44b
mark task 1.4.1 complete: typecheck passes
Hona Jan 3, 2026
ba6b236
mark task 1.4.2 complete: telemetry exports verified
Hona Jan 3, 2026
bc80363
mark task 1.4.3 complete: Tool.define auto-instrumentation verified
Hona Jan 3, 2026
b1dbaa6
remove manual telemetry wrapper from glob.ts - auto-instrumentation h…
Hona Jan 3, 2026
4505f14
mark task 2.1.1 complete: glob.ts telemetry wrapper removed
Hona Jan 3, 2026
83d2a7c
remove manual telemetry wrapper from grep.ts - auto-instrumentation h…
Hona Jan 3, 2026
989d304
mark task 2.1.2 complete: grep.ts telemetry wrapper removed
Hona Jan 3, 2026
96b774a
remove manual telemetry wrapper from read.ts - auto-instrumentation h…
Hona Jan 3, 2026
2c2f208
remove manual telemetry wrapper from write.ts - auto-instrumentation …
Hona Jan 3, 2026
422780d
remove manual telemetry wrapper from edit.ts - auto-instrumentation h…
Hona Jan 3, 2026
3b59d70
mark task 2.1.5 complete: edit.ts telemetry wrapper removed
Hona Jan 3, 2026
8668ccd
remove manual telemetry wrapper from multiedit.ts - auto-instrumentat…
Hona Jan 3, 2026
94ded13
mark task 2.1.6 complete: multiedit.ts telemetry wrapper removed
Hona Jan 3, 2026
3511b33
remove manual telemetry wrapper from bash.ts - auto-instrumentation h…
Hona Jan 3, 2026
725c688
mark task 2.1.7 complete: bash.ts telemetry wrapper removed
Hona Jan 3, 2026
30008ea
remove manual telemetry wrapper from batch.ts - auto-instrumentation …
Hona Jan 3, 2026
b831685
mark task 2.1.8 complete: batch.ts telemetry wrapper removed
Hona Jan 3, 2026
a9a2853
remove manual telemetry wrapper from ls.ts - auto-instrumentation han…
Hona Jan 3, 2026
6347359
mark task 2.1.9 complete: ls.ts telemetry wrapper removed
Hona Jan 3, 2026
278bb94
remove manual telemetry wrapper from lsp.ts - auto-instrumentation ha…
Hona Jan 3, 2026
390888d
mark task 2.1.10 complete: lsp.ts telemetry wrapper removed
Hona Jan 3, 2026
3fc5d8b
remove manual telemetry wrapper from task.ts - auto-instrumentation h…
Hona Jan 3, 2026
18657c3
mark task 2.1.11 complete: task.ts telemetry wrapper removed
Hona Jan 3, 2026
d57f80d
remove manual telemetry wrapper from skill.ts - auto-instrumentation …
Hona Jan 3, 2026
87e008b
mark task 2.1.12 complete: skill.ts telemetry wrapper removed
Hona Jan 3, 2026
53fc936
remove manual telemetry wrappers from todo.ts - auto-instrumentation …
Hona Jan 3, 2026
7a2a084
remove manual telemetry wrapper from webfetch.ts - auto-instrumentati…
Hona Jan 3, 2026
8a9e350
remove manual telemetry wrapper from websearch.ts - auto-instrumentat…
Hona Jan 3, 2026
25a11f4
remove manual telemetry wrapper from codesearch.ts - auto-instrumenta…
Hona Jan 3, 2026
cd1fcf0
mark 2.1-checkpoint complete: all tool telemetry wrappers removed
Hona Jan 3, 2026
f3fa7b5
enhance codesearch.ts metadata with query, tokensNum, hasResults, sta…
Hona Jan 3, 2026
2fcdb41
enhance edit.ts metadata with errorCount and fileExisted
Hona Jan 3, 2026
bc0f0ad
enhance grep.ts metadata with uniqueFiles count
Hona Jan 3, 2026
5198149
enhance ls.ts metadata with directories count
Hona Jan 3, 2026
9b7019a
enhance lsp.ts metadata with operation and resultCount
Hona Jan 3, 2026
27200c8
mark task 2.2.6 complete in plan.md
Hona Jan 3, 2026
3efb5a7
enhance multiedit.ts metadata with success/failure counts and totals
Hona Jan 3, 2026
4efded3
mark task 2.2.7 complete in plan.md
Hona Jan 3, 2026
358583f
enhance read.ts metadata with isImage, isBinary, linesRead, totalLine…
Hona Jan 3, 2026
ca4c06e
mark task 2.2.8 complete in plan.md
Hona Jan 3, 2026
3148189
enhance skill.ts metadata with skillFound field
Hona Jan 3, 2026
82114d8
mark task 2.2.9 complete in plan.md
Hona Jan 3, 2026
b3d72a4
enhance task.ts metadata with toolCallsCount and isNewSession
Hona Jan 3, 2026
f5b26c6
mark task 2.2.10 complete in plan.md
Hona Jan 3, 2026
13c0fe2
enhance todo.ts (TodoWriteTool) metadata with completedCount and pend…
Hona Jan 3, 2026
628eedf
mark task 2.2.11 complete in plan.md
Hona Jan 3, 2026
85fbbd5
enhance todo.ts (TodoReadTool) metadata with todoCount and completedC…
Hona Jan 3, 2026
8f54c7e
mark task 2.2.12 complete in plan.md
Hona Jan 3, 2026
6da6b15
enhance webfetch.ts metadata with statusCode, contentType, and respon…
Hona Jan 3, 2026
68ff30e
mark task 2.2.13 complete in plan.md
Hona Jan 3, 2026
4183e05
enhance websearch.ts metadata with statusCode, resultCount, hasResult…
Hona Jan 3, 2026
b4d0b87
mark task 2.2.14 complete in plan.md
Hona Jan 3, 2026
c33f4c2
enhance write.ts metadata with errorCount and fileCreated
Hona Jan 3, 2026
2b2700a
mark task 2.2.15 complete in plan.md
Hona Jan 3, 2026
f994f63
mark Phase 2.3 validation tasks complete in plan.md
Hona Jan 3, 2026
476414a
refactor: use `using` syntax for session.prompt.loop span
Hona Jan 3, 2026
b8f504e
mark task 3.1.1 complete in plan.md
Hona Jan 3, 2026
81c07b0
feat(telemetry): add per-step child spans in session prompt loop
Hona Jan 3, 2026
d04cff3
mark Phase 3 complete: session loop refactor validated
Hona Jan 3, 2026
179795a
refactor(llm): migrate LLM.stream to traced() wrapper pattern
Hona Jan 3, 2026
dbf10ad
refactor(prompt): migrate SessionPrompt.prompt to traced() wrapper pa…
Hona Jan 3, 2026
2e02853
mark task 4.1.2 complete in plan.md
Hona Jan 3, 2026
5f2db2b
refactor(compaction): migrate SessionCompaction.process to traced() w…
Hona Jan 3, 2026
ceb46ec
refactor(summary): migrate SessionSummary.summarize to traced() wrapp…
Hona Jan 3, 2026
7ccb6b6
refactor(processor): migrate SessionProcessor.process to using span p…
Hona Jan 3, 2026
8f535d2
mark task 4.1.5 complete in plan.md
Hona Jan 3, 2026
f3b05d0
refactor(snapshot): migrate Snapshot.track to using span pattern
Hona Jan 3, 2026
afb1999
refactor(snapshot): migrate Snapshot.restore to traced() wrapper pattern
Hona Jan 3, 2026
d293723
mark task 4.2.2 complete in plan.md
Hona Jan 3, 2026
489c91c
refactor(plugin): migrate Plugin.trigger to using span pattern
Hona Jan 3, 2026
a34477f
refactor(agent): migrate Agent.generate to using span pattern
Hona Jan 3, 2026
098aaf4
mark task 4.2.4 complete in plan.md
Hona Jan 3, 2026
bf3fd16
mark Phase 4 validation tasks 4.3.1-4.3.4 complete
Hona Jan 3, 2026
5d2663b
refactor(lsp): migrate touchFile to using span pattern
Hona Jan 3, 2026
c91a060
docs: mark LSP.touchFile migration complete in plan
Hona Jan 3, 2026
1c7d098
refactor(lsp): migrate hover to traced() wrapper pattern
Hona Jan 3, 2026
fb2c7b7
docs: mark LSP.hover migration complete in plan
Hona Jan 3, 2026
7d88cc3
refactor(lsp): migrate definition to traced() wrapper pattern
Hona Jan 3, 2026
595cf7a
docs: mark LSP.definition migration complete in plan
Hona Jan 3, 2026
36aab98
refactor(lsp): migrate references to traced() wrapper pattern
Hona Jan 3, 2026
07226cd
docs: mark LSP.references migration complete in plan
Hona Jan 3, 2026
470db3f
refactor(lsp): migrate LSPClient.create to using span pattern
Hona Jan 3, 2026
8f5e09b
docs: mark LSPClient.create migration complete in plan
Hona Jan 3, 2026
009634c
refactor(mcp): migrate fetchPromptsForClient to using span pattern
Hona Jan 3, 2026
c031f00
docs: mark fetchPromptsForClient migration complete in plan
Hona Jan 3, 2026
ae3ced3
refactor(mcp): migrate MCP.tools inner span to using span pattern
Hona Jan 3, 2026
2228907
refactor(mcp): migrate MCP.getPrompt to using span pattern
Hona Jan 3, 2026
a88a59e
docs: mark MCP.getPrompt migration complete in plan
Hona Jan 3, 2026
bb04558
refactor(mcp): migrate client connection spans to using span pattern
Hona Jan 3, 2026
d8a2c49
docs: mark MCP client connection span migration complete in plan
Hona Jan 3, 2026
c4d94fb
docs: mark convertMcpTool review complete - keep withSpan inline
Hona Jan 3, 2026
69876a8
docs: mark LSP module diff validation complete in plan
Hona Jan 3, 2026
1ef8738
docs: complete Phase 5.3 validation and Phase 6.1-6.2 verification
Hona Jan 3, 2026
90e4fd8
docs: mark test suite task 6.3.1 complete (518 pass, 0 fail)
Hona Jan 3, 2026
a953c41
docs: mark 6.5.1-6.5.2 complete with diff stats results
Hona Jan 3, 2026
6cbe2eb
docs: mark 6.5.3 complete - verified no telemetry in tool execute fun…
Hona Jan 3, 2026
ee85577
docs: mark 6.5.4 complete - per-file diff summary shows framework fil…
Hona Jan 3, 2026
8302f55
docs: mark 6.5.5 complete - verified clean diffs with no mass indenta…
Hona Jan 3, 2026
4fa84ef
docs: mark 6.3.2 complete - bun dev manual test passes
Hona Jan 3, 2026
c53a52a
docs: mark 6.5.6 complete - final SLOC count comparison documented
Hona Jan 3, 2026
a45eabf
docs: mark OTel verification tasks complete after manual Aspire testing
Hona Jan 3, 2026
1d693f7
Merge remote-tracking branch 'upstream/dev' into feat/aspire-otel
Hona Jan 3, 2026
dedd716
refacotr/clean done
Hona Jan 3, 2026
8a519ff
feat(telemetry): add OTEL_EXPORTER_OTLP_ENDPOINT flag definition
Hona Jan 3, 2026
b7d08cb
docs: mark Phase 1 flag definition as completed
Hona Jan 3, 2026
f777fa8
feat(config): apply OTEL_EXPORTER_OTLP_ENDPOINT env var override at c…
Hona Jan 3, 2026
2d66a6e
docs: mark Phase 2 config loading tasks as completed
Hona Jan 3, 2026
3885f62
refactor(telemetry): simplify CLI entry points by removing direct env…
Hona Jan 3, 2026
fb02394
refactor(telemetry): simplify llm.ts telemetry check using Telemetry.…
Hona Jan 3, 2026
dbc67df
refactor(telemetry): simplify agent.ts telemetry check using Telemetr…
Hona Jan 3, 2026
57dea6d
docs: mark agent.ts telemetry simplification as completed
Hona Jan 3, 2026
aebc273
refactor(telemetry): remove duplicate env var check from resolveConfig
Hona Jan 3, 2026
ff4d4c2
docs(telemetry): add inline comments explaining config precedence
Hona Jan 3, 2026
27b3ef5
test(telemetry): add unit tests for telemetry configuration
Hona Jan 3, 2026
9646c4f
docs(config): add OpenTelemetry experimental option documentation
Hona Jan 3, 2026
91fddf2
docs(plan): mark OpenTelemetry refactor as complete
Hona Jan 3, 2026
3b1922f
Delete plan.md
Hona Jan 3, 2026
27349e3
simplify config lol
Hona Jan 3, 2026
16f9bb9
kill dead tests
Hona Jan 3, 2026
a842b67
clean clean clean
Hona Jan 3, 2026
eb76917
generate
Hona Jan 3, 2026
e06f3ab
Merge remote-tracking branch 'upstream/dev' into feat/aspire-otel
Hona Jan 6, 2026
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
123 changes: 123 additions & 0 deletions bun.lock

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions packages/opencode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@
"test": "bun test",
"build": "bun run script/build.ts",
"dev": "bun run --conditions=browser ./src/index.ts",
"aspire:start": "docker run --rm -d -p 18888:18888 -p 4317:18889 -e ASPIRE_DASHBOARD_UNSECURED_ALLOW_ANONYMOUS=true --name aspire-dashboard mcr.microsoft.com/dotnet/aspire-dashboard:latest && echo 'Aspire Dashboard: http://localhost:18888'",
"aspire:stop": "docker stop aspire-dashboard 2>/dev/null || true",
"dev:otel": "bun run aspire:start; OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317 OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true bun dev",
"random": "echo 'Random script updated at $(date)' && echo 'Change queued successfully' && echo 'Another change made' && echo 'Yet another change' && echo 'One more change' && echo 'Final change' && echo 'Another final change' && echo 'Yet another final change'",
"clean": "echo 'Cleaning up...' && rm -rf node_modules dist",
"lint": "echo 'Running lint checks...' && bun test --coverage",
Expand Down Expand Up @@ -81,6 +84,14 @@
"@opencode-ai/sdk": "workspace:*",
"@opencode-ai/util": "workspace:*",
"@openrouter/ai-sdk-provider": "1.5.2",
"@opentelemetry/api": "1.9.0",
"@opentelemetry/api-logs": "0.208.0",
"@opentelemetry/sdk-logs": "0.208.0",
"@opentelemetry/resources": "2.2.0",
"@opentelemetry/sdk-node": "0.208.0",
"@opentelemetry/semantic-conventions": "1.37.0",
"@opentelemetry/exporter-trace-otlp-grpc": "0.208.0",
"@opentelemetry/exporter-logs-otlp-grpc": "0.208.0",
"@opentui/core": "0.1.69",
"@opentui/solid": "0.1.69",
"@parcel/watcher": "2.5.1",
Expand Down
13 changes: 10 additions & 3 deletions packages/opencode/src/agent/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import PROMPT_SUMMARY from "./prompt/summary.txt"
import PROMPT_TITLE from "./prompt/title.txt"
import { PermissionNext } from "@/permission/next"
import { mergeDeep, pipe, sortBy, values } from "remeda"
import { Telemetry } from "@/telemetry"

export namespace Agent {
export const Info = z
Expand Down Expand Up @@ -214,18 +215,24 @@ export namespace Agent {
}

export async function generate(input: { description: string; model?: { providerID: string; modelID: string } }) {
const cfg = await Config.get()
const defaultModel = input.model ?? (await Provider.defaultModel())
using _ = Telemetry.span("agent.generate", {
"llm.provider_id": defaultModel.providerID,
"llm.model_id": defaultModel.modelID,
})
const cfg = await Config.get()
const model = await Provider.getModel(defaultModel.providerID, defaultModel.modelID)
const language = await Provider.getLanguage(model)
const system = SystemPrompt.header(defaultModel.providerID)
system.push(PROMPT_GENERATE)
const existing = await list()
const result = await generateObject({
experimental_telemetry: {
isEnabled: cfg.experimental?.openTelemetry,
isEnabled: Telemetry.isEnabled(),
functionId: "opencode.agent.generate",
metadata: {
userId: cfg.username ?? "unknown",
"llm.provider_id": defaultModel.providerID,
"llm.model_id": defaultModel.modelID,
},
},
temperature: 0.3,
Expand Down
9 changes: 9 additions & 0 deletions packages/opencode/src/cli/cmd/tui/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ await Log.init({
})(),
})

const globalConfig = await Config.global()
if (globalConfig?.experimental?.openTelemetry) {
const { Telemetry } = await import("@/telemetry")
Telemetry.init(Telemetry.resolveConfig("opencode-server", true))
}

process.on("unhandledRejection", (e) => {
Log.Default.error("rejection", {
e: e instanceof Error ? e.message : e,
Expand Down Expand Up @@ -58,7 +64,10 @@ export const rpc = {
},
async shutdown() {
Log.Default.info("worker shutting down")
Log.Default.info("disposing all instances")
await Instance.disposeAll()
const { Telemetry } = await import("@/telemetry")
await Telemetry.shutdown()
// TODO: this should be awaited, but ws connections are
// causing this to hang, need to revisit this
server.stop(true)
Expand Down
2 changes: 1 addition & 1 deletion packages/opencode/src/config/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -954,7 +954,7 @@ export namespace Config {
openTelemetry: z
.boolean()
.optional()
.describe("Enable OpenTelemetry spans for AI SDK calls (using the 'experimental_telemetry' flag)"),
.describe("Enable OpenTelemetry tracing. Set OTEL_EXPORTER_OTLP_ENDPOINT env var for endpoint."),
primary_tools: z
.array(z.string())
.optional()
Expand Down
1 change: 1 addition & 0 deletions packages/opencode/src/flag/flag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export namespace Flag {
export const OPENCODE_DISABLE_MODELS_FETCH = truthy("OPENCODE_DISABLE_MODELS_FETCH")
export const OPENCODE_FAKE_VCS = process.env["OPENCODE_FAKE_VCS"]
export const OPENCODE_CLIENT = process.env["OPENCODE_CLIENT"] ?? "cli"
export const OTEL_EXPORTER_OTLP_ENDPOINT = process.env["OTEL_EXPORTER_OTLP_ENDPOINT"]

// Experimental
export const OPENCODE_EXPERIMENTAL = truthy("OPENCODE_EXPERIMENTAL")
Expand Down
17 changes: 17 additions & 0 deletions packages/opencode/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import { EOL } from "os"
import { WebCommand } from "./cli/cmd/web"
import { PrCommand } from "./cli/cmd/pr"
import { SessionCommand } from "./cli/cmd/session"
import { Config } from "./config/config"
import { Telemetry } from "./telemetry"

process.on("unhandledRejection", (e) => {
Log.Default.error("rejection", {
Expand All @@ -40,6 +42,14 @@ process.on("uncaughtException", (e) => {
})
})

process.on("SIGTERM", async () => {
await Telemetry.shutdown()
})

process.on("SIGINT", async () => {
await Telemetry.shutdown()
})

const cli = yargs(hideBin(process.argv))
.parserConfiguration({ "populate--": true })
.scriptName("opencode")
Expand Down Expand Up @@ -75,6 +85,11 @@ const cli = yargs(hideBin(process.argv))
version: Installation.VERSION,
args: process.argv.slice(2),
})

const globalConfig = await Config.global()
if (globalConfig?.experimental?.openTelemetry) {
Telemetry.init(Telemetry.resolveConfig("opencode-cli", true))
}
})
.usage("\n" + UI.logo())
.completion("completion", "generate shell completion script")
Expand Down Expand Up @@ -151,6 +166,8 @@ try {
}
process.exitCode = 1
} finally {
// Shutdown telemetry before exit
await Telemetry.shutdown()
// Some subprocesses don't react properly to SIGTERM and similar signals.
// Most notably, some docker-container-based MCP servers don't handle such signals unless
// run using `docker run --init`.
Expand Down
95 changes: 54 additions & 41 deletions packages/opencode/src/lsp/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { NamedError } from "@opencode-ai/util/error"
import { withTimeout } from "../util/timeout"
import { Instance } from "../project/instance"
import { Filesystem } from "../util/filesystem"
import { Telemetry } from "@/telemetry"

const DIAGNOSTICS_DEBOUNCE_MS = 150

Expand Down Expand Up @@ -40,6 +41,10 @@ export namespace LSPClient {
}

export async function create(input: { serverID: string; server: LSPServer.Handle; root: string }) {
using _span = Telemetry.span("lsp.client.create", {
"lsp.server_id": input.serverID,
"lsp.root": input.root,
})
const l = log.clone().tag("serverID", input.serverID)
l.info("starting client")

Expand Down Expand Up @@ -79,50 +84,58 @@ export namespace LSPClient {
connection.listen()

l.info("sending initialize")
await withTimeout(
connection.sendRequest("initialize", {
rootUri: pathToFileURL(input.root).href,
processId: input.server.process.pid,
workspaceFolders: [
{
name: "workspace",
uri: pathToFileURL(input.root).href,
},
],
initializationOptions: {
...input.server.initialization,
},
capabilities: {
window: {
workDoneProgress: true,
},
workspace: {
configuration: true,
didChangeWatchedFiles: {
dynamicRegistration: true,
await Telemetry.withSpan(
"lsp.request.initialize",
{
"lsp.server_id": input.serverID,
},
async () => {
await withTimeout(
connection.sendRequest("initialize", {
rootUri: pathToFileURL(input.root).href,
processId: input.server.process.pid,
workspaceFolders: [
{
name: "workspace",
uri: pathToFileURL(input.root).href,
},
],
initializationOptions: {
...input.server.initialization,
},
},
textDocument: {
synchronization: {
didOpen: true,
didChange: true,
capabilities: {
window: {
workDoneProgress: true,
},
workspace: {
configuration: true,
didChangeWatchedFiles: {
dynamicRegistration: true,
},
},
textDocument: {
synchronization: {
didOpen: true,
didChange: true,
},
publishDiagnostics: {
versionSupport: true,
},
},
},
publishDiagnostics: {
versionSupport: true,
}),
45_000,
).catch((err) => {
l.error("initialize error", { error: err })
throw new InitializeError(
{ serverID: input.serverID },
{
cause: err,
},
},
},
}),
45_000,
).catch((err) => {
l.error("initialize error", { error: err })
throw new InitializeError(
{ serverID: input.serverID },
{
cause: err,
},
)
})
)
})
},
)

await connection.sendNotification("initialized", {})

Expand Down
37 changes: 30 additions & 7 deletions packages/opencode/src/lsp/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { Config } from "../config/config"
import { spawn } from "child_process"
import { Instance } from "../project/instance"
import { Flag } from "@/flag/flag"
import { Telemetry, traced } from "@/telemetry"

export namespace LSP {
const log = Log.create({ service: "lsp" })
Expand Down Expand Up @@ -275,6 +276,7 @@ export namespace LSP {
}

export async function touchFile(input: string, waitForDiagnostics?: boolean) {
using _span = Telemetry.span("lsp.touch_file", { "lsp.file": input })
log.info("touching file", { file: input })
const clients = await getClients(input)
await Promise.all(
Expand All @@ -300,7 +302,14 @@ export namespace LSP {
return results
}

export async function hover(input: { file: string; line: number; character: number }) {
export const hover = traced<{ file: string; line: number; character: number }, (unknown | null)[]>(
"lsp.request.hover",
(input) => ({
"lsp.file": input.file,
"lsp.line": input.line,
"lsp.character": input.character,
}),
)(async (input) => {
return run(input.file, (client) => {
return client.connection
.sendRequest("textDocument/hover", {
Expand All @@ -314,7 +323,7 @@ export namespace LSP {
})
.catch(() => null)
})
}
})

enum SymbolKind {
File = 1,
Expand Down Expand Up @@ -383,7 +392,14 @@ export namespace LSP {
.then((result) => result.filter(Boolean))
}

export async function definition(input: { file: string; line: number; character: number }) {
export const definition = traced<{ file: string; line: number; character: number }, unknown[]>(
"lsp.request.definition",
(input) => ({
"lsp.file": input.file,
"lsp.line": input.line,
"lsp.character": input.character,
}),
)(async (input) => {
return run(input.file, (client) =>
client.connection
.sendRequest("textDocument/definition", {
Expand All @@ -392,9 +408,16 @@ export namespace LSP {
})
.catch(() => null),
).then((result) => result.flat().filter(Boolean))
}

export async function references(input: { file: string; line: number; character: number }) {
})

export const references = traced<{ file: string; line: number; character: number }, unknown[]>(
"lsp.request.references",
(input) => ({
"lsp.file": input.file,
"lsp.line": input.line,
"lsp.character": input.character,
}),
)(async (input) => {
return run(input.file, (client) =>
client.connection
.sendRequest("textDocument/references", {
Expand All @@ -404,7 +427,7 @@ export namespace LSP {
})
.catch(() => []),
).then((result) => result.flat().filter(Boolean))
}
})

export async function implementation(input: { file: string; line: number; character: number }) {
return run(input.file, (client) =>
Expand Down
Loading