import { AgentProfile } from "@tangle-network/agent-interface";
//#region src/types.d.ts
interface TCloudConfig {
  /** API base URL (default: https://router.tangle.tools/v1) */
  baseURL?: string;
  /** Platform API URL for billing/keys (default: https://id.tangle.tools) */
  platformURL?: string;
  /** API key for standard (non-private) mode */
  apiKey?: string;
  /** Default model */
  model?: string;
  /** Operator routing preferences */
  routing?: RoutingConfig;
  /** Enable shielded (private) mode */
  shielded?: ShieldedConfig | boolean;
  /** Privacy proxy configuration for IP hiding */
  privacy?: PrivacyConfig;
  /** Spending limits and metering */
  limits?: SpendingLimits;
  /** Retry configuration for transient failures */
  retry?: RetryConfig | false;
  /** Default request timeout in ms (default: 60000). Set 0 to disable. */
  timeout?: number;
}
interface RetryConfig {
  /** Max retry attempts (default: 3) */
  maxRetries?: number;
  /** Initial backoff in ms (default: 500) */
  initialBackoffMs?: number;
  /** Max backoff in ms (default: 30000) */
  maxBackoffMs?: number;
  /** Backoff multiplier (default: 2) */
  multiplier?: number;
  /** HTTP status codes that trigger retry (default: [429, 500, 502, 503, 504]) */
  retryableStatuses?: number[];
}
interface SpendingLimits {
  /** Max USD to spend per request. Rejects if estimated cost exceeds this. */
  maxCostPerRequest?: number;
  /** Max USD to spend across all requests in this client's lifetime. Stops at limit. */
  maxTotalSpend?: number;
  /** Max requests allowed. Stops at limit. */
  maxRequests?: number;
  /** Callback when a limit is approached (80% threshold) */
  onLimitWarning?: (info: {
    type: 'cost' | 'total' | 'requests';
    current: number;
    limit: number;
  }) => void;
  /** Callback when a limit is hit (request blocked) */
  onLimitReached?: (info: {
    type: 'cost' | 'total' | 'requests';
    current: number;
    limit: number;
  }) => void;
}
interface RoutingConfig {
  /** Routing mode: 'operator' (Tangle operators only), 'provider' (direct APIs only), 'auto' (try operators, fall back to providers) */
  mode?: 'operator' | 'provider' | 'auto';
  /** Preferred operator slug or address */
  prefer?: string;
  /** Blueprint ID — route to operators under this Blueprint */
  blueprintId?: string;
  /** Service instance ID — route to a specific service instance */
  serviceId?: string;
  /** Routing strategy */
  strategy?: 'lowest-latency' | 'lowest-price' | 'highest-reputation' | 'round-robin';
  /** Region filter */
  region?: string;
  /** Fallback operator slugs (tried in order) */
  fallback?: string[];
}
interface EmbeddingOptions {
  model?: string;
  input: string | string[];
}
interface EmbeddingResponse {
  object: string;
  data: {
    object: string;
    embedding: number[];
    index: number;
  }[];
  model: string;
  usage: {
    prompt_tokens: number;
    total_tokens: number;
  };
}
interface ImageGenerateOptions {
  model?: string;
  prompt: string;
  n?: number;
  size?: string;
  quality?: string;
  response_format?: 'url' | 'b64_json';
}
/**
 * OpenAI-compatible /v1/images/edits request. Accepts one or more
 * reference images + a prompt describing how to transform them.
 *
 * For gpt-image-2, the supplied images are passed as `image[]` (the
 * model supports multi-image composition); for dall-e-2 only a single
 * image is honored. The optional `mask` is the OpenAI inpainting mask
 * (PNG with alpha) used to constrain where edits are applied.
 *
 * Carrying both shapes here lets callers point at the same `imagesEdit`
 * method regardless of upstream model; cli-bridge / tangle-router
 * decide what to forward.
 */
interface ImageEditOptions {
  model?: string;
  prompt: string;
  /** One or more reference images. Pass as Blob (browser/Node 22+),
   *  ArrayBuffer (will be wrapped in a Blob), or `{data, mediaType}`
   *  for base64 + explicit mime. The first form is preferred. */
  image: ImageEditAttachment | ImageEditAttachment[];
  /** Optional inpainting mask — PNG with transparent pixels marking
   *  the editable region (OpenAI dall-e-2 / gpt-image-2 inpaint mode). */
  mask?: ImageEditAttachment;
  n?: number;
  size?: string;
  quality?: string;
  response_format?: 'url' | 'b64_json';
}
type ImageEditAttachment = Blob | ArrayBuffer | {
  data: string /** base64 */;
  mediaType: string;
  filename?: string;
};
interface ImageResponse {
  created: number;
  data: {
    url?: string;
    b64_json?: string;
    revised_prompt?: string;
  }[];
}
interface RerankOptions {
  model?: string;
  query: string;
  documents: string[];
  top_n?: number;
}
interface RerankResponse {
  results: {
    index: number;
    relevance_score: number;
  }[];
}
type SearchProvider = 'perplexity' | 'exa' | 'you' | 'parallel' | 'tavily' | 'brave';
type SearchRecency = 'day' | 'week' | 'month' | 'year';
interface SearchOptions {
  /** Cancel transport, response-body reads and retry waits. Never serialized. */
  signal?: AbortSignal;
  query: string;
  provider?: SearchProvider;
  /** Alias accepted by the Router for provider-compatible clients. */
  model?: SearchProvider;
  maxResults?: number;
  searchRecency?: SearchRecency;
  includeDomains?: string[];
  excludeDomains?: string[];
}
interface SearchHit {
  title: string;
  url: string;
  snippet?: string;
  publishedAt?: string;
  score?: number;
  source?: string;
}
interface SearchResponse {
  id: string;
  object: 'search.result' | string;
  provider: SearchProvider;
  model: string;
  query: string;
  data: SearchHit[];
  citations: string[];
  usage?: {
    upstream_cost?: number;
    billed_cost?: number;
    gross_margin?: number;
    markup?: number;
    billing_units?: Record<string, unknown>;
  };
}
/** Providers served by the router's research API (POST /v1/research). Mirrors
 *  SearchProvider minus `brave` (no research API). Each has its own `effort`
 *  vocabulary — see ResearchOptions.effort. */
