Skip to content

Commit c4b30ba

Browse files
committed
fix: parent tool spans to the correct generation
1 parent a3b8507 commit c4b30ba

7 files changed

Lines changed: 572 additions & 37 deletions

File tree

.github/workflows/ci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,5 @@ jobs:
3232
run: pnpm run format:check
3333
- name: Build
3434
run: pnpm run build
35+
- name: Test
36+
run: pnpm run test

CONTRIBUTING.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ Build the plugin:
1616
pnpm run build
1717
```
1818

19+
Run the tests:
20+
21+
```bash
22+
pnpm test
23+
```
24+
1925
Format files:
2026

2127
```bash

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@
3939
"scripts": {
4040
"build": "tsc",
4141
"format": "prettier --write .",
42-
"format:check": "prettier --check ."
42+
"format:check": "prettier --check .",
43+
"test": "tsc && node --test test/*.test.js"
4344
},
4445
"dependencies": {
4546
"@langfuse/otel": "^5.4.1",
@@ -50,6 +51,7 @@
5051
"effect": "^3.21.2"
5152
},
5253
"devDependencies": {
54+
"@opentelemetry/context-async-hooks": "2.7.1",
5355
"prettier": "^3.8.3",
5456
"typescript": "^6.0.3"
5557
}

pnpm-lock.yaml

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/index.ts

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ type SessionNextEvent =
2323
properties: {
2424
sessionID: string;
2525
timestamp: number;
26+
assistantMessageID?: string;
2627
agent: string;
2728
model: NonNullable<ActiveGenerationStep["model"]>;
2829
snapshot?: string;
@@ -39,9 +40,23 @@ type SessionNextEvent =
3940
properties: {
4041
sessionID: string;
4142
timestamp: number;
43+
assistantMessageID?: string;
4244
error: { message: string };
4345
};
4446
}
47+
| {
48+
id: string;
49+
type: "session.next.tool.called";
50+
properties: {
51+
timestamp: number;
52+
sessionID: string;
53+
assistantMessageID?: string;
54+
callID: string;
55+
tool: string;
56+
input: Record<string, unknown>;
57+
provider: { executed: boolean; metadata?: unknown };
58+
};
59+
}
4560
| {
4661
id: string;
4762
type: "session.next.retried";
@@ -172,6 +187,7 @@ const eventHook = (event: OpencodeEvent, shutdown?: () => Promise<void>) =>
172187
if (event.type === "session.next.step.started") {
173188
langfuse.startActiveGenerationStep({
174189
sessionID: event.properties.sessionID,
190+
assistantMessageID: event.properties.assistantMessageID,
175191
agent: event.properties.agent,
176192
model: event.properties.model,
177193
started: event.properties.timestamp,
@@ -183,11 +199,23 @@ const eventHook = (event: OpencodeEvent, shutdown?: () => Promise<void>) =>
183199
langfuse.traceFailedGenerationStep({
184200
id: event.id,
185201
sessionID: event.properties.sessionID,
202+
assistantMessageID: event.properties.assistantMessageID,
186203
completed: event.properties.timestamp,
187204
error: event.properties.error,
188205
});
189206
}
190207

208+
if (event.type === "session.next.tool.called") {
209+
const messageID = event.properties.assistantMessageID;
210+
211+
if (messageID) {
212+
langfuse.rememberToolCall({
213+
callID: event.properties.callID,
214+
messageID,
215+
});
216+
}
217+
}
218+
191219
if (event.type === "session.next.retried") {
192220
langfuse.traceEvent({
193221
id: event.id,
@@ -228,7 +256,25 @@ const eventHook = (event: OpencodeEvent, shutdown?: () => Promise<void>) =>
228256
if (event.type === "message.updated") {
229257
const message = event.properties.info;
230258

231-
if (message.role !== "assistant" || !message.time.completed) {
259+
if (message.role !== "assistant") {
260+
return;
261+
}
262+
263+
// session.next.step.started is not exposed to plugins by every OpenCode
264+
// version. message.updated is emitted when the assistant message is
265+
// created, before any of that generation's tools execute.
266+
langfuse.startActiveGenerationStep({
267+
sessionID: message.sessionID,
268+
assistantMessageID: message.id,
269+
agent: message.mode,
270+
model: {
271+
id: message.modelID,
272+
providerID: message.providerID,
273+
},
274+
started: message.time.created,
275+
});
276+
277+
if (!message.time.completed) {
232278
return;
233279
}
234280

0 commit comments

Comments
 (0)