import type { OpenGeniBrowserClient } from "@opengeni/sdk/browser"; import { type SessionUsageLimit } from "@opengeni/sdk/session-usage-limits"; import type { ClientConfig, SessionEvent } from "../types.js"; /** * - `absent`: an older server. Hide the feature and never send a limit. * - `disabled`: the server turned new limits off. Show existing state and * allow only removing a limit. * - `enabled`: the full editor. */ export type SessionUsageLimitCapability = "absent" | "disabled" | "enabled"; export declare function sessionUsageLimitCapability(config: Pick | null | undefined): SessionUsageLimitCapability; /** A limit being chosen: none, or an amount typed in dollars. */ export type SessionUsageLimitDraft = { kind: "none"; } | { kind: "limit"; text: string; }; export declare const NO_SESSION_USAGE_LIMIT: SessionUsageLimitDraft; export type ParsedSessionUsageLimitDraft = { ok: true; limitMicros: number | null; } | { ok: false; error: string; }; export declare const USAGE_LIMIT_AMOUNT_REQUIRED = "Enter an amount in US dollars, like 25."; export declare const USAGE_LIMIT_AMOUNT_INVALID = "Enter dollars with up to 2 decimals, at most $10,000,000."; /** The draft as the request's `limitMicros` (null for no limit), or why it can't be sent. */ export declare function parseSessionUsageLimitDraft(draft: SessionUsageLimitDraft): ParsedSessionUsageLimitDraft; /** The right-hand value of the new-chat "Usage limit" row. */ export declare function sessionUsageLimitDraftSummary(draft: SessionUsageLimitDraft): string; /** Plain dollars for the amount input ("50", "12.5"), no symbol or grouping. */ export declare function sessionUsageLimitInputValue(micros: number): string; export type SessionUsageLimitSaveFailure = { kind: "conflict" | "preparing" | "not_root" | "forbidden" | "disabled" | "unavailable" | "invalid" | "unknown" | "other"; message: string; /** For `not_root`: the task that owns the limit. */ rootSessionId?: string | undefined; }; /** * The save may or may not have been applied (the response was lost). Re-send * the same operation to find out; the server applies an operation once. */ export declare function isOutcomeUnknown(error: unknown): boolean; /** What a failed save means, in words, from the response's `details.code`. */ export declare function classifySessionUsageLimitSaveError(error: unknown): SessionUsageLimitSaveFailure; export declare const OPEN_SESSION_USAGE_LIMIT_EVENT = "opengeni:open-session-usage-limit"; export declare function requestSessionUsageLimitEditor(target: EventTarget): void; /** Any agent in the task tree is running: keep the usage view fresh. */ export declare function lineageHasRunningSession(nodes: ReadonlyArray<{ session: { status: string; }; children: ReadonlyArray; }>): boolean; export type SessionUsageLimitRefusalAmounts = { rootSessionId: string; limitMicros: number; usedMicros: number; }; /** * What a refused Send says until the reread projection answers: the typed * refusal's amounts when the error carries them, otherwise the last known * limit (the server only refuses at or over it). Null when nothing is * pending, or nothing is known to show. */ export declare function usageLimitRefusalFromState(input: { pending: boolean; error: { rootSessionId?: string | undefined; limitMicros?: number | undefined; usedMicros?: number | undefined; } | null; usage: SessionUsageLimit | null; }): SessionUsageLimitRefusalAmounts | null; type UsageLimitClient = Pick; export type SessionUsageLimitSnapshot = { usage: SessionUsageLimit | null; /** The last read failed (the last good value, if any, stays). */ error: unknown; loading: boolean; }; /** Events on the task's own stream that can change its usage or limit. */ export declare function isSessionUsageLimitRefreshEvent(event: SessionEvent): boolean; /** * The goal is paused at the usage limit right now: the newest goal event in * the loaded stream is that pause. Raising the limit never resumes it. */ export declare function goalPausedAtUsageLimit(events: readonly SessionEvent[]): boolean; /** Wait after a burst of usage events before reading, so one turn is one read. */ export declare const SESSION_USAGE_LIMIT_EVENT_DEBOUNCE_MS = 1000; /** * At most this often, while the page is visible and the task tree is running * or could still change unseen (it has agents, or a limit is set). A child's * usage is not in the parent's stream, so this bounds how stale it can get. */ export declare const SESSION_USAGE_LIMIT_POLL_MS = 30000; export type UseSessionUsageLimitOptions = { client: UsageLimitClient; workspaceId: string; sessionId: string; /** `session.usageLimit` from the detail read, until the first GET answers. */ initial?: SessionUsageLimit | null | undefined; /** False when the server doesn't offer limits: never read. */ enabled: boolean; /** * Only the one owner of the live stream passes these: it reads on relevant * events, polls while visible, does a final read when the tree goes idle, * and rereads on focus and reconnect. Other views share what it reads. */ live?: { events: readonly SessionEvent[]; /** The session or one of its agents is running. */ active: boolean; /** * Keep polling while idle: the task has agents, which can start and finish * between two reads of the tree without the parent's stream showing it. */ watch?: boolean | undefined; connectionState?: string | undefined; } | undefined; }; export type SessionUsageLimitState = SessionUsageLimitSnapshot & { refresh: () => Promise; /** Show a saved projection right away (the PUT response). */ apply: (usage: SessionUsageLimit) => void; }; export declare function useSessionUsageLimit(options: UseSessionUsageLimitOptions): SessionUsageLimitState; export {};