type ResearchProvider = 'perplexity' | 'exa' | 'you' | 'parallel' | 'tavily';
interface ResearchOptions {
  query: string;
  provider?: ResearchProvider;
  /** Alias accepted by the Router for provider-compatible clients. */
  model?: ResearchProvider;
  /** Depth/cost dial, provider-specific:
   *  perplexity minimal|low|medium|high · you lite|standard|deep|exhaustive ·
   *  exa deep-lite|deep|deep-reasoning · tavily mini|pro|auto ·
   *  parallel lite|base|core|pro|ultra. Omit for the provider default. */
  effort?: string;
  maxResults?: number;
  searchRecency?: SearchRecency;
  includeDomains?: string[];
  excludeDomains?: string[];
  /** Optional JSON schema requesting structured output from the provider. */
  outputSchema?: unknown;
}
interface ResearchHit {
  title: string;
  url: string;
  snippet?: string;
  publishedAt?: string;
  source?: string;
}
interface ResearchResponse {
  id: string;
  object: 'research.result' | string;
  provider: ResearchProvider;
  query: string;
  /** The synthesized multi-step research answer. */
  answer: string;
  /** Supporting sources behind the answer. */
  results: ResearchHit[];
  citations: string[];
  /** Present when an outputSchema was requested and the provider honored it. */
  structured?: unknown;
  usage?: {
    upstream_cost?: number;
    billed_cost?: number;
    gross_margin?: number;
    markup?: number;
    billing_units?: Record<string, unknown>;
  };
}
interface WebSearchPlugin {
  id: 'web';
  engine?: 'native' | 'exa' | 'parallel' | 'firecrawl';
  provider?: SearchProvider;
  maxResults?: number;
  max_results?: number;
  searchPrompt?: string;
  search_prompt?: string;
  includeDomains?: string[];
  include_domains?: string[];
  excludeDomains?: string[];
  exclude_domains?: string[];
  searchRecency?: SearchRecency;
  search_recency?: SearchRecency;
}
type ChatPlugin = WebSearchPlugin | ({
  id: string;
} & Record<string, unknown>);
interface CompletionOptions {
  model?: string;
  prompt: string;
  temperature?: number;
  maxTokens?: number;
  stop?: string | string[];
  topP?: number;
}
interface CompletionResponse {
  id: string;
  object: string;
  created: number;
  model: string;
  choices: {
    text: string;
    index: number;
    finish_reason: string;
  }[];
  usage?: {
    prompt_tokens: number;
    completion_tokens: number;
    total_tokens: number;
  };
}
interface TranscriptionResponse {
  text: string;
}
interface FineTuningJobOptions {
  model: string;
  training_file: string;
  hyperparameters?: {
    n_epochs?: number | 'auto';
    batch_size?: number | 'auto';
    learning_rate_multiplier?: number | 'auto';
  };
  suffix?: string;
}
interface FineTuningJob {
  id: string;
  object: string;
  model: string;
  status: string;
  created_at: number;
  finished_at: number | null;
  fine_tuned_model: string | null;
  error: {
    code: string;
    message: string;
  } | null;
}
interface BatchRequest {
  model: string;
  messages: ChatMessage[];
  temperature?: number;
  max_tokens?: number;
}
interface BatchJobResponse {
  id: string;
  status: 'pending' | 'processing' | 'completed' | 'failed';
  total_items: number;
  completed: number;
  failed: number;
  results: ({
    status: 'fulfilled';
    data: ChatCompletion;
  } | {
    status: 'rejected';
    error: string;
  })[] | null;
  error: string | null;
  created_at: string;
  completed_at: string | null;
}
interface VideoGenerateOptions {
  model?: string;
  provider?: string | Record<string, unknown>;
  prompt: string;
  duration?: number;
  resolution?: string;
  aspect_ratio?: string;
  size?: string;
  image_url?: string;
  frame_images?: Array<Record<string, unknown>>;
  input_references?: Array<Record<string, unknown>>;
  generate_audio?: boolean;
  seed?: number;
  callback_url?: string;
}
interface VideoResponse {
  id: string;
  status: string;
  url?: string;
  error?: string;
}
/** Request body for POST /v1/avatar/generate */
interface AvatarGenerateRequest {
  /** URL to narration audio (wav/mp3) */
  audio_url: string;
  /** URL to face image, OR omit and use avatar_id */
  image_url?: string;
  /** Preset avatar identifier (provider-specific) */
  avatar_id?: string;
  /** Target duration in seconds (capped by operator's max_duration_seconds) */
  duration_seconds?: number;
  /** Output format (default: "mp4") */
  output_format?: string;
}
/** Response from POST /v1/avatar/generate (202 Accepted) */
interface AvatarGenerateResponse {
  job_id: string;
  status: 'queued' | 'processing' | 'completed' | 'failed';
  result?: AvatarResult;
  error?: string;
}
/** Result payload within a completed avatar job */
interface AvatarResult {
  video_url: string;
  duration_seconds: number;
  format: string;
}
/** Response from GET /v1/avatar/jobs/:id */
interface AvatarJobStatus {
  job_id: string;
  status: 'queued' | 'processing' | 'completed' | 'failed';
  result?: AvatarResult;
  error?: string;
}
interface PrivacyConfig {
  /** 'direct' — no proxy (default). 'relayer' — route through tcloud-relayer. */
  mode: 'direct' | 'relayer';
  /** Relayer URL for 'relayer' mode (e.g. 'http://localhost:3030') */
  relayerUrl?: string;
}
interface ShieldedConfig {
  /** Pre-existing spending private key (hex). If not set, generates ephemeral. */
  spendingKey?: string;
  /** Pre-existing commitment. If not set, derives from key. */
  commitment?: string;
  /** Chain ID (default: 3799 for Tangle testnet) */
  chainId?: number;
  /** ShieldedCredits contract address */
  creditsAddress?: string;
  /** Service ID for the blueprint */
  serviceId?: bigint;
  /** Privacy proxy configuration for IP hiding */
  privacy?: PrivacyConfig;
}
interface ChatMessage {
  role: 'system' | 'user' | 'assistant' | 'tool';
  content: string;
  name?: string;
}
/** Gateway-level options for routing, compliance, and inference strategies. */
interface GatewayOptions {
  /** BYOK: per-request provider credentials. Zero markup. */
  byok?: Record<string, Array<{
    apiKey?: string;
  }>>;
  /** Route only through ZDR-verified providers. */
  zeroDataRetention?: boolean;
  /** Route only through providers that don't train on prompts. */
  disallowPromptTraining?: boolean;
  /** Inject cache_control markers for providers that need them. */
  caching?: 'auto' | false;
  /** Provider priority order. */
  order?: string[];
  /** Restrict to these providers only. */
  only?: string[];
  /** Fallback model list tried in order. */
  models?: string[];
  /** Per-provider or global timeout (ms, clamped 1s–120s). */
  timeout?: number | Record<string, number>;
  /** Smart routing hint. 'quality' auto-enables RSA. */
  optimize?: 'cost' | 'latency' | 'quality';
  /** Disable response cache for this request. */
  cache?: boolean;
  /** Enable or configure router-managed web search for chat completions. */
  webSearch?: boolean | {
    provider?: SearchProvider;
    engine?: 'native' | 'exa' | 'parallel' | 'firecrawl';
    maxResults?: number;
    searchPrompt?: string;
    includeDomains?: string[];
    excludeDomains?: string[];
    searchRecency?: SearchRecency;
  };
  /**
   * RSA / MoA: population-based quality amplification.
   * Spawns N parallel calls, aggregates K at a time, refines over T rounds.
   * Add `models` for Mixture-of-Agents (diverse models per slot).
   */
  rsa?: {
    n?: number;
    k?: number;
    t?: number;
    /** MoA: diverse models for generation (round-robin). Aggregation uses primary model. */
    models?: string[];
  };
  /**
   * Best-of-N: generate N candidates, score, return the winner.
   * Scorer: webhook (your HTTP endpoint) or llm (LLM-as-judge).
   */
  bestOfN?: {
    n?: number;
    /** Diverse models for generation (round-robin). */
    models?: string[];
    scorer: {
      type: 'webhook';
      url: string;
      timeout?: number;
    } | {
      type: 'llm';
      model: string;
      prompt: string;
    };
  };
}
/**
 * Bridge options — route a single chat call through the Tangle Router's
 * cli-bridge short-circuit. The bridge drives subscription-backed CLIs
 * (Claude Code, Codex, Kimi Code, opencode) as OpenAI-compatible
 * harnesses with persistent session resume.
 *
 * When `bridge` is set, the client:
 *   1. Rewrites `model` to `bridge/<harness>/<model>` (or `bridge/<harness>`
 *      if no model is given — uses the harness default)
 *   2. Injects `X-Bridge-Unlock` with the caller's unlock token
 *   3. Injects `X-Resume` so follow-up calls with the same id resume
 *      the CLI's native session (no re-tokenizing prior turns)
 *   4. Optionally injects BYOB headers `X-Bridge-Url` + `X-Bridge-Bearer`
 *      if the caller wants to target their own cli-bridge instance
 *      (requires the router to be deployed with CLI_BRIDGE_BYOB_ENABLED)
 */
