import { O as Agent } from "./agent-tool-types-BC-WFlsz.js";
import {
  ClientParameters,
  Method,
  RPCMethod,
  SerializableReturnValue,
  SerializableValue
} from "./serializable.js";
import {
  PartyFetchOptions,
  PartySocket,
  PartySocketOptions
} from "partysocket";

//#region src/client.d.ts
declare class AgentConnectionError extends Error {
  code: number;
  reason: string;
  wasClean: boolean;
  constructor(event: CloseEvent);
}
declare function isTerminalCloseEvent(event: CloseEvent): boolean;
type TerminalReconnectOptions = {
  shouldReconnectOnClose?: (event: CloseEvent) => boolean;
};
/**
 * Options for creating an AgentClient
 */
type AgentClientOptions<State = unknown> = Omit<
  PartySocketOptions,
  "party" | "room"
> &
  TerminalReconnectOptions & {
    /** Name of the agent to connect to (ignored if basePath is set) */ agent: string /** Name of the specific Agent instance (ignored if basePath is set) */;
    name?: string;
    /**
     * Full URL path - bypasses agent/name URL construction.
     * When set, the client connects to this path directly.
     * Server must handle routing manually (e.g., with getAgentByName + fetch).
     * @example
     * // Client connects to /user, server routes based on session
     * useAgent({ agent: "UserAgent", basePath: "user" })
     */
    basePath?: string /** Called when the Agent's state is updated */;
    onStateUpdate?: (
      state: State,
      source: "server" | "client"
    ) => void /** Called when a state update fails (e.g., connection is readonly) */;
    onStateUpdateError?: (error: string) => void;
    /**
     * Called when the server sends the agent's identity on connect.
     * Useful when using basePath, as the actual instance name is determined server-side.
     * @param name The actual agent instance name
     * @param agent The agent class name (kebab-case)
     */
    onIdentity?: (name: string, agent: string) => void;
    /**
     * Called when identity changes on reconnect (different instance than before).
     * If not provided and identity changes, a warning will be logged.
     * @param oldName Previous instance name
     * @param newName New instance name
     * @param oldAgent Previous agent class name
     * @param newAgent New agent class name
     */
    onIdentityChange?: (
      oldName: string,
      newName: string,
      oldAgent: string,
      newAgent: string
    ) => void;
    /**
     * Additional path to append to the URL.
     * Works with both standard routing and basePath.
     * @example
     * // With basePath: /user/settings
     * { basePath: "user", path: "settings" }
     * // Standard: /agents/my-agent/room/settings
     * { agent: "MyAgent", name: "room", path: "settings" }
     */
    path?: string;
    /**
     * Default timeout (in milliseconds) applied to non-streaming `call()`s
     * that don't pass an explicit `timeout`. Defaults to 30 000 ms.
     * Set to `0` to disable. Streaming calls never get a default timeout.
     */
    defaultCallTimeout?: number /** Called when the connection closes with a terminal code and will not reconnect. */;
    onConnectionError?: (error: AgentConnectionError) => void;
  };
/**
 * Default timeout (in milliseconds) applied to non-streaming RPC calls
 * that don't pass an explicit `timeout`. Acts as a backstop so calls
 * whose response is lost (e.g. the connection drops mid-flight) reject
 * instead of hanging forever. Override per client via
 * `defaultCallTimeout`, or per call via `timeout` (0 disables).
 */
declare const DEFAULT_CALL_TIMEOUT_MS = 30000;
/**
 * Options for streaming RPC calls
 */
type StreamOptions = {
  /** Called when a chunk of data is received */ onChunk?: (
    chunk: unknown
  ) => void /** Called when the stream ends */;
  onDone?: (finalChunk: unknown) => void /** Called when an error occurs */;
  onError?: (error: string) => void;
};
/**
 * Options for RPC calls
 */
type CallOptions = {
  /** Timeout in milliseconds. If the call doesn't complete within this time, it will be rejected. */ timeout?: number /** Streaming options for handling streaming responses */;
  stream?: StreamOptions;
};
/**
 * Options for the agentFetch function
 */
type AgentClientFetchOptions = Omit<PartyFetchOptions, "party" | "room"> & {
  /** Name of the agent to connect to (ignored if basePath is set) */ agent: string /** Name of the specific Agent instance (ignored if basePath is set) */;
  name?: string;
  /**
   * Full URL path - bypasses agent/name URL construction.
   * When set, the request is made to this path directly.
   */
  basePath?: string;
};
type AllOptional<T> = T extends [infer A, ...infer R]
  ? undefined extends A
    ? AllOptional<R>
    : false
  : true;
type RPCMethods<T> = {
  [K in keyof T as T[K] extends RPCMethod<T[K]> ? K : never]: RPCMethod<T[K]>;
};
type OptionalParametersMethod<T extends RPCMethod> =
  AllOptional<ClientParameters<T>> extends true ? T : never;
type AgentMethods<T> = Omit<RPCMethods<T>, keyof Agent<any, any>>;
type OptionalAgentMethods<T> = {
  [K in keyof AgentMethods<T> as AgentMethods<T>[K] extends OptionalParametersMethod<
    AgentMethods<T>[K]
  >
    ? K
    : never]: OptionalParametersMethod<AgentMethods<T>[K]>;
};
type RequiredAgentMethods<T> = Omit<
  AgentMethods<T>,
  keyof OptionalAgentMethods<T>
