Unified · Split
| @@ -234,28 +234,30 @@ export const makeClaudeTextGeneration = Effect.fn("makeClaudeTextGeneration")(fu · 233 unmodified lines | ||
| 234 | 234 | ); |
| 235 | 235 | |
| 236 | 236 | const envelope = yield* decodeClaudeOutputEnvelope(rawStdout).pipe( |
| 237 | − Effect.catchTag("SchemaError", (cause) => | |
| 238 | − Effect.fail( | |
| 239 | − new TextGenerationError({ | |
| 240 | − operation, | |
| 241 | − detail: "Claude CLI returned unexpected output format.", | |
| 242 | − cause, | |
| 243 | − }), | |
| 244 | − ), | |
| 245 | − ), | |
| 237 | + Effect.catchTags({ | |
| 238 | + SchemaError: (cause) => | |
| 239 | + Effect.fail( | |
| 240 | + new TextGenerationError({ | |
| 241 | + operation, | |
| 242 | + detail: "Claude CLI returned unexpected output format.", | |
| 243 | + cause, | |
| 244 | + }), | |
| 245 | + ), | |
| 246 | + }), | |
| 246 | 247 | ); |
| 247 | 248 | |
| 248 | 249 | const decodeOutput = Schema.decodeEffect(outputSchemaJson); |
| 249 | 250 | return yield* decodeOutput(envelope.structured_output).pipe( |
| 250 | − Effect.catchTag("SchemaError", (cause) => | |
| 251 | − Effect.fail( | |
| 252 | − new TextGenerationError({ | |
| 253 | − operation, | |
| 254 | − detail: "Claude returned invalid structured output.", | |
| 255 | − cause, | |
| 256 | − }), | |
| 257 | − ), | |
| 258 | − ), | |
| 251 | + Effect.catchTags({ | |
| 252 | + SchemaError: (cause) => | |
| 253 | + Effect.fail( | |
| 254 | + new TextGenerationError({ | |
| 255 | + operation, | |
| 256 | + detail: "Claude returned invalid structured output.", | |
| 257 | + cause, | |
| 258 | + }), | |
| 259 | + ), | |
| 260 | + }), | |
| 259 | 261 | ); |
| 260 | 262 | }); |
| 261 | 263 | |
| @@ -281,15 +281,16 @@ export const makeCodexTextGeneration = Effect.fn("makeCodexTextGeneration")(func · 280 unmodified lines | ||
| 281 | 281 | }), |
| 282 | 282 | ), |
| 283 | 283 | Effect.flatMap(decodeOutput), |
| 284 | − Effect.catchTag("SchemaError", (cause) => | |
| 285 | − Effect.fail( | |
| 286 | − new TextGenerationError({ | |
| 287 | − operation, | |
| 288 | − detail: "Codex returned invalid structured output.", | |
| 289 | − cause, | |
| 290 | − }), | |
| 291 | − ), | |
| 292 | − ), | |
| 284 | + Effect.catchTags({ | |
| 285 | + SchemaError: (cause) => | |
| 286 | + Effect.fail( | |
| 287 | + new TextGenerationError({ | |
| 288 | + operation, | |
| 289 | + detail: "Codex returned invalid structured output.", | |
| 290 | + cause, | |
| 291 | + }), | |
| 292 | + ), | |
| 293 | + }), | |
| 293 | 294 | ); |
| 294 | 295 | }).pipe(Effect.ensuring(cleanup)); |
| 295 | 296 | }); |
| @@ -28,30 +28,7 @@ import { · 27 unmodified lines | ||
| 28 | 28 | |
| 29 | 29 | const CURSOR_TIMEOUT_MS = 180_000; |
| 30 | 30 | |
| 31 | −function mapCursorAcpError( | |
| 32 | − operation: | |
| 33 | − | "generateCommitMessage" | |
| 34 | − | "generatePrContent" | |
| 35 | − | "generateBranchName" | |
| 36 | − | "generateThreadTitle", | |
| 37 | − detail: string, | |
| 38 | − cause: unknown, | |
| 39 | −): TextGenerationError { | |
| 40 | − return new TextGenerationError({ | |
| 41 | − operation, | |
| 42 | − detail, | |
| 43 | − ...(cause !== undefined ? { cause } : {}), | |
| 44 | − }); | |
| 45 | −} | |
| 46 | − | |
| 47 | −function isTextGenerationError(error: unknown): error is TextGenerationError { | |
| 48 | − return ( | |
| 49 | − typeof error === "object" && | |
| 50 | − error !== null && | |
| 51 | − "_tag" in error && | |
| 52 | − error._tag === "TextGenerationError" | |
| 53 | − ); | |
| 54 | −} | |
| 31 | +const isTextGenerationError = Schema.is(TextGenerationError); | |
| 55 | 32 | |
| 56 | 33 | /** |
| 57 | 34 | * Build a Cursor text-generation closure bound to a specific `CursorSettings` |
| @@ -111,13 +88,14 @@ export const makeCursorTextGeneration = Effect.fn("makeCursorTextGeneration")(fu · 53 unmodified lines | ||
| 111 | 88 | model: modelSelection.model, |
| 112 | 89 | selections: modelSelection.options, |
| 113 | 90 | mapError: ({ cause, configId, step }) => |
| 114 | − mapCursorAcpError( | |
| 91 | + new TextGenerationError({ | |
| 115 | 92 | operation, |
| 116 | − step === "set-config-option" | |
| 117 | − ? `Failed to set Cursor ACP config option "${configId}" for text generation.` | |
| 118 | − : "Failed to set Cursor ACP base model for text generation.", | |
| 93 | + detail: | |
| 94 | + step === "set-config-option" | |
| 95 | + ? `Failed to set Cursor ACP config option "${configId}" for text generation.` | |
| 96 | + : "Failed to set Cursor ACP base model for text generation.", | |
| 119 | 97 | cause, |
| 120 | − ), | |
| 98 | + }), | |
| 121 | 99 | }); |
| 122 | 100 | |
| 123 | 101 | return yield* runtime.prompt({ |
| @@ -140,7 +118,11 @@ export const makeCursorTextGeneration = Effect.fn("makeCursorTextGeneration")(fu · 16 unmodified lines | ||
| 140 | 118 | Effect.mapError((cause) => |
| 141 | 119 | isTextGenerationError(cause) |
| 142 | 120 | ? cause |
| 143 | − : mapCursorAcpError(operation, "Cursor ACP request failed.", cause), | |
| 121 | + : new TextGenerationError({ | |
| 122 | + operation, | |
| 123 | + detail: "Cursor ACP request failed.", | |
| 124 | + cause, | |
| 125 | + }), | |
| 144 | 126 | ), |
| 145 | 127 | ); |
| 146 | 128 | |
| @@ -157,21 +139,26 @@ export const makeCursorTextGeneration = Effect.fn("makeCursorTextGeneration")(fu · 10 unmodified lines | ||
| 157 | 139 | |
| 158 | 140 | const decodeOutput = Schema.decodeEffect(Schema.fromJsonString(outputSchemaJson)); |
| 159 | 141 | return yield* decodeOutput(extractJsonObject(rawResult)).pipe( |
| 160 | − Effect.catchTag("SchemaError", (cause) => | |
| 161 | − Effect.fail( | |
| 162 | − new TextGenerationError({ | |
| 163 | − operation, | |
| 164 | − detail: "Cursor Agent returned invalid structured output.", | |
| 165 | − cause, | |
| 166 | − }), | |
| 167 | − ), | |
| 168 | − ), | |
| 142 | + Effect.catchTags({ | |
| 143 | + SchemaError: (cause) => | |
| 144 | + Effect.fail( | |
| 145 | + new TextGenerationError({ | |
| 146 | + operation, | |
| 147 | + detail: "Cursor Agent returned invalid structured output.", | |
| 148 | + cause, | |
| 149 | + }), | |
| 150 | + ), | |
| 151 | + }), | |
| 169 | 152 | ); |
| 170 | 153 | }).pipe( |
| 171 | 154 | Effect.mapError((cause) => |
| 172 | 155 | isTextGenerationError(cause) |
| 173 | 156 | ? cause |
| 174 | − : mapCursorAcpError(operation, "Cursor ACP text generation failed.", cause), | |
| 157 | + : new TextGenerationError({ | |
| 158 | + operation, | |
| 159 | + detail: "Cursor ACP text generation failed.", | |
| 160 | + cause, | |
| 161 | + }), | |
| 175 | 162 | ), |
| 176 | 163 | Effect.scoped, |
| 177 | 164 | ); |
| @@ -31,30 +31,7 @@ import { · 30 unmodified lines | ||
| 31 | 31 | |
| 32 | 32 | const GROK_TIMEOUT_MS = 180_000; |
| 33 | 33 | |
| 34 | −function mapGrokAcpError( | |
| 35 | − operation: | |
| 36 | − | "generateCommitMessage" | |
| 37 | − | "generatePrContent" | |
| 38 | − | "generateBranchName" | |
| 39 | − | "generateThreadTitle", | |
| 40 | − detail: string, | |
| 41 | − cause: unknown, | |
| 42 | −): TextGenerationError { | |
| 43 | − return new TextGenerationError({ | |
| 44 | − operation, | |
| 45 | − detail, | |
| 46 | − ...(cause !== undefined ? { cause } : {}), | |
| 47 | − }); | |
| 48 | −} | |
| 49 | − | |
| 50 | −function isTextGenerationError(error: unknown): error is TextGenerationError { | |
| 51 | − return ( | |
| 52 | − typeof error === "object" && | |
| 53 | − error !== null && | |
| 54 | − "_tag" in error && | |
| 55 | − error._tag === "TextGenerationError" | |
| 56 | − ); | |
| 57 | −} | |
| 34 | +const isTextGenerationError = Schema.is(TextGenerationError); | |
| 58 | 35 | |
| 59 | 36 | export const makeGrokTextGeneration = Effect.fn("makeGrokTextGeneration")(function* ( |
| 60 | 37 | grokSettings: GrokSettings, |
| @@ -109,11 +86,11 @@ export const makeGrokTextGeneration = Effect.fn("makeGrokTextGeneration")(functi · 48 unmodified lines | ||
| 109 | 86 | currentModelId: currentGrokModelIdFromSessionSetup(started.sessionSetupResult), |
| 110 | 87 | requestedModelId: resolvedModel, |
| 111 | 88 | mapError: (cause) => |
| 112 | − mapGrokAcpError( | |
| 89 | + new TextGenerationError({ | |
| 113 | 90 | operation, |
| 114 | − "Failed to set Grok ACP base model for text generation.", | |
| 91 | + detail: "Failed to set Grok ACP base model for text generation.", | |
| 115 | 92 | cause, |
| 116 | − ), | |
| 93 | + }), | |
| 117 | 94 | }); |
| 118 | 95 | |
| 119 | 96 | return yield* runtime.prompt({ |
| @@ -133,7 +110,11 @@ export const makeGrokTextGeneration = Effect.fn("makeGrokTextGeneration")(functi · 13 unmodified lines | ||
| 133 | 110 | Effect.mapError((cause: EffectAcpErrors.AcpError | TextGenerationError) => |
| 134 | 111 | isTextGenerationError(cause) |
| 135 | 112 | ? cause |
| 136 | − : mapGrokAcpError(operation, "Grok ACP request failed.", cause), | |
| 113 | + : new TextGenerationError({ | |
| 114 | + operation, | |
| 115 | + detail: "Grok ACP request failed.", | |
| 116 | + cause, | |
| 117 | + }), | |
| 137 | 118 | ), |
| 138 | 119 | ); |
| 139 | 120 | |
| @@ -150,21 +131,26 @@ export const makeGrokTextGeneration = Effect.fn("makeGrokTextGeneration")(functi · 10 unmodified lines | ||
| 150 | 131 | |
| 151 | 132 | const decodeOutput = Schema.decodeEffect(Schema.fromJsonString(outputSchemaJson)); |
| 152 | 133 | return yield* decodeOutput(extractJsonObject(trimmed)).pipe( |
| 153 | − Effect.catchTag("SchemaError", (cause) => | |
| 154 | − Effect.fail( | |
| 155 | − new TextGenerationError({ | |
| 156 | − operation, | |
| 157 | − detail: "Grok Agent returned invalid structured output.", | |
| 158 | − cause, | |
| 159 | − }), | |
| 160 | − ), | |
| 161 | − ), | |
| 134 | + Effect.catchTags({ | |
| 135 | + SchemaError: (cause) => | |
| 136 | + Effect.fail( | |
| 137 | + new TextGenerationError({ | |
| 138 | + operation, | |
| 139 | + detail: "Grok Agent returned invalid structured output.", | |
| 140 | + cause, | |
| 141 | + }), | |
| 142 | + ), | |
| 143 | + }), | |
| 162 | 144 | ); |
| 163 | 145 | }).pipe( |
| 164 | 146 | Effect.mapError((cause) => |
| 165 | 147 | isTextGenerationError(cause) |
| 166 | 148 | ? cause |
| 167 | − : mapGrokAcpError(operation, "Grok ACP text generation failed.", cause), | |
| 149 | + : new TextGenerationError({ | |
| 150 | + operation, | |
| 151 | + detail: "Grok ACP text generation failed.", | |
| 152 | + cause, | |
| 153 | + }), | |
| 168 | 154 | ), |
| 169 | 155 | Effect.scoped, |
| 170 | 156 | ); |
| @@ -348,15 +348,16 @@ export const makeOpenCodeTextGeneration = Effect.fn("makeOpenCodeTextGeneration" · 347 unmodified lines | ||
| 348 | 348 | |
| 349 | 349 | const decodeOutput = Schema.decodeEffect(Schema.fromJsonString(input.outputSchemaJson)); |
| 350 | 350 | return yield* decodeOutput(extractJsonObject(rawOutput)).pipe( |
| 351 | − Effect.catchTag("SchemaError", (cause) => | |
| 352 | − Effect.fail( | |
| 353 | − new TextGenerationError({ | |
| 354 | − operation: input.operation, | |
| 355 | − detail: "OpenCode returned invalid structured output.", | |
| 356 | − cause, | |
| 357 | − }), | |
| 358 | − ), | |
| 359 | − ), | |
| 351 | + Effect.catchTags({ | |
| 352 | + SchemaError: (cause) => | |
| 353 | + Effect.fail( | |
| 354 | + new TextGenerationError({ | |
| 355 | + operation: input.operation, | |
| 356 | + detail: "OpenCode returned invalid structured output.", | |
| 357 | + cause, | |
| 358 | + }), | |
| 359 | + ), | |
| 360 | + }), | |
| 360 | 361 | ); |
| 361 | 362 | }); |
| 362 | 363 | |