interface BridgeOptions {
  /** Which harness to drive. Picks the backend on the bridge. */
  harness: 'claude-code' | 'claudish' | 'codex' | 'opencode' | 'kimi-code' | 'sandbox' | 'openai' | 'anthropic' | 'moonshot' | 'zai';
  /** Model id inside the harness (e.g. `sonnet`, `kimi-for-coding`, `gpt-5-codex`). Omit for harness default. */
  model?: string;
  /** Router-issued unlock token. Required for router-mediated bridge calls; unused by direct cli-bridge clients. */
  unlock?: string;
  /** Stable caller-owned id for session resume. Map one id per logical conversation. */
  resume?: string;
  /** BYOB: point at your own cli-bridge instance. Router must have BYOB enabled. */
  bridgeUrl?: string;
  /** BYOB: bearer your cli-bridge expects. */
  bridgeBearer?: string;
}
interface SandboxChatOptions {
  /** Inline sandbox AgentProfile. Serialized as cli-bridge/sandbox-api `agent_profile`. */
  agentProfile?: AgentProfile;
  /** Direct sandbox or cli-bridge session id. Serialized as `session_id`. */
  sessionId?: string;
}
interface ChatOptions {
  /** Cancel transport, response-body reads and retry waits. Never serialized. */
  signal?: AbortSignal;
  /** Model to use */
  model?: string;
  /** Messages */
  messages: ChatMessage[];
  /** Temperature (0-2) */
  temperature?: number;
  /** Max tokens to generate */
  maxTokens?: number;
  /** Stream response */
  stream?: boolean;
  /** Stop sequences */
  stop?: string | string[];
  /** Top-p sampling */
  topP?: number;
  /** Frequency penalty */
  frequencyPenalty?: number;
  /** Presence penalty */
  presencePenalty?: number;
  /** JSON mode */
  responseFormat?: {
    type: 'text' | 'json_object';
  };
  /** Tools / function calling */
  tools?: any[];
  /** Tool choice strategy or specific tool */
  toolChoice?: 'none' | 'auto' | 'required' | {
    type: 'function';
    function: {
      name: string;
    };
  };
  /** OpenRouter-compatible plugins, e.g. `[{ id: 'web', max_results: 5 }]`. */
  plugins?: ChatPlugin[];
  /** Shorthand for `gateway.webSearch`; explicit `gateway.webSearch` wins when both are set. */
  webSearch?: GatewayOptions['webSearch'];
  /**
   * Gateway options: routing, compliance, inference strategies (RSA/MoA/Best-of-N).
   * Sent as `body.gateway` to the Router.
   */
  gateway?: GatewayOptions;
  /**
   * Provider-specific parameters passed through to the upstream API.
   * Protected OpenAI/Tangle fields cannot be overridden from this escape hatch.
   * Example: `{ thinking: { type: 'enabled', budget_tokens: 8000 } }`
   */
  providerOptions?: Record<string, unknown>;
  /**
   * Typed sandbox/cli-bridge extensions. Use this instead of smuggling
   * `agent_profile` or `session_id` through providerOptions.
   */
  sandbox?: SandboxChatOptions;
  /**
   * Route this call through the Tangle Router's cli-bridge short-circuit.
   * See {@link BridgeOptions}. When set, `model` is rewritten to
   * `bridge/<harness>/<model>` and bridge headers are injected.
   */
  bridge?: BridgeOptions;
}
interface ChatCompletion {
  /** SDK receipt for this response only. Absent when cost is only guessed. */
  tangle?: {
    costUsd: number;
    costSource: 'receipt' | 'rates';
  };
  id: string;
  object: string;
  created: number;
  model: string;
  choices: {
    index: number;
    message: ChatMessage;
    finish_reason: string;
  }[];
  usage?: {
    prompt_tokens: number;
    completion_tokens: number;
    total_tokens: number;
    billed_cost?: number;
    cost?: number;
  };
}
interface ChatCompletionChunk {
  id: string;
  object: string;
  created: number;
  model: string;
  choices: {
    index: number;
    delta: Partial<ChatMessage>;
    finish_reason: string | null;
  }[];
}
interface Model {
  id: string;
  name: string;
  description?: string;
  context_length: number;
  pricing: {
    prompt: string;
    completion: string;
  };
  _provider?: string;
  architecture?: {
    input_modalities?: string[];
    output_modalities?: string[];
  };
}
interface Operator {
  id: string;
  slug: string;
  name: string;
  description?: string;
  status: string;
  endpointUrl: string;
  blueprintType: string;
  reputationScore: number;
  uptimePercent: number;
  avgLatencyMs: number;
  totalRequests: number;
  stakeTnt: number;
  /** GPU model name (e.g. "A100", "H100") */
  gpuModel?: string;
  /** Number of GPUs available */
  gpuCount?: number;
  /** Total VRAM across all GPUs in MiB */
  totalVramMib?: number;
  /** Whether this operator is TEE-attested */
  teeAttested?: boolean;
  /** TEE provider if attested (e.g. "aws_nitro") */
  teeProvider?: string;
  models: {
    modelId: string;
    inputPrice: number;
    outputPrice: number;
  }[];
}
interface CreditBalance {
  balance: number;
  transactions: {
    id: string;
    amount: number;
    type: string;
    description: string;
    createdAt: string;
  }[];
}
interface CreateKeyOptions {
  name: string;
  /** Explicit parent key ID. When omitted and calling with an API key,
   * the new key is auto-parented to the calling key. */
  parentKeyId?: string;
  product?: 'router' | 'sandbox' | 'evals' | 'blueprint-agent';
  projectId?: string;
  budgetUsd?: number;
  /** The parent's REMAINING budget, when known (e.g. from the verify
   *  response). When set, `budgetUsd` is derived within it — never above
   *  remaining, never below the platform minimum — instead of sending a
   *  flat default the platform would refuse. See deriveChildBudgetUsd. */
  parentBudgetRemainingUsd?: number;
  allowedModels?: string[];
  rpmLimit?: number;
  /** ISO 8601 datetime. Must be in the future. */
  expiresAt?: string;
}
interface CreatedKey {
  id: string;
  key: string;
  prefix: string;
  name: string;
  product: string | null;
  budgetUsd: number | null;
  budgetRemaining: number | null;
}
interface ApiKeyInfo {
  id: string;
  keyPrefix: string;
  name: string;
  parentKeyId: string | null;
  product: string | null;
  projectId: string | null;
  budgetUsd: number | null;
  budgetSpent: number;
  allowedModels: string[] | null;
  rpmLimit: number | null;
  expiresAt: string | null;
  lastUsedAt: string | null;
  revokedAt: string | null;
  createdAt: string;
}
interface UpdateKeyOptions {
  name?: string;
  budgetUsd?: number;
  allowedModels?: string[];
  rpmLimit?: number | null;
  expiresAt?: string | null;
}
/** Status event from an async job SSE stream */
interface JobEvent {
  status: 'queued' | 'processing' | 'completed' | 'failed' | 'cancelled';
  progress?: number;
  result?: Record<string, unknown>;
  error?: string;
  timestamp: number;
}
/** Options for watchJob() */
interface WatchJobOptions {
  /** Operator endpoint URL (if not using default routing) */
  operatorUrl?: string;
  /** Callback for each event (useful for progress tracking) */
  onEvent?: (event: JobEvent) => void;
  /** Timeout in ms (default: 5 minutes) */
  timeout?: number;
  /** Model to route to (for operator discovery) */
  model?: string;
  /** SSE bearer token (replaces API key for operator SSE auth) */
  sseToken?: string;
}
interface SpendAuth {
  commitment: string;
  serviceId: string;
  jobIndex: number;
  amount: string;
  operator: string;
  nonce: string;
  expiry: string;
  signature: string;
}
//#endregion
//#region src/private-router.d.ts
/**
 * Private Router — operator rotation strategies for privacy-preserving inference.
 *
 * Each strategy determines how requests are distributed across operators
 * to minimize the information any single operator can gather about a user's
 * conversation patterns.
 */
