@@ -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