// src/errors.ts
var AgentSDKError = class extends Error {
  /** @internal Marker for cross-bundle identity checks */
  _agentSDKError = true;
  /** Machine-readable error code. Prefer values from the ErrorCode enum. */
  code;
  /** Whether this error is safe to retry */
  retryable;
  /** HTTP status code hint for error classification */
  httpStatus;
  constructor(message, options) {
    super(message, options);
    this.name = "AgentSDKError";
    this.code = options?.code;
    this.retryable = options?.retryable ?? false;
    this.httpStatus = options?.httpStatus;
  }
  /** Check if an error is an AgentSDKError (works across bundled copies) */
  static is(error) {
    return error instanceof Error && "_agentSDKError" in error && error._agentSDKError === true;
  }
};

// src/chat/errors.ts
var ChatError = class extends AgentSDKError {
  code;
  retryable;
  retryAfter;
  timestamp;
  constructor(message, options) {
    super(message, {
      cause: options.cause,
      code: options.code,
      retryable: options.retryable
    });
    this.name = "ChatError";
    this.code = options.code;
    this.retryable = options.retryable ?? false;
    this.retryAfter = options.retryAfter;
    this.timestamp = (/* @__PURE__ */ new Date()).toISOString();
  }
};

// src/chat/state.ts
var StateMachine = class {
  constructor(initial, transitions) {
    this.initial = initial;
    this.transitions = transitions;
    this._current = initial;
  }
  _current;
  /** Current state */
  get current() {
    return this._current;
  }
  /**
   * Check whether transitioning to `next` is allowed from current state
   * @param next - Target state to check
   * @returns True if transition is allowed
   */
  canTransition(next) {
    const allowed = this.transitions[this._current];
    return allowed !== void 0 && allowed.includes(next);
  }
  /**
   * Transition to `next` state.
   * @throws ChatError(INVALID_TRANSITION) if the transition is not allowed
   */
  transition(next) {
    if (!this.canTransition(next)) {
      throw new ChatError(
        `Invalid transition: ${this._current} \u2192 ${next}`,
        { code: "INVALID_TRANSITION" /* INVALID_TRANSITION */ }
      );
    }
    this._current = next;
  }
  /** Reset to initial state */
  reset() {
    this._current = this.initial;
  }
};
var RUNTIME_TRANSITIONS = {
  idle: ["streaming", "disposed"],
  streaming: ["idle", "error", "disposed"],
  error: ["idle", "disposed"],
  disposed: []
};
var MESSAGE_TRANSITIONS = {
  pending: ["streaming", "error", "cancelled"],
  streaming: ["complete", "error", "cancelled"],
  complete: [],
  error: [],
  cancelled: []
};
var TOOL_CALL_TRANSITIONS = {
  pending: ["running", "requires_approval", "error"],
  running: ["complete", "error"],
  requires_approval: ["running", "denied", "error"],
  complete: [],
  error: [],
  denied: []
};
function createRuntimeStateMachine() {
  return new StateMachine("idle", RUNTIME_TRANSITIONS);
}
function createMessageStateMachine() {
  return new StateMachine("pending", MESSAGE_TRANSITIONS);
}
function createToolCallStateMachine() {
  return new StateMachine("pending", TOOL_CALL_TRANSITIONS);
}
var ChatReentrancyGuard = class {
  _acquired = false;
  /** Whether the guard is currently held */
  get isAcquired() {
    return this._acquired;
  }
  /**
   * Acquire the guard. Throws if already acquired.
   * @throws ChatError with code REENTRANCY
   */
  acquire() {
    if (this._acquired) {
      throw new ChatError(
        "Concurrent operation detected: a send is already in progress",
        { code: "REENTRANCY" /* REENTRANCY */ }
      );
    }
    this._acquired = true;
  }
  /** Release the guard. Safe to call even if not acquired. */
  release() {
    this._acquired = false;
  }
};
var ChatAbortController = class {
  _controller;
  _onExternalAbort;
  _externalSignal;
  constructor(externalSignal) {
    this._controller = new AbortController();
    this._externalSignal = externalSignal;
    if (externalSignal) {
      if (externalSignal.aborted) {
        this._controller.abort(externalSignal.reason);
      } else {
        this._onExternalAbort = () => {
          this._controller.abort(externalSignal.reason);
        };
        externalSignal.addEventListener("abort", this._onExternalAbort, { once: true });
      }
    }
  }
  /** The AbortSignal for this controller */
  get signal() {
    return this._controller.signal;
  }
  /** Whether the operation has been aborted */
  get isAborted() {
    return this._controller.signal.aborted;
  }
  /**
   * Abort the operation.
   * @param reason - Optional abort reason
   */
  abort(reason) {
    this._controller.abort(reason);
  }
  /** Clean up external signal listener to prevent memory leaks */
  dispose() {
    if (this._onExternalAbort && this._externalSignal) {
      this._externalSignal.removeEventListener("abort", this._onExternalAbort);
    }
  }
};

export { ChatAbortController, ChatReentrancyGuard, MESSAGE_TRANSITIONS, RUNTIME_TRANSITIONS, StateMachine, TOOL_CALL_TRANSITIONS, createMessageStateMachine, createRuntimeStateMachine, createToolCallStateMachine };
//# sourceMappingURL=state.js.map
//# sourceMappingURL=state.js.map