(evidence: ModelStepSettlementEvidence)
| 524 | } |
| 525 | |
| 526 | export function settleModelStepOutcome(evidence: ModelStepSettlementEvidence): ModelStepOutcome { |
| 527 | const { aborted, failure, sawFinish, finishReason, usage, request } = evidence; |
| 528 | if (aborted || failure?.kind === 'abort') { |
| 529 | return failedStepOutcome( |
| 530 | 'aborted', |
| 531 | failure ?? normalizeModelFailure(Object.assign(new Error('aborted'), { name: 'AbortError' })), |
| 532 | request, |
| 533 | usage, |
| 534 | ); |
| 535 | } |
| 536 | if (failure) { |
| 537 | return failedStepOutcome( |
| 538 | failure.retryable ? 'retryable-failure' : 'terminal-failure', |
| 539 | failure, |
| 540 | request, |
| 541 | usage, |
| 542 | ); |
| 543 | } |
| 544 | if (!sawFinish || finishReason === 'other' || finishReason === 'unknown') { |
| 545 | return failedStepOutcome( |
| 546 | 'truncated', |
| 547 | modelStepFailure( |
| 548 | 'provider_unavailable', |
| 549 | `Provider stream ended without finishing (${finishReason})`, |
| 550 | ), |
| 551 | request, |
| 552 | usage, |
| 553 | ); |
| 554 | } |
| 555 | if (finishReason === 'content-filter' || finishReason === 'error') { |
| 556 | return failedStepOutcome( |
| 557 | 'terminal-failure', |
| 558 | modelStepFailure( |
| 559 | finishReason === 'content-filter' ? 'unknown' : 'provider_unavailable', |
| 560 | finishReason === 'content-filter' |
| 561 | ? 'Provider stopped the stream on a content filter' |
| 562 | : 'Provider stopped the stream with an error', |
| 563 | ), |
| 564 | request, |
| 565 | usage, |
| 566 | ); |
| 567 | } |
| 568 | return { |
| 569 | kind: 'completed', |
| 570 | finishReason, |
| 571 | ...(usage ? { usage } : {}), |
| 572 | request, |
| 573 | continuation: 'none', |
| 574 | }; |
| 575 | } |
| 576 | |
| 577 | function modelStepFailure(kind: ModelFailureKind, message: string): ModelFailure { |
| 578 | return { type: 'model_failure', kind, message, retryable: false }; |
no test coverage detected