mirror of
https://github.com/stablyai/orca.git
synced 2026-09-30 16:02:56 +00:00
* fix(native-chat): hide activity while awaiting input * fix(native-chat): keep approval turns cancellable * test(native-chat): satisfy split PR quality gate * fix(native-chat): catalog approval cancellation label * fix(native-chat): include approval cancellation runtime label * fix(codex): settle prompts when cancelled turns complete * fix(codex): settle prompt registry fallbacks * test(native-chat): cover pending interaction fallbacks * test(native-chat): split prompt state coverage * test(native-chat): keep prompt state isolated * fix(native-chat): bound prompt turn backfill * refactor(codex): centralize prompt registry bounds * fix(native-chat): cancel pending prompts precisely * fix(native-chat): consolidate capability imports * fix(native-chat): harden precise prompt cancellation * fix claude cancellation teardown races * retry claude prompt lifecycle admission * bound claude prompt cancellation retry work * fix(codex): bound prompt turn identity on registration * fix(native-chat): route rejected late dispatch settlements * fix(codex): retain exact cancellable prompt turn ids --------- Co-authored-by: Merge Sim <sim@local>
60 lines
2.8 KiB
TypeScript
60 lines
2.8 KiB
TypeScript
// Why a submission is `rejected`: the message provably did not happen.
|
|
//
|
|
// Two different facts reach this state, and the reason string is what tells them
|
|
// apart. A CONTENT rejection is permanent — the provider looked at this payload
|
|
// and refused it, and it would refuse the same payload again; its reason is the
|
|
// provider's own explanation ("Claude messages support at most 20 images") and is
|
|
// meant to be read. A TRANSPORT rejection is transient — the frame was never
|
|
// handed to the provider at all, so the same text under a fresh id is a first
|
|
// delivery and the next attempt may well succeed; its reason names an internal
|
|
// cause and must NOT be put in front of a person.
|
|
//
|
|
// Both are `rejected` because both make the single claim that state exists to
|
|
// make: this message did not reach the provider. Neither is ever re-delivered
|
|
// under its own id — `rejected` is terminal in the reducer — so a retry rotates
|
|
// the client message id, which is a new message and cannot duplicate.
|
|
//
|
|
// Shared rather than main-only because both sides need it: the host writes the
|
|
// reason, and a client has to know which kind it is holding before it can decide
|
|
// whether the string is showable.
|
|
|
|
export const DISPATCH_REJECTED_WRITE_FAILED = 'provider_write_failed'
|
|
|
|
/** Local admission refused the frame before any transport was involved. Two
|
|
* strings rather than one provider-neutral marker because both are already
|
|
* durable journal reasons; rewording either would relabel rows on disk. */
|
|
export const DISPATCH_REJECTED_QUEUE_FULL = 'claude structured dispatch queue is full'
|
|
export const DISPATCH_REJECTED_CODEX_QUEUE_FULL = 'codex structured dispatch queue is full'
|
|
|
|
/** The provider confirmed a queued frame was withdrawn before execution. */
|
|
export const DISPATCH_REJECTED_CANCELLED = 'provider_cancelled_before_start'
|
|
|
|
export function dispatchWriteFailureReason(error: unknown): string {
|
|
const detail = error instanceof Error ? error.message : String(error)
|
|
return `${DISPATCH_REJECTED_WRITE_FAILED}: ${detail}`
|
|
}
|
|
|
|
/** True for the internal transport marker, false for a provider's own words. */
|
|
export function dispatchRejectionWasTransportWriteFailure(
|
|
reason: string | null | undefined
|
|
): boolean {
|
|
return (
|
|
reason === DISPATCH_REJECTED_WRITE_FAILED ||
|
|
reason?.startsWith(`${DISPATCH_REJECTED_WRITE_FAILED}: `) === true
|
|
)
|
|
}
|
|
|
|
/**
|
|
* True when the reason is ours rather than the provider's, so it must not be
|
|
* shown verbatim. A content rejection carries the provider's own explanation and
|
|
* is the only kind a person should read.
|
|
*/
|
|
export function dispatchRejectionReasonIsInternal(reason: string | null | undefined): boolean {
|
|
return (
|
|
dispatchRejectionWasTransportWriteFailure(reason) ||
|
|
reason === DISPATCH_REJECTED_QUEUE_FULL ||
|
|
reason === DISPATCH_REJECTED_CODEX_QUEUE_FULL ||
|
|
reason === DISPATCH_REJECTED_CANCELLED
|
|
)
|
|
}
|