feat: track thread ids and retry stream disconnects
This commit is contained in:
+25
-11
@@ -71,6 +71,8 @@ type Usage = {
|
||||
type RequestEntry = {
|
||||
seq: number;
|
||||
request_id?: string | null;
|
||||
response_id?: string | null;
|
||||
thread_id?: string | null;
|
||||
lifecycle_state?: string | null;
|
||||
started_at?: string;
|
||||
first_response_at?: string | null;
|
||||
@@ -303,7 +305,7 @@ const defaultProfileForm: ProfileFormState = {
|
||||
model_remap: "",
|
||||
reasoning_equals: "516,1034,1552",
|
||||
retryable_status_codes: "429,503",
|
||||
retryable_error_messages: "Selected model is at capacity. Please try a different model.",
|
||||
retryable_error_messages: "Selected model is at capacity. Please try a different model.\nstream disconnected before completion: Concurrency limit exceeded for account, please retry later",
|
||||
upstream_fetch_retry_attempts: "5",
|
||||
upstream_fetch_retry_backoff_ms: "350",
|
||||
endpoints: "/responses\n/chat/completions\n/v1/responses\n/v1/chat/completions",
|
||||
@@ -382,6 +384,10 @@ function cachedRatio(inputTokens?: number | null, cachedTokens?: number | null)
|
||||
return Math.max(0, Math.min(1, cached / inputTokens));
|
||||
}
|
||||
|
||||
function requestPrimaryId(entry: RequestEntry) {
|
||||
return entry.response_id || entry.request_id || "-";
|
||||
}
|
||||
|
||||
function splitList(value: string) {
|
||||
return value
|
||||
.split(/[\s,]+/)
|
||||
@@ -1105,7 +1111,8 @@ export default function App() {
|
||||
<div className="request-subtitle">
|
||||
<code>{`${entry.method || "-"} ${entry.path || "-"}`}</code>
|
||||
<span className="hint">{entry.response_stream ? "stream" : "non-stream"}</span>
|
||||
<span className="hint">{entry.request_id || "-"}</span>
|
||||
<span className="hint">id {requestPrimaryId(entry)}</span>
|
||||
<span className="hint">thread {entry.thread_id || "-"}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="request-badges">
|
||||
@@ -1138,16 +1145,23 @@ export default function App() {
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="request-block">
|
||||
<label>Token</label>
|
||||
<div className="request-token-row">
|
||||
<span className="token-pill token-in">in {numberFormat(effectiveInput)}</span>
|
||||
<span className="token-pill token-out">out {numberFormat(usage.output_tokens)}</span>
|
||||
<span className="token-pill token-cached">cached {numberFormat(usage.cached_tokens)}{cachedHitRatio !== null ? ` (${percent(cachedHitRatio)})` : ""}</span>
|
||||
<span className="token-pill token-reasoning">reasoning {numberFormat(entry.reasoning_tokens ?? usage.reasoning_tokens)}</span>
|
||||
<span className="token-pill token-total">total {numberFormat(usage.total_tokens)}</span>
|
||||
<div className="request-block">
|
||||
<label>Token</label>
|
||||
<div className="request-token-row">
|
||||
<span className="token-pill token-in">in {numberFormat(effectiveInput)}</span>
|
||||
<span className="token-pill token-out">out {numberFormat(usage.output_tokens)}</span>
|
||||
<span className="token-pill token-cached">cached {numberFormat(usage.cached_tokens)}{cachedHitRatio !== null ? ` (${percent(cachedHitRatio)})` : ""}</span>
|
||||
<span className="token-pill token-reasoning">reasoning {numberFormat(entry.reasoning_tokens ?? usage.reasoning_tokens)}</span>
|
||||
<span className="token-pill token-total">total {numberFormat(usage.total_tokens)}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="request-block">
|
||||
<label>IDs</label>
|
||||
<code>{`response ${entry.response_id || "-"}`}</code>
|
||||
<span className="hint">{`request ${entry.request_id || "-"}`}</span>
|
||||
<span className="hint">{`thread ${entry.thread_id || "-"}`}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user