>;
type AgentPromiseReturnType<T, K extends keyof AgentMethods<T>> =
  ReturnType<AgentMethods<T>[K]> extends Promise<any>
    ? ReturnType<AgentMethods<T>[K]>
    : Promise<ReturnType<AgentMethods<T>[K]>>;
type AgentStub<T> = {
  [K in keyof AgentMethods<T>]: (
    ...args: ClientParameters<AgentMethods<T>[K]>
  ) => AgentPromiseReturnType<AgentMethods<T>, K>;
};
type UntypedAgentStub = Record<string, Method>;
type AgentClientStub<AgentT> = keyof AgentMethods<AgentT> extends never
  ? UntypedAgentStub
  : AgentStub<AgentT>;
type OptionalArgsAgentClientCall<AgentT> = <
  K extends keyof OptionalAgentMethods<AgentT>
>(
  method: K,
  args?: ClientParameters<OptionalAgentMethods<AgentT>[K]>,
  options?: CallOptions | StreamOptions
) => AgentPromiseReturnType<AgentT, K>;
type RequiredArgsAgentClientCall<AgentT> = <
  K extends keyof RequiredAgentMethods<AgentT>
>(
  method: K,
  args: ClientParameters<RequiredAgentMethods<AgentT>[K]>,
  options?: CallOptions | StreamOptions
) => AgentPromiseReturnType<AgentT, K>;
type TypedAgentClientCall<AgentT> = OptionalArgsAgentClientCall<AgentT> &
  RequiredArgsAgentClientCall<AgentT>;
type UntypedAgentClientCall = {
  <T extends SerializableReturnValue>(
    method: string,
    args?: SerializableValue[],
    options?: CallOptions | StreamOptions
  ): Promise<T>;
  <T = unknown>(
    method: string,
    args?: unknown[],
    options?: CallOptions | StreamOptions
  ): Promise<T>;
};
type AgentClientCall<AgentT> = keyof AgentMethods<AgentT> extends never
  ? UntypedAgentClientCall
  : TypedAgentClientCall<AgentT>;
/**
 * Creates a proxy that wraps RPC method calls.
 * Internal JS methods (toJSON, then, etc.) return undefined to avoid
 * triggering RPC calls during serialization (e.g., console.log)
 */
declare function createStubProxy<T = Record<string, Method>>(
  call: (method: string, args: unknown[]) => unknown
): T;
/**
 * WebSocket client for connecting to an Agent
 */
declare class AgentClient<
  AgentT = unknown,
  State = AgentT extends {
    get state(): infer S;
  }
    ? S
    : AgentT
> extends PartySocket {
  /**
   * @deprecated Use agentFetch instead
   */
  static fetch(_opts: PartyFetchOptions): Promise<Response>;
  agent: string;
  name: string;
  call: AgentClientCall<AgentT>;
  stub: AgentClientStub<AgentT>;
  /**
   * The current agent state, updated on server broadcasts and client setState calls.
   * Starts as undefined until the first state message is received from the server.
   */
  state: State | undefined;
  /**
   * Whether the client has received identity from the server.
   * Becomes true after the first identity message is received.
   * Resets to false on connection close.
   */
  identified: boolean;
  /**
   * Terminal connection error, if the server closed the socket with a code
   * that should not be retried automatically.
   */
  connectionError: AgentConnectionError | null;
  /**
   * Promise that resolves when identity has been received from the server.
   * Useful for waiting before making calls that depend on knowing the instance.
   * Resets on connection close so it can be awaited again after reconnect.
   */
  get ready(): Promise<void>;
  private options;
  private _pendingCalls;
  private _readyPromise;
  private _resolveReady;
  private _previousName;
  private _previousAgent;
  private _resetReady;
  constructor(options: AgentClientOptions<State>);
  /**
   * Reject pending RPC calls with the given reason.
   * With `onlyTransmitted`, calls still sitting in the send buffer are
   * kept pending (they'll be flushed on reconnect).
   */
  private _rejectPendingCalls;
  setState(state: State): void;
  /**
   * Close the connection and immediately reject all pending RPC calls.
   * This provides immediate feedback on intentional close rather than
   * waiting for the WebSocket close handshake to complete.
   *
   * Note: Any calls made after `close()` will be rejected when the
   * underlying WebSocket close event fires.
   */
  close(code?: number, reason?: string): void;
  /**
   * Call a method on the Agent.
   * When AgentT is provided, method names are inferred from the agent's methods.
   * Falls back to untyped string-based calls when AgentT is not provided.
   */
  private _callImpl;
}
/**
 * Make an HTTP request to an Agent
 * @param opts Connection options
 * @param init Request initialization options
 * @returns Promise resolving to a Response
 */
declare function agentFetch(
  opts: AgentClientFetchOptions,
  init?: RequestInit
): Promise<Response>;
//#endregion
export {
  AgentClient,
  AgentClientFetchOptions,
  AgentClientOptions,
  AgentConnectionError,
  AgentMethods,
  AgentPromiseReturnType,
  AgentStub,
  CallOptions,
  DEFAULT_CALL_TIMEOUT_MS,
  OptionalAgentMethods,
  RPCMethods,
  RequiredAgentMethods,
  StreamOptions,
  UntypedAgentStub,
  agentFetch,
  createStubProxy,
  isTerminalCloseEvent
};
//# sourceMappingURL=client.d.ts.map