interface OperatorInfo {
  slug: string;
  endpointUrl: string;
  region: string;
  reputationScore: number;
  avgLatencyMs: number;
  models: string[];
}
type RoutingStrategy = 'round-robin' | 'random' | 'geo-distributed' | 'min-exposure' | 'latency-aware';
interface PrivateRouterConfig {
  strategy: RoutingStrategy;
  /** Max requests to same operator before forced rotation */
  maxRequestsPerOperator: number;
  /** Minimum number of distinct operators to use */
  minOperators: number;
  /** Region preferences (operators in these regions preferred) */
  preferRegions?: string[];
  /** Exclude specific operators */
  excludeOperators?: string[];
  /** Enable context summarization between operator switches (reduces info leakage) */
  summarizeOnSwitch: boolean;
}
declare class PrivateRouter {
  private config;
  private operators;
  private usage;
  private currentIndex;
  private totalRequests;
  /** Slug of the most-recently-selected operator. Populated on each selectOperator() hit. */
  private _lastSelectedSlug;
  constructor(config?: Partial<PrivateRouterConfig>);
  /** Set the available operator pool */
  setOperators(operators: OperatorInfo[]): void;
  /** Select the next operator for a request */
  selectOperator(model: string): OperatorInfo | null;
  /** Should we summarize context before this request? (operator is changing) */
  shouldSummarize(model: string): boolean;
  /** Get privacy stats */
  getStats(): {
    totalRequests: number;
    operatorsUsed: number;
    operatorBreakdown: {
      slug: string;
      requests: number;
      lastUsed: number;
    }[];
    strategy: RoutingStrategy;
  };
  private roundRobin;
  private random;
  private geoDistributed;
  private minExposure;
  private latencyAware;
  private recordUsage;
  /** Slug of the most-recently-selected operator (null before the first call). */
  get lastSelectedSlug(): string | null;
  private getLastUsedOperator;
  private peekNextOperator;
}
//#endregion
//#region src/decisions.d.ts
/**
 * Decision surfaces and key-scope utilities — the client half of the
 * router's decision-model features.
 *
 * Two wires, one job (structured judgment):
 *
 *  - **Decisions** (`POST /v1/decisions`) — OpenAI's native wire, served
 *    verbatim by Router: `input` + up to 200 typed questions
 *    (`predicate` / `choice` / `score`), answers in question order, any
 *    question may answer `refusal` instead. The request body passes through
 *    byte-for-byte (only `model` is rewritten upstream), so every OpenAI
 *    field — `prompt_cache_key`, `prompt_cache_options`, `safety_identifier`,
 *    item-array inputs — keeps native semantics. Use this surface when the
 *    caller is OpenAI-SDK-shaped.
 *
 *  - **System One** (`POST /v1/systemone`) — the fleet's decision wire
 *    (TypeSafe-originated; agent-eval's `systemone/protocol` owns the
 *    canonical contract): `state` + named `noul`/`score`/`choice` questions,
 *    answers keyed by name, strict validation, calibrated profiles. OpenAI's
 *    row is served through a translation; per-question refusals fail the
 *    whole evaluation rather than silently answering fewer questions. Use
 *    this surface for judges and policy machinery.
 *
 * Both carry the router rails: durable idempotent replay, `X-Tangle-Max-Cost-USD`
 * limits, and `X-Tangle-Cost-USD` receipts. Billing is input-only at the
 * row's reviewed rate (the spec's own example bills `output_tokens: 0`).
 */
/** A typed question. `instructions` is required by the API. */
type DecisionQuestion = {
  type: 'predicate';
  name?: string;
  instructions: string;
} | {
  type: 'choice';
  name?: string;
  instructions: string;
  choices: Array<{
    value: string | boolean;
    description?: string;
  }>;
} | {
  type: 'score';
  name?: string;
  instructions: string;
  levels: Array<{
    label: string;
    description?: string;
  }>;
};
/** One answer per question, in order; any question may answer refusal instead. */
type DecisionAnswer = {
  type: 'predicate';
  name: string | null;
  probability: number;
} | {
  type: 'choice';
  name: string | null;
  choice: string | boolean;
  probabilities: Array<{
    value: string | boolean;
    probability: number;
  }>;
  confidence: number;
} | {
  type: 'score';
  name: string | null;
  score: number;
  probabilities: Array<{
    value: number;
    label: string;
    probability: number;
  }>;
  confidence: number;
} | {
  type: 'refusal';
  name: string | null;
};
interface DecisionUsage {
  input_tokens: number;
  input_tokens_details?: {
    cached_tokens: number;
    cache_write_tokens: number;
  };
  output_tokens: number;
  output_tokens_details?: {
    reasoning_tokens: number;
  };
  total_tokens: number;
}
/** `POST /v1/decisions` request. Extra OpenAI fields ride along verbatim. */
interface DecisionCreateOptions {
  model: string;
  input: string | ReadonlyArray<Record<string, unknown>>;
  questions: ReadonlyArray<DecisionQuestion>;
  /** Opaque caller-scoped end-user identifier (≤128 chars). */
  safetyIdentifier?: string;
  /** Partition prompt-cache reuse by caller key (≤64 chars). */
  promptCacheKey?: string;
  /** Retry safety: identical key + body replays the settled outcome. */
  idempotencyKey?: string;
  /** Per-call cost ceiling (USD); the router refuses above it (402). */
  maxCostUsd?: number;
  signal?: AbortSignal;
}
interface DecisionResponse {
  model: string;
  answers: DecisionAnswer[];
  usage: DecisionUsage;
}
/** Cost + identity receipts from the router, beside the answer. */
interface DecisionReceipts {
  generationId: string | null;
  servedModel: string | null;
  costUsd: number | null;
  providerCostUsd: number | null;
  maxCostUsd: number | null;
  replayed: boolean;
}
interface DecisionResult {
  decision: DecisionResponse;
  receipts: DecisionReceipts;
}
type SystemOneState = string | Record<string, unknown> | ReadonlyArray<unknown>;
type SystemOneQuestion = {
  type: 'noul';
  instructions?: string | SystemOneState | null;
  criteria?: {
    true?: string | SystemOneState | null;
    false?: string | SystemOneState | null;
  } | null;
} | {
  type: 'score';
  instructions?: string | SystemOneState | null;
  criteria: ReadonlyArray<string | SystemOneState>;
} | {
  type: 'choice';
  instructions?: string | SystemOneState | null;
  criteria: Record<string, string | SystemOneState | null>;
};
type SystemOneAnswer = {
  type: 'noul';
  noul: number;
} | {
  type: 'score';
  score: number;
  confidence: number;
  legend: Record<string, unknown>;
  probabilities: Record<string, number>;
} | {
  type: 'choice';
  choice: string;
  confidence: number;
  probabilities: Record<string, number>;
};
interface SystemOneEvaluateOptions {
  /** A System One row id or bare id (e.g. `openai/gpt-6-luna`, `jev-1.13.0`). */
  model: string;
  state: SystemOneState;
  questions: Record<string, SystemOneQuestion>;
  idempotencyKey?: string;
  maxCostUsd?: number;
  signal?: AbortSignal;
}
interface SystemOneResultBody {
  model: string;
  answers: Record<string, SystemOneAnswer>;
  usage: {
    input_tokens: number;
    output_tokens: number;
  };
}
interface SystemOneResult {
  result: SystemOneResultBody;
  receipts: DecisionReceipts;
}
interface KeyScopeInfo {
  /** The key's model allow-list, or null when the key is unscoped. A scoped
   *  caller routes within this set BEFORE its first refusal. */
  allowedModels: string[] | null;
  limit: number | null;
  limitRemaining: number | null;
  limitReset: 'monthly' | null;
  rateLimitRequests: number | null;
  expiresAt: string | null;
}
/** Parse the allowed-model set out of a router `model_not_allowed` refusal —
 *  both refusal shapes name it after `Allowed:`. Null when the message
 *  carries no set (an unexpected shape; do not guess). */
