Skip to content

fix(daemon): increase default API timeout to 120s for heartbeat reliability#1979

Open
AnwarPy wants to merge 7 commits intomultica-ai:mainfrom
AnwarPy:fix/daemon-api-timeout-heartbeat
Open

fix(daemon): increase default API timeout to 120s for heartbeat reliability#1979
AnwarPy wants to merge 7 commits intomultica-ai:mainfrom
AnwarPy:fix/daemon-api-timeout-heartbeat

Conversation

@AnwarPy
Copy link
Copy Markdown

@AnwarPy AnwarPy commented May 1, 2026

Problem

The daemon heartbeat endpoint (POST /api/daemon/heartbeat) can take 12-24 seconds under normal load, and with network variance sometimes exceeds 60 seconds. The original hardcoded 30-second HTTP client timeout in NewClient() caused frequent context deadline exceeded errors, leading to unnecessary heartbeat failures.

Changes

  • config.go: DefaultAPITimeout increased from 60s to 120s
    • Also adds Config.APITimeout field, Overrides.APITimeout, and MULTICA_DAEMON_API_TIMEOUT env var support
  • client.go: Adds SetTimeout(d time.Duration) setter method
  • daemon.go: Applies configured timeout in New() after SetVersion()
  • client_test.go: Unit test for SetTimeout

Testing

  • Tested locally with 4 runtimes (claude, opencode, openclaw, hermes)
  • Before fix: heartbeat failures every 1-3 minutes (context deadline exceeded)
  • After fix (120s): zero heartbeat errors across 30+ minutes of operation
  • Users can override via MULTICA_DAEMON_API_TIMEOUT env var

Impact

  • Low risk: Only changes the HTTP client timeout default
  • The 120s value provides sufficient headroom for slow heartbeat responses without affecting normal operations
  • External callers retain the default 30s timeout (applied in NewClient())

Fixes #1637

@vercel
Copy link
Copy Markdown

vercel Bot commented May 1, 2026

Someone is attempting to deploy a commit to the IndexLabs Team on Vercel.

A member of the Team first needs to authorize it.

Anwar Anabtawi added 5 commits May 2, 2026 00:52
…a-ai#1637)

Issue: server /api/daemon/heartbeat takes 12-24s, exceeding the
hardcoded 30s HTTP client timeout in NewClient().

Changes:
- config.go: DefaultAPITimeout=60s, Config.APITimeout field,
  Overrides.APITimeout, env var MULTICA_DAEMON_API_TIMEOUT
- client.go: SetTimeout(d) setter method
- daemon.go: Apply timeout in New() after SetVersion()
- client_test.go: TestClient_SetTimeout unit test

Rebased on main v0.2.22 (374f62b).
…bility

Issue: The heartbeat endpoint can take 12-24s under load, and with
network variance sometimes exceeds 60s. The original 30s default
caused frequent 'context deadline exceeded' errors.

Changes:
- config.go: DefaultAPITimeout increased from 60s to 120s
- daemon.go: Add debug logging to confirm timeout is applied

Users can override via MULTICA_DAEMON_API_TIMEOUT env var.

Fixes multica-ai#1637
When the daemon is started with a minimal PATH (e.g., from a service
manager or Electron app), exec.LookPath("hermes") fails even though
the binary exists in common user locations.

Probes these fallback paths when MULTICA_HERMES_PATH is not set:
  1. ~/.local/bin/hermes
  2. ~/hermes-agent/.venv/bin/hermes

Fixes model discovery failure for Hermes Agent provider.
The hermes acp handshake (initialize + session/new) takes ~8s under
normal load. The previous 12s deadline was cutting it close, especially
when the system is under load or the LLM provider is slow to respond.

Bump to 20s to give ample headroom while still failing fast enough to
not block the UI indefinitely.
The ModelPicker and ModelDropdown components were gated behind
runtimeOnline, which meant any runtime that appeared offline would
silently show 'No models available' instead of attempting discovery.

The daemon may still be running and reachable via heartbeat even when
the UI marks it offline (transient heartbeat delay, cache staleness).

Change: always fire the model discovery query when a runtimeId exists.
A failed discovery will surface as an error instead of an empty list.
@AnwarPy AnwarPy force-pushed the fix/daemon-api-timeout-heartbeat branch from c9c65b4 to 326e228 Compare May 1, 2026 21:52
Anwar Anabtawi added 2 commits May 2, 2026 04:49
- apps/web/components.json: rtl: true
- apps/web/app/layout.tsx: lang=ar dir=rtl
- apps/desktop/src/renderer/index.html: lang=ar dir=rtl
- server/internal/middleware/csp.go: connect-src * wss: (allow LAN)

Note: Arabic i18n translations not yet added — RTL direction only.
- globals.css: row-reverse for resizable panels, force sidebar visibility
- issue-detail.tsx: ensure sidebar defaultLayout >= 20% (was collapsed)
- Dockerfile.web.rtl: helper Dockerfile for RTL builds
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Desktop daemon v0.2.16 heartbeat POSTs time out — /api/daemon/heartbeat takes 12–24s to respond

1 participant