Repository: TabbyML/tabby
File: clients/tabby-agent/src/http/tabbyApiClient.ts (TypeScript)

Code before:
  }

  isChatApiAvailable(): boolean {
    const health = this.serverHealth;
    return !!(health && health["chat_model"]);
  }

  async connect(options: { reset?: boolean } = {}): Promise<void> {
    if (options.reset) {
      this.reset();
    }
    await this.healthCheck();
    if (this.status === "ready") {
      await this.updateServerProvidedConfig();
      await this.anonymousUsageLogger.uniqueEvent("AgentConnected", this.serverHealth);
    }
  }

  private async healthCheck(
    options: { signal?: AbortSignal; method?: "GET" | "POST"; background?: boolean } = {
      method: "GET",
      background: false,
    },
  ): Promise<void> {
    const { signal, method, background } = options;
    if (this.healthCheckMutexAbortController && !this.healthCheckMutexAbortController.signal.aborted && background) {
      // if background check true, and there is a running check, ignore background check
      if (background) {
        return;
      }
      this.healthCheckMutexAbortController.abort(new MutexAbortError());
    }
    const abortController = new AbortController();
    this.healthCheckMutexAbortController = abortController;
    this.updateIsConnecting(true);

    const requestId = uuid();
    const requestPath = "/v1/health";
    const requestDescription = `${method} ${this.endpoint + requestPath}`;
    const requestOptions = {
      signal: abortSignalFromAnyOf([signal, abortController.signal, this.createTimeOutAbortSignal()]),
    };
    try {
      if (!this.api) {
        throw new Error("http client not initialized");
      }
      this.logger.debug(`Health check request: ${requestDescription}. [${requestId}]`);
      let response;
      if (method === "POST") {
        response = await this.api.POST(requestPath, requestOptions);
      } else {

Review comment (suggestion):
```suggestion
    if (this.healthCheckMutexAbortController && !this.healthCheckMutexAbortController.signal.aborted) {
```

Code after:

  isChatApiAvailable(): boolean {
    const health = this.serverHealth;
    return !!(health && health["chat_model"]);
  }

  async connect(options: { reset?: boolean } = {}): Promise<void> {
    if (options.reset) {
      this.reset();
    }
    await this.healthCheck();
    if (this.status === "ready") {
      await this.updateServerProvidedConfig();
      await this.anonymousUsageLogger.uniqueEvent("AgentConnected", this.serverHealth);
    }
  }

  private async healthCheck(
    options: { signal?: AbortSignal; method?: "GET" | "POST"; background?: boolean } = {
      method: "GET",
      background: false,
    },
  ): Promise<void> {
    const { signal, method, background } = options;
    if (this.healthCheckMutexAbortController && !this.healthCheckMutexAbortController.signal.aborted) {
      // if background check true, and there is a running check, ignore background check
      if (background) {
        return;
      }

      this.healthCheckMutexAbortController.abort(new MutexAbortError());
    }
    const abortController = new AbortController();
    this.healthCheckMutexAbortController = abortController;
    this.updateIsConnecting(true);

    const requestId = uuid();
    const requestPath = "/v1/health";
    const requestDescription = `${method} ${this.endpoint + requestPath}`;
    const requestOptions = {
      signal: abortSignalFromAnyOf([signal, abortController.signal, this.createTimeOutAbortSignal()]),
    };
    try {
      if (!this.api) {
        throw new Error("http client not initialized");
      }
      this.logger.debug(`Health check request: ${requestDescription}. [${requestId}]`);
      let response;
      if (method === "POST") {
        response = await this.api.POST(requestPath, requestOptions);
      } else {