declare function parseModelNotAllowed(message: string): string[] | null;
type ModelWithinAllowListResolution = {
  status: 'allowed';
  model: string;
  rerouted: false;
} | {
  status: 'rerouted';
  model: string;
  rerouted: true;
  blockedModel: string;
} | {
  status: 'refused';
  model: null;
  allowedModels: readonly string[];
};
/** Resolve a model request against a key's allow-list: unscoped or permitted
 *  → allowed; a permitted fallback → rerouted (the blocked model named);
 *  nothing permitted → refused with the set (fail loud, never silently
 *  downgrade — a different model is a different decision-maker). */
declare function resolveModelWithinAllowList(input: {
  requested: string;
  allowedModels?: readonly string[] | null;
  fallbacks?: readonly string[];
}): ModelWithinAllowListResolution;
/** The loud, correctable refusal: blocked model, allowed set, the fix. */
declare function formatModelNotAllowedRefusal(input: {
  requested: string;
  allowedModels: readonly string[];
}): string;
declare const MIN_CHILD_KEY_BUDGET_USD = 0.5;
/** The source key is exhausted — correctable, both numbers on the error. */
declare class ParentBudgetExhaustedError extends Error {
  readonly requestedUsd: number;
  readonly parentRemainingUsd: number;
  constructor(requestedUsd: number, parentRemainingUsd: number);
}
/** Derive a child key's budget ask from the parent's remaining budget:
 *  unknown parent → the configured ask stands; exhausted → correctable
 *  error before any mint; otherwise max(min, min(requested, floor-to-cents
 *  remaining)). Never above a known remaining, never below the platform
 *  minimum. */
