Skip to content

Commit 7749d8e

Browse files
authored
Add v2 session failure events (anomalyco#25628)
1 parent 28112fb commit 7749d8e

7 files changed

Lines changed: 104 additions & 22 deletions

File tree

packages/opencode/src/cli/cmd/tui/context/sync-v2.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,15 @@ export const { use: useSyncV2, provider: SyncProviderV2 } = createSimpleContext(
143143
currentAssistant.snapshot = { ...currentAssistant.snapshot, end: event.properties.snapshot }
144144
})
145145
break
146+
case "session.next.step.failed":
147+
update(event.properties.sessionID, (draft) => {
148+
const currentAssistant = activeAssistant(draft)
149+
if (!currentAssistant) return
150+
currentAssistant.time.completed = event.properties.timestamp
151+
currentAssistant.finish = "error"
152+
currentAssistant.error = event.properties.error
153+
})
154+
break
146155
case "session.next.text.started":
147156
update(event.properties.sessionID, (draft) => {
148157
activeAssistant(draft)?.content.push({ type: "text", text: "" })
@@ -210,7 +219,7 @@ export const { use: useSyncV2, provider: SyncProviderV2 } = createSimpleContext(
210219
match.time.completed = event.properties.timestamp
211220
})
212221
break
213-
case "session.next.tool.error":
222+
case "session.next.tool.failed":
214223
update(event.properties.sessionID, (draft) => {
215224
const match = latestTool(activeAssistant(draft), event.properties.callID)
216225
if (match?.state.status !== "running") return

packages/opencode/src/session/processor.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ export const layer: Layer.Layer<
405405
case "tool-error": {
406406
const toolCall = yield* readToolCall(value.toolCallId)
407407
// TODO(v2): Temporary dual-write while migrating session messages to v2 events.
408-
EventV2.run(SessionEvent.Tool.Error.Sync, {
408+
EventV2.run(SessionEvent.Tool.Failed.Sync, {
409409
sessionID: ctx.sessionID,
410410
callID: value.toolCallId,
411411
error: {
@@ -650,6 +650,17 @@ export const layer: Layer.Layer<
650650
yield* bus.publish(Session.Event.Error, { sessionID: ctx.sessionID, error })
651651
return
652652
}
653+
if (!ctx.assistantMessage.summary) {
654+
// TODO(v2): Temporary dual-write while migrating session messages to v2 events.
655+
EventV2.run(SessionEvent.Step.Failed.Sync, {
656+
sessionID: ctx.sessionID,
657+
error: {
658+
type: error.name,
659+
message: errorMessage(e),
660+
},
661+
timestamp: DateTime.makeUnsafe(Date.now()),
662+
})
663+
}
653664
ctx.assistantMessage.error = error
654665
yield* bus.publish(Session.Event.Error, {
655666
sessionID: ctx.assistantMessage.sessionID,

packages/opencode/src/session/projectors-next.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,9 @@ export default [
161161
SyncEvent.project(SessionEvent.Step.Ended.Sync, (db, data, event) => {
162162
update(db, { id: SessionMessage.ID.make(event.id), type: "session.next.step.ended", data })
163163
}),
164+
SyncEvent.project(SessionEvent.Step.Failed.Sync, (db, data, event) => {
165+
update(db, { id: SessionMessage.ID.make(event.id), type: "session.next.step.failed", data })
166+
}),
164167
SyncEvent.project(SessionEvent.Text.Started.Sync, (db, data, event) => {
165168
update(db, { id: SessionMessage.ID.make(event.id), type: "session.next.text.started", data })
166169
}),
@@ -181,8 +184,8 @@ export default [
181184
SyncEvent.project(SessionEvent.Tool.Success.Sync, (db, data, event) => {
182185
update(db, { id: SessionMessage.ID.make(event.id), type: "session.next.tool.success", data })
183186
}),
184-
SyncEvent.project(SessionEvent.Tool.Error.Sync, (db, data, event) => {
185-
update(db, { id: SessionMessage.ID.make(event.id), type: "session.next.tool.error", data })
187+
SyncEvent.project(SessionEvent.Tool.Failed.Sync, (db, data, event) => {
188+
update(db, { id: SessionMessage.ID.make(event.id), type: "session.next.tool.failed", data })
186189
}),
187190
SyncEvent.project(SessionEvent.Reasoning.Started.Sync, (db, data, event) => {
188191
update(db, { id: SessionMessage.ID.make(event.id), type: "session.next.reasoning.started", data })

packages/opencode/src/v2/session-event.ts

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ const Base = {
2222
sessionID: SessionID,
2323
}
2424

25+
const Error = Schema.Struct({
26+
type: Schema.String,
27+
message: Schema.String,
28+
})
29+
2530
export const AgentSwitched = EventV2.define({
2631
type: "session.next.agent.switched",
2732
aggregate: "sessionID",
@@ -128,6 +133,16 @@ export namespace Step {
128133
},
129134
})
130135
export type Ended = Schema.Schema.Type<typeof Ended>
136+
137+
export const Failed = EventV2.define({
138+
type: "session.next.step.failed",
139+
aggregate: "sessionID",
140+
schema: {
141+
...Base,
142+
error: Error,
143+
},
144+
})
145+
export type Failed = Schema.Schema.Type<typeof Failed>
131146
}
132147

133148
export namespace Text {
@@ -275,23 +290,20 @@ export namespace Tool {
275290
})
276291
export type Success = Schema.Schema.Type<typeof Success>
277292

278-
export const Error = EventV2.define({
279-
type: "session.next.tool.error",
293+
export const Failed = EventV2.define({
294+
type: "session.next.tool.failed",
280295
aggregate: "sessionID",
281296
schema: {
282297
...Base,
283298
callID: Schema.String,
284-
error: Schema.Struct({
285-
type: Schema.String,
286-
message: Schema.String,
287-
}),
299+
error: Error,
288300
provider: Schema.Struct({
289301
executed: Schema.Boolean,
290302
metadata: Schema.Record(Schema.String, Schema.Unknown).pipe(Schema.optional),
291303
}),
292304
},
293305
})
294-
export type Error = Schema.Schema.Type<typeof Error>
306+
export type Failed = Schema.Schema.Type<typeof Failed>
295307
}
296308

297309
export const RetryError = Schema.Struct({
@@ -359,6 +371,7 @@ export const All = Schema.Union(
359371
Shell.Ended,
360372
Step.Started,
361373
Step.Ended,
374+
Step.Failed,
362375
Text.Started,
363376
Text.Delta,
364377
Text.Ended,
@@ -368,7 +381,7 @@ export const All = Schema.Union(
368381
Tool.Called,
369382
Tool.Progress,
370383
Tool.Success,
371-
Tool.Error,
384+
Tool.Failed,
372385
Reasoning.Started,
373386
Reasoning.Delta,
374387
Reasoning.Ended,

packages/opencode/src/v2/session-message-updater.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,17 @@ export function update<Result>(adapter: Adapter<Result>, event: SessionEvent.Eve
199199
)
200200
}
201201
},
202+
"session.next.step.failed": (event) => {
203+
if (currentAssistant) {
204+
adapter.updateAssistant(
205+
produce(currentAssistant, (draft) => {
206+
draft.time.completed = event.data.timestamp
207+
draft.finish = "error"
208+
draft.error = event.data.error
209+
}),
210+
)
211+
}
212+
},
202213
"session.next.text.started": () => {
203214
if (currentAssistant) {
204215
adapter.updateAssistant(
@@ -314,7 +325,7 @@ export function update<Result>(adapter: Adapter<Result>, event: SessionEvent.Eve
314325
)
315326
}
316327
},
317-
"session.next.tool.error": (event) => {
328+
"session.next.tool.failed": (event) => {
318329
if (currentAssistant) {
319330
adapter.updateAssistant(
320331
produce(currentAssistant, (draft) => {

packages/opencode/src/v2/session-message.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ export class Assistant extends Schema.Class<Assistant>("Session.Message.Assistan
152152
write: Schema.Finite,
153153
}),
154154
}).pipe(Schema.optional),
155-
error: Schema.String.pipe(Schema.optional),
155+
error: SessionEvent.Step.Failed.fields.data.fields.error.pipe(Schema.optional),
156156
time: Schema.Struct({
157157
created: V2Schema.DateTimeUtcFromMillis,
158158
completed: V2Schema.DateTimeUtcFromMillis.pipe(Schema.optional),

packages/sdk/js/src/v2/gen/types.gen.ts

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ export type Event =
5858
| EventSessionNextShellEnded
5959
| EventSessionNextStepStarted
6060
| EventSessionNextStepEnded
61+
| EventSessionNextStepFailed
6162
| EventSessionNextTextStarted
6263
| EventSessionNextTextDelta
6364
| EventSessionNextTextEnded
@@ -70,7 +71,7 @@ export type Event =
7071
| EventSessionNextToolCalled
7172
| EventSessionNextToolProgress
7273
| EventSessionNextToolSuccess
73-
| EventSessionNextToolError
74+
| EventSessionNextToolFailed
7475
| EventSessionNextRetried
7576
| EventSessionNextCompactionStarted
7677
| EventSessionNextCompactionDelta
@@ -823,6 +824,7 @@ export type GlobalEvent = {
823824
| EventSessionNextShellEnded
824825
| EventSessionNextStepStarted
825826
| EventSessionNextStepEnded
827+
| EventSessionNextStepFailed
826828
| EventSessionNextTextStarted
827829
| EventSessionNextTextDelta
828830
| EventSessionNextTextEnded
@@ -835,7 +837,7 @@ export type GlobalEvent = {
835837
| EventSessionNextToolCalled
836838
| EventSessionNextToolProgress
837839
| EventSessionNextToolSuccess
838-
| EventSessionNextToolError
840+
| EventSessionNextToolFailed
839841
| EventSessionNextRetried
840842
| EventSessionNextCompactionStarted
841843
| EventSessionNextCompactionDelta
@@ -857,6 +859,7 @@ export type GlobalEvent = {
857859
| SyncEventSessionNextShellEnded
858860
| SyncEventSessionNextStepStarted
859861
| SyncEventSessionNextStepEnded
862+
| SyncEventSessionNextStepFailed
860863
| SyncEventSessionNextTextStarted
861864
| SyncEventSessionNextTextDelta
862865
| SyncEventSessionNextTextEnded
@@ -869,7 +872,7 @@ export type GlobalEvent = {
869872
| SyncEventSessionNextToolCalled
870873
| SyncEventSessionNextToolProgress
871874
| SyncEventSessionNextToolSuccess
872-
| SyncEventSessionNextToolError
875+
| SyncEventSessionNextToolFailed
873876
| SyncEventSessionNextRetried
874877
| SyncEventSessionNextCompactionStarted
875878
| SyncEventSessionNextCompactionDelta
@@ -1973,6 +1976,22 @@ export type SyncEventSessionNextStepEnded = {
19731976
}
19741977
}
19751978

1979+
export type SyncEventSessionNextStepFailed = {
1980+
type: "sync"
1981+
name: "session.next.step.failed.1"
1982+
id: string
1983+
seq: number
1984+
aggregateID: "sessionID"
1985+
data: {
1986+
timestamp: number
1987+
sessionID: string
1988+
error: {
1989+
type: string
1990+
message: string
1991+
}
1992+
}
1993+
}
1994+
19761995
export type SyncEventSessionNextTextStarted = {
19771996
type: "sync"
19781997
name: "session.next.text.started.1"
@@ -2157,9 +2176,9 @@ export type SyncEventSessionNextToolSuccess = {
21572176
}
21582177
}
21592178

2160-
export type SyncEventSessionNextToolError = {
2179+
export type SyncEventSessionNextToolFailed = {
21612180
type: "sync"
2162-
name: "session.next.tool.error.1"
2181+
name: "session.next.tool.failed.1"
21632182
id: string
21642183
seq: number
21652184
aggregateID: "sessionID"
@@ -2710,6 +2729,19 @@ export type EventSessionNextStepEnded = {
27102729
}
27112730
}
27122731

2732+
export type EventSessionNextStepFailed = {
2733+
id: string
2734+
type: "session.next.step.failed"
2735+
properties: {
2736+
timestamp: number
2737+
sessionID: string
2738+
error: {
2739+
type: string
2740+
message: string
2741+
}
2742+
}
2743+
}
2744+
27132745
export type EventSessionNextTextStarted = {
27142746
id: string
27152747
type: "session.next.text.started"
@@ -2870,9 +2902,9 @@ export type EventSessionNextToolSuccess = {
28702902
}
28712903
}
28722904

2873-
export type EventSessionNextToolError = {
2905+
export type EventSessionNextToolFailed = {
28742906
id: string
2875-
type: "session.next.tool.error"
2907+
type: "session.next.tool.failed"
28762908
properties: {
28772909
timestamp: number
28782910
sessionID: string
@@ -3162,7 +3194,10 @@ export type SessionMessageAssistant = {
31623194
write: number
31633195
}
31643196
}
3165-
error?: string
3197+
error?: {
3198+
type: string
3199+
message: string
3200+
}
31663201
}
31673202

31683203
export type SessionMessageCompaction = {

0 commit comments

Comments
 (0)