@@ -4,7 +4,7 @@ import { SessionV1 } from "@opencode-ai/core/v1/session"
44import type { NamedError } from "@opencode-ai/core/util/error"
55import { APICallError } from "ai"
66import { setTimeout as sleep } from "node:timers/promises"
7- import { Effect , Schedule , Schema } from "effect"
7+ import { Effect , Exit , Schedule , Schema } from "effect"
88import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
99import { SessionRetry } from "../../src/session/retry"
1010import { MessageV2 } from "../../src/session/message-v2"
@@ -115,6 +115,28 @@ describe("session.retry.delay", () => {
115115 } )
116116 } ) ,
117117 )
118+
119+ it . instance ( "policy caps output-length errors at three retries" , ( ) =>
120+ Effect . gen ( function * ( ) {
121+ const error = new SessionV1 . OutputLengthError ( { } ) . toObject ( )
122+ const attempts : number [ ] = [ ]
123+ const step = yield * Schedule . toStep (
124+ SessionRetry . policy ( {
125+ provider : "test" ,
126+ parse : ( ) => error ,
127+ set : ( info ) => Effect . sync ( ( ) => attempts . push ( info . attempt ) ) ,
128+ } ) ,
129+ )
130+
131+ yield * step ( 0 , error )
132+ yield * step ( 0 , error )
133+ yield * step ( 0 , error )
134+ const fourth = yield * step ( 0 , error ) . pipe ( Effect . exit )
135+
136+ expect ( attempts ) . toStrictEqual ( [ 1 , 2 , 3 ] )
137+ expect ( Exit . isFailure ( fourth ) ) . toBe ( true )
138+ } ) ,
139+ )
118140} )
119141
120142describe ( "session.retry.retryable" , ( ) => {
0 commit comments