declare function deriveChildBudgetUsd(input: {
  requestedUsd: number;
  parentRemainingUsd?: number | null;
  minChildUsd?: number;
}): number;
//#endregion
//#region src/client.d.ts
/** Rotation knobs for {@link TCloudClient.rotating}. */
interface RotatingRoutingConfig {
  /** Router strategy. Defaults to `'min-exposure'`. */
  strategy?: Extract<RoutingStrategy, 'min-exposure' | 'round-robin' | 'random'>;
  /**
   * Pre-seed the operator pool. When omitted the client fetches
   * `/api/operators` on the first call (TTL-cached).
   */
  pool?: OperatorInfo[];
  /** Minimum distinct operators required before routing proceeds. */
  minOperators?: number;
  /** Max requests per operator before forced rotation. */
  maxRequestsPerOperator?: number;
  /** Exclude specific operator slugs. */
  excludeOperators?: string[];
  /** Prefer specific regions (others kept as fallback). */
  preferRegions?: string[];
}
/** Configuration accepted by {@link TCloudClient.rotating}. */
type RotatingClientConfig = Omit<TCloudConfig, 'routing'> & {
  routing?: RotatingRoutingConfig;
};
/** Rotation stats surfaced by {@link TCloudClient.getRotationStats}. */
interface RotationStats {
  /** Per-operator call counter. */
  callsByOperator: Record<string, number>;
  /** Slug of the most-recently-selected operator, if any. */
  currentOperator: string | null;
}
declare class TCloudClient {
  readonly baseURL: string;
  readonly platformURL: string;
  readonly apiKey?: string;
  readonly model: string;
  private headers;
  private spendAuthFn?;
  private privacy?;
  private limits?;
  private retryConfig;
  private timeoutMs;
  private _totalSpent;
  private _requestCount;
  readonly privateRouter?: PrivateRouter;
  private _cachedOperators;
  private _operatorsCachedAt;
  private static readonly OPERATORS_TTL_MS;
  /**
   * Build a client pointed directly at a cli-bridge instance — skips the
   * Tangle Router entirely. cli-bridge serves the OpenAI-compatible
   * `/v1/chat/completions` endpoint natively, so chat() / ask() /
   * chatStream() work as-is against any local or remote bridge.
   *
   * Use this when you have your own cli-bridge running (locally or on
   * your own VPS) and don't need router-side gating, billing, or
   * observability — your CLI subscriptions on the bridge box pay for
   * the LLM tokens directly.
   *
   * Wire form: model id is `<harness>/<model>` (e.g. `claude-code/sonnet`,
   * `kimi-code/kimi-for-coding`) — no `bridge/` prefix needed in direct
   * mode; cli-bridge accepts the harness id as the first path segment.
   *
   * ```ts
   * const client = TCloudClient.fromCliBridge({
   *   url: 'http://127.0.0.1:3344',
   *   bearer: process.env.CLI_BRIDGE_BEARER!,
   * })
   * const reply = await client.ask('explain X', 'claude-code/sonnet')
   * ```
   *
   * For session-resumable agentic dispatches, use `client.bridge(...)` on
   * the returned direct client. `resume` is serialized to cli-bridge's
   * `session_id` body field and the model wire format stays
   * `<harness>/<model>` without the router-only `bridge/` prefix.
   */
  static fromCliBridge(opts: {
    /** cli-bridge base URL — `http://127.0.0.1:3344` for default local; can be any reachable URL. */
    url: string;
    /** BRIDGE_BEARER from the cli-bridge's `.env.local`. */
    bearer: string;
    /** Optional config passthrough (timeout, retry, etc). */
    config?: Omit<TCloudConfig, 'apiKey' | 'baseURL'>;
  }): TCloudClient;
  /**
   * Build a client that rotates which operator serves each call. Mirrors
   * {@link TCloudClient.shielded} in shape: returns a standard `TCloudClient`
   * that behaves identically for the OpenAI-compatible surface but
   * dispatches each chat/completions/embeddings request through a
   * {@link PrivateRouter} — different operator per call per the chosen
   * strategy.
   *
   * ```ts
   * const tcloud = TCloudClient.rotating({
   *   apiKey: process.env.TANGLE_API_KEY,
   *   routing: { strategy: 'min-exposure' },
   * })
   * await tcloud.ask('hello')
   * tcloud.getRotationStats() // { callsByOperator: { ... }, currentOperator: '…' }
   * ```
   *
   * Rotation is meaningful only for stateless calls. Sandbox-harness
   * sessions bind to a single operator for the lifetime of the session;
   * `rotating()` clients refuse to dispatch them — see {@link bridge}.
   */
  static rotating(config?: RotatingClientConfig): TCloudClient;
  constructor(config?: TCloudConfig);
  /** Set the SpendAuth signer for private mode */
  setSpendAuthSigner(fn: () => Promise<SpendAuth>): void;
  /** Current metering stats */
  get usage(): {
    totalSpent: number;
    requestCount: number;
    limits: {
      maxCostPerRequest?: number;
      maxTotalSpend?: number;
      maxRequests?: number;
      onLimitWarning?: (info: {
        type: 'cost' | 'total' | 'requests';
        current: number;
        limit: number;
      }) => void;
      onLimitReached?: (info: {
        type: 'cost' | 'total' | 'requests';
        current: number;
        limit: number;
      }) => void;
    } | undefined;
  };
  /** Check spending limits before a request. Throws TCloudError if blocked. */
  private checkLimits;
  /** Ensure the private router has operators loaded (with TTL-based caching) */
  private ensureRouterOperators;
  /** Track cost after a response, using actual pricing from response headers when available */
  private trackCost;
  /**
   * Core fetch with retry + timeout. All helpers build on this.
   * Retries on retryable status codes with exponential backoff + jitter.
   */
  private _doFetch;
  /**
   * Shared request helper for billable calls that keep the Response (the
   * decision surfaces read cost/identity receipts off its headers).
   */
  private _requestWithResponse;
  /**
   * Shared request helper for billable JSON API calls.
   * Enforces: checkLimits → fetch with retry/timeout → error parsing → requestCount.
   */
  private _request;
  /**
   * Shared request helper for read-only/non-billable JSON API calls.
   * No limits check, no request counting.
   */
  private _fetch;
  /**
   * Shared request helper for billable calls that return non-JSON (e.g. ArrayBuffer).
   */
  private _requestRaw;
  /**
   * Prepare headers for chat requests — operator routing + SpendAuth +
   * bridge short-circuit headers when `options.bridge` is set.
   * Shared between chat() and chatStream() to eliminate duplication.
   */
  private _prepareChatRequest;
  /**
   * Resolve the effective model string. When a bridge is set, rewrite to
   * `bridge/<harness>/<model>` (or `bridge/<harness>` if no model).
   */
  private _effectiveModel;
  /** Build the chat completions request body */
  private _chatBody;
  /** Chat completion (non-streaming) */
  chat(options: ChatOptions): Promise<ChatCompletion>;
  /** Chat completion (streaming) — returns an async iterator of chunks */
  chatStream(options: ChatOptions): AsyncGenerator<ChatCompletionChunk>;
  /**
   * Bridge — scoped helper for a subscription-backed CLI harness behind
   * the Tangle Router's cli-bridge. Returns a mini-client bound to
   * (harness, unlock, resume) so you don't thread those through every
   * call.
   *
   * ```ts
   * const kimi = tcloud.bridge({ harness: 'kimi-code', model: 'kimi-for-coding', unlock: UNLOCK, resume: 'pr-42' })
   * await kimi.ask('review this diff…')
   * for await (const chunk of kimi.stream('continue…')) process.stdout.write(chunk)
   * ```
   *
   * Sessions persist across process restarts — use the same `resume` id
   * to land on the same CLI conversation (context intact, no replay tax).
   *
   * Guard: clients built via {@link TCloudClient.rotating} cannot dispatch
   * sandbox-harness sessions (rotation rotates per call; a sandbox session
   * binds to one operator). Attempting `bridge({ harness: 'sandbox' })` on
   * a rotating client throws.
   */
  bridge(cfg: BridgeOptions): BridgeSession;
  private _isDirectCliBridge;
  /**
   * Rotation stats — populated only on clients created via
   * {@link TCloudClient.rotating}. Non-rotating clients return an empty
   * counter and `currentOperator: null`.
   */
  getRotationStats(): RotationStats;
  /** Convenience: send a single message and get the text response */
  ask(message: string, modelOrOptions?: string | Partial<ChatOptions>): Promise<string>;
  /** Convenience: send a single message and get the full completion (with usage) */
  askFull(message: string, modelOrOptions?: string | Partial<ChatOptions>): Promise<ChatCompletion>;
  /** Convenience: stream a single message and yield text chunks */
  askStream(message: string, modelOrOptions?: string | Partial<ChatOptions>): AsyncGenerator<string>;
  /** List available models */
  models(): Promise<Model[]>;
  /** List active operators */
  operators(): Promise<{
    operators: Operator[];
    stats: any;
  }>;
  /** Get credit balance */
  credits(): Promise<CreditBalance>;
  /** Add credits via Stripe checkout. Returns the checkout URL. */
  addCredits(amount: number): Promise<{
    url: string;
  }>;
  /** Get transaction history */
  transactions(limit?: number): Promise<{
    id: string;
    amount: number;
    type: string;
    product: string | null;
    description: string | null;
    createdAt: string;
  }[]>;
  /**
   * Create a new API key.
   * When called with an API key (not session), the new key is automatically
   * a child of the calling key — enabling hierarchical key delegation.
   *
   * Pass `parentKeyId` explicitly to create a child of a specific key.
   * Child keys inherit the parent's product scope, allowedModels, and rpmLimit
   * if not specified. Budget cannot exceed the parent's remaining budget.
   */
  /** The OpenAI Decisions wire, natively: `client.decisions.create(...)`. */
  readonly decisions: {
    create: (options: DecisionCreateOptions) => Promise<DecisionResult>;
  };
  private _decisionsCreate;
  /** The System One wire (fleet judges): state + named questions, answers by name. */
  systemone(options: SystemOneEvaluateOptions): Promise<SystemOneResult>;
  /**
   * This key's own scope, live: `GET /v1/key` — the allow-list in its
   * positive form (null = unscoped), budgets, rate limit, expiry. Scoped
   * callers route within `allowedModels` BEFORE a first refusal.
   */
  keyInfo(): Promise<KeyScopeInfo>;
  private _allowedModelsCache;
  private static readonly ALLOWED_MODELS_TTL_MS;
  /**
   * The key's model allow-list (null when unscoped), cached five minutes.
   * `refresh: true` forces a re-read — key rotations and allow-list edits
   * land here first.
   */
  allowedModels(options?: {
    refresh?: boolean;
  }): Promise<string[] | null>;
  /**
   * Resolve a model request against this key's allow-list (live, cached):
   * permitted → `{status:'allowed'}`; a permitted fallback → rerouted with
   * the blocked model named; nothing permitted → refused carrying the set —
   * never a silent downgrade. Throws nothing; callers surface `refused`
   * with `formatModelNotAllowedRefusal`.
   */
  resolveModel(requested: string, options?: {
    fallbacks?: readonly string[];
    refresh?: boolean;
  }): Promise<ModelWithinAllowListResolution>;
  createKey(opts: CreateKeyOptions): Promise<CreatedKey>;
  /** Get a single API key by ID */
  getKey(id: string): Promise<ApiKeyInfo>;
  /**
   * List API keys.
   * Pass `children: true` to list child keys of the calling API key.
   */
  keys(opts?: {
    children?: boolean;
  }): Promise<ApiKeyInfo[]>;
  /**
   * Update an API key's limits.
   * Can adjust budget, allowedModels, rpmLimit, expiresAt, and name.
   */
  updateKey(id: string, updates: UpdateKeyOptions): Promise<ApiKeyInfo>;
  /** Revoke an API key. If the key has children, they are also revoked recursively. */
  revokeKey(id: string): Promise<void>;
  /** Rotate an API key — creates new key with same config, revokes old */
  rotateKey(id: string): Promise<{
    newKey: CreatedKey;
    revokedKeyId: string;
  }>;
  /** Create a project for usage attribution */
  createProject(name: string, product?: string): Promise<{
    id: string;
    name: string;
  }>;
  /** List projects */
  projects(): Promise<{
    id: string;
    name: string;
    product: string | null;
    createdAt: string;
  }[]>;
  /** Generate embeddings */
  embeddings(options: EmbeddingOptions): Promise<EmbeddingResponse>;
  /** Generate images */
  imageGenerate(options: ImageGenerateOptions): Promise<ImageResponse>;
  /**
   * Edit / inpaint / variate an existing image with a text prompt.
   * Sibling to `imageGenerate`; routes to `/v1/images/edits` via
   * multipart/form-data per the OpenAI spec.
   *
   * Reference image attachments may be passed as `Blob`, `ArrayBuffer`,
   * or `{data: base64, mediaType, filename?}`. Multi-image composition
   * (e.g. gpt-image-2 with two reference frames + a prompt that fuses
   * them) is supported by passing an array; for legacy models only the
   * first image is honored upstream.
   */
  imagesEdit(options: ImageEditOptions): Promise<ImageResponse>;
  /** Rerank documents by relevance to a query */
  rerank(options: RerankOptions): Promise<RerankResponse>;
  /** Search the web through Tangle Router billing and provider routing. */
  search(options: SearchOptions): Promise<SearchResponse>;
  /** Run a multi-step deep-research task through Tangle Router billing and
   *  provider routing (POST /v1/research). Slower and costlier than `search` —
   *  the provider synthesizes an answer over many fetches. Pick depth with
   *  `effort` (provider-specific vocabulary; see {@link ResearchOptions.effort}). */
  research(options: ResearchOptions): Promise<ResearchResponse>;
  /** Text-to-speech */
  speech(options: {
    model?: string;
    input: string;
    voice?: string;
  }): Promise<ArrayBuffer>;
  /** Legacy completions endpoint */
  completions(options: CompletionOptions): Promise<CompletionResponse>;
  /** Audio transcription (speech-to-text) */
  transcribe(file: Blob, options?: {
    model?: string;
    language?: string;
    prompt?: string;
  }): Promise<TranscriptionResponse>;
  /** Create a fine-tuning job */
  fineTuneCreate(options: FineTuningJobOptions): Promise<FineTuningJob>;
  /** List fine-tuning jobs */
  fineTuneList(): Promise<{
    data: FineTuningJob[];
  }>;
  /** Submit a batch of chat requests */
  batch(requests: BatchRequest[]): Promise<BatchJobResponse>;
  /** Get batch job status */
  batchStatus(jobId: string): Promise<BatchJobResponse>;
  /** Generate video */
  videoGenerate(options: VideoGenerateOptions): Promise<VideoResponse>;
  /** Get video generation status */
  videoStatus(id: string): Promise<VideoResponse>;
  /** Generate an avatar video (lip-synced talking head from audio + face image).
   *  Returns 202 with a job_id for async polling via avatarJobStatus(). */
  avatarGenerate(options: AvatarGenerateRequest): Promise<AvatarGenerateResponse>;
  /** Poll an avatar generation job by ID. */
  avatarJobStatus(jobId: string): Promise<AvatarJobStatus>;
  /** Poll an avatar job until it reaches a terminal state (completed/failed).
   *  Returns the final job status. Throws on failure. */
  pollAvatarJob(jobId: string, options?: {
    intervalMs?: number;
    timeoutMs?: number;
  }): Promise<AvatarJobStatus>;
  /**
   * Watch an async job via SSE until it reaches a terminal state.
   * Works with avatar, video, and training blueprint operators.
   *
   * @param jobId - The job ID returned by the creation endpoint
   * @param options - Optional: operatorUrl override, onEvent callback
   * @returns The final JobEvent (completed/failed/cancelled)
   */
  watchJob(jobId: string, options?: WatchJobOptions): Promise<JobEvent>;
  /** Create a vector collection on the operator's vector store */
  createCollection(options: {
    name: string;
    dimensions: number;
    distance_metric?: string;
  }): Promise<any>;
  /** List collections on the operator's vector store */
  listCollections(): Promise<any>;
  /** Upsert vectors into a collection */
  upsertVectors(collection: string, vectors: Array<{
    id: string;
    vector: number[];
    metadata?: Record<string, any>;
  }>): Promise<any>;
  /** Similarity search in a collection */
  queryVectors(collection: string, options: {
    vector: number[];
    top_k?: number;
    filter?: Record<string, any>;
  }): Promise<any>;
  /** RAG query — embed text + search collection in one call */
  ragQuery(options: {
    query: string;
    collection: string;
    top_k?: number;
    embedding_model?: string;
  }): Promise<any>;
  /** Search models by name, provider, or capability */
  searchModels(query: string): Promise<Model[]>;
  /** Estimate cost for a request (without sending it) */
  estimateCost(options: {
    model?: string;
    inputTokens: number;
    outputTokens: number;
  }): Promise<{
    inputCost: number;
    outputCost: number;
    total: number;
  }>;
  /**
   * Get a pricing spectrum across resource tiers for a model.
   *
   * Uses REAL per-operator pricing from `operator.models[].inputPrice`.
   * Each tier filters operators by GPU count and TEE capability, then
   * reports the cheapest and most expensive operator for that config.
   *
   * @param options.model - Model ID to price (falls back to client default)
   * @param options.tiers - Number of tiers (1-7, default 5)
   */
  pricingSpectrum(options: {
    model?: string;
    tiers?: number;
  }): Promise<PricingTier[]>;
  private get _apiRoot();
  eval(opts: {
    models: string[];
    scenarios: Array<{
      id: string;
      prompt: string;
      rubric?: string;
      category?: string;
      expectedContains?: string[];
      maxLatencyMs?: number;
    }>;
    judge?: string;
    iterations?: number;
    systemPrompt?: string;
  }): Promise<{
    results: Array<{
      model: string;
      summary: any;
      scenarios: any[];
    }>;
  }>;
  createSuite(opts: {
    name: string;
    scenarios: Array<{
      id: string;
      prompt: string;
      rubric?: string;
    }>;
    models: string[];
    judge?: string;
    iterations?: number;
    tags?: string[];
  }): Promise<{
    suite: {
      id: string;
      name: string;
    };
  }>;
  listSuites(): Promise<{
    suites: Array<{
      id: string;
      name: string;
      models: string[];
    }>;
  }>;
  runSuite(suiteId: string, opts?: {
    baseline?: boolean;
    concurrency?: number;
  }): Promise<any>;
  listRuns(suiteId: string): Promise<any>;
  getRun(runId: string): Promise<any>;
  setBaseline(runId: string): Promise<void>;
  sandboxPricing(opts?: {
    cpu?: number;
    ram?: number;
    disk?: number;
  }): Promise<{
    pricing: {
      hourlyRate: number;
      perMinuteRate: number;
    };
    plan: string;
    limits: {
      maxCpu: number;
      maxRamGb: number;
      maxDiskGb: number;
    };
    balance: number;
    canAfford: {
      minutes: number;
      hours: number;
    };
  }>;
  sandboxStatus(): Promise<{
    linked: boolean;
    keyPrefix?: string;
    gatewayUrl?: string;
  }>;
  sandboxProvision(): Promise<{
    provisioned: boolean;
    minutesRemaining?: number;
  }>;
  sandboxCreate(opts: {
    model?: string;
    harness?: 'claude-code' | 'codex' | 'opencode' | 'amp' | 'factory';
    cpu?: number;
    ram?: number;
    storage?: number;
    gitUrl?: string;
    systemPrompt?: string;
  }): Promise<{
    sessionId: string;
    harness: string;
    model: string;
    minutesRemaining?: number;
  }>;
  sandboxList(): Promise<{
    sessions: Array<{
      id: string;
      status: string;
      model: string;
      harness: string;
    }>;
  }>;
  sandboxStats(sandboxId: string): Promise<{
    config: {
      cpu: number;
      ramGb: number;
      diskGb: number;
    };
    uptime: number;
    computeMinutes: number;
    live?: {
      cpuPercent: number;
      memoryUsedMb: number;
      memoryTotalMb: number;
    };
  }>;
  sandboxDestroy(sessionId: string): Promise<{
    deleted: boolean;
  }>;
  userInfo(): Promise<{
    user: {
      id: string;
      email: string;
      name?: string;
    };
    balance: number;
    subscription: {
      plan: string;
      status: string;
    } | null;
    usage: Record<string, {
      cost: number;
      count: number;
    }>;
  }>;
}
/** Select N evenly-spaced items, always including first and last. */
/**
 * BridgeSession — a chat client scoped to one bridge configuration.
 *
 * Instead of threading `{ harness, unlock, resume }` through every
 * `chat()` call, create a session once and call `ask` / `stream` / `chat`
 * on it. The session's `resume` id is stable across calls so follow-up
 * turns land on the same CLI conversation.
 *
 * ```ts
 * const tcloud = new TCloudClient({ apiKey, baseURL: 'https://router.tangle.tools/api' })
 * const kimi = tcloud.bridge({ harness: 'kimi-code', model: 'kimi-for-coding', unlock: UNLOCK, resume: 'pr-42' })
 *
 * // one-shot
 * const reply = await kimi.ask('summarize this diff')
 *
 * // streaming
 * for await (const chunk of kimi.stream('continue…')) process.stdout.write(chunk)
 *
 * // full OpenAI-shaped request
 * const completion = await kimi.chat({ messages, temperature: 0.2 })
 *
 * // new resume id for a different logical conversation
 * const kimiOther = kimi.withResume('ticket-123')
 * ```
 */
declare class BridgeSession {
  private readonly client;
  private readonly cfg;
  private readonly direct;
  constructor(client: TCloudClient, cfg: BridgeOptions, direct?: boolean);
  /** Full chat completion (non-streaming). */
  chat(options: Omit<ChatOptions, 'bridge'>): Promise<ChatCompletion>;
  /** Stream OpenAI chat.completion.chunks. */
  chatStream(options: Omit<ChatOptions, 'bridge'>): AsyncGenerator<ChatCompletionChunk>;
  /** One-shot: send a string, get the assistant text. */
  ask(message: string, extra?: Omit<Partial<ChatOptions>, 'bridge' | 'messages'>): Promise<string>;
  /** One-shot: send a string, stream text deltas. */
  stream(message: string, extra?: Omit<Partial<ChatOptions>, 'bridge' | 'messages'>): AsyncGenerator<string>;
  /** Turn-based: send full message history, get assistant text. */
  turn(messages: ChatMessage[], extra?: Omit<Partial<ChatOptions>, 'bridge' | 'messages'>): Promise<string>;
  /** Clone with a new resume id — same harness, different logical conversation. */
  withResume(resume: string): BridgeSession;
  /** Clone with a different model inside the same harness. */
  withModel(model: string): BridgeSession;
  /** The effective model id that will land on the router (`bridge/<harness>/<model>`). */
  get model(): string;
  /** The resume id currently bound to this session, if any. */
  get resume(): string | undefined;
}
interface TierConfig {
  name: string;
  cpu: number;
  ramGb: number;
  gpu: number;
  tee: boolean;
}
interface PricingTier {
  tier: string;
  config: TierConfig;
  /** Raw cheapest per-input-token price (for programmatic use) */
  cheapestPrice?: number;
  /** Raw priciest per-input-token price (undefined if same as cheapest) */
  priciestPrice?: number;
  /** Formatted cheapest price */
  cheapest: string;
  /** Formatted priciest price (undefined if only one price point) */
  priciest?: string;
  /** Operators matching GPU/TEE requirements */
  availableOperators: number;
  /** Operators that also serve the requested model at a listed price */
  operatorsWithModel: number;
}
declare class TCloudError extends Error {
  status: number;
  constructor(status: number, message: string);
}
//#endregion
export { EmbeddingResponse as $, OperatorInfo as A, UpdateKeyOptions as At, BatchRequest as B, SystemOneResult as C, SearchRecency as Ct, formatModelNotAllowedRefusal as D, SpendingLimits as Dt, deriveChildBudgetUsd as E, SpendAuth as Et, AvatarGenerateRequest as F, ChatOptions as G, ChatCompletion as H, AvatarGenerateResponse as I, CompletionResponse as J, ChatPlugin as K, AvatarJobStatus as L, PrivateRouterConfig as M, VideoResponse as Mt, RoutingStrategy as N, WatchJobOptions as Nt, parseModelNotAllowed as O, TCloudConfig as Ot, ApiKeyInfo as P, WebSearchPlugin as Pt, EmbeddingOptions as Q, AvatarResult as R, SystemOneQuestion as S, SearchProvider as St, SystemOneState as T, ShieldedConfig as Tt, ChatCompletionChunk as U, BridgeOptions as V, ChatMessage as W, CreatedKey as X, CreateKeyOptions as Y, CreditBalance as Z, MIN_CHILD_KEY_BUDGET_USD as _, RetryConfig as _t, RotationStats as a, ImageGenerateOptions as at, SystemOneAnswer as b, SearchHit as bt, TierConfig as c, Model as ct, DecisionQuestion as d, RerankOptions as dt, FineTuningJob as et, DecisionReceipts as f, RerankResponse as ft, KeyScopeInfo as g, ResearchResponse as gt, DecisionUsage as h, ResearchProvider as ht, RotatingRoutingConfig as i, ImageEditOptions as it, PrivateRouter as j, VideoGenerateOptions as jt, resolveModelWithinAllowList as k, TranscriptionResponse as kt, DecisionAnswer as l, Operator as lt, DecisionResult as m, ResearchOptions as mt, PricingTier as n, GatewayOptions as nt, TCloudClient as o, ImageResponse as ot, DecisionResponse as p, ResearchHit as pt, CompletionOptions as q, RotatingClientConfig as r, ImageEditAttachment as rt, TCloudError as s, JobEvent as st, BridgeSession as t, FineTuningJobOptions as tt, DecisionCreateOptions as u, PrivacyConfig as ut, ModelWithinAllowListResolution as v, RoutingConfig as vt, SystemOneResultBody as w, SearchResponse as wt, SystemOneEvaluateOptions as x, SearchOptions as xt, ParentBudgetExhaustedError as y, SandboxChatOptions as yt, BatchJobResponse as z };