Skip to content

fix: make CALL_TIMEOUT_MS env-overridable and raise HTTP worker default_timeout to 600 s#867

Open
kek-Sec wants to merge 2 commits into
rohitg00:mainfrom
kek-Sec:fix/866-configurable-call-timeout
Open

fix: make CALL_TIMEOUT_MS env-overridable and raise HTTP worker default_timeout to 600 s#867
kek-Sec wants to merge 2 commits into
rohitg00:mainfrom
kek-Sec:fix/866-configurable-call-timeout

Conversation

@kek-Sec

@kek-Sec kek-Sec commented Jun 9, 2026

Copy link
Copy Markdown

What

  • CALL_TIMEOUT_MS in src/mcp/rest-proxy.ts is now env-overridable via
    AGENTMEMORY_CALL_TIMEOUT_MS, with a default of 600 000 ms (was 15 000 ms).
    Mirrors the existing AGENTMEMORY_PROBE_TIMEOUT_MS pattern already in the
    same file.
  • iii-config.yaml default_timeout raised from 180 000 ms to 600 000 ms.
  • callTimeoutMs() is exported; test/mcp-call-timeout.test.ts covers the
    default value, env-var parsing, malformed-value fallback, and the abort
    behaviour under a hanging server response (9 new tests, all pass).

Why

On stores with 1 100+ semantic memories and 630+ insights,
memory_consolidate and memory_reflect reliably time out because the
proxy's HTTP client aborts the request after 15 s — before the server
finishes the LLM-backed operation.

Making the timeout env-overridable is a non-breaking improvement: users who
don't set the env var get the new 600 s default; anyone who needs a
different ceiling can set AGENTMEMORY_CALL_TIMEOUT_MS in their MCP server
env config.

Related to #655 (which addresses the server-side sequential KV bottleneck).
This addresses the client-side transport ceiling — both fixes are needed for
large stores to complete reliably.

How to verify

  1. Point the server at a large memory store (500+ semantic entries).
  2. Run memory_consolidate — it should complete instead of returning a
    timeout error.
  3. Set AGENTMEMORY_CALL_TIMEOUT_MS=5000 and confirm a small store still
    respects the override.
  4. npm test — the new suite at test/mcp-call-timeout.test.ts passes (9
    tests); no regressions in the existing suite.

Fixes #866

Summary by CodeRabbit

  • New Features

    • Increased HTTP worker default timeout to support longer-running operations (now 600s).
    • Proxied request timeout is now configurable and resilient to invalid values, with safe clamping to platform limits.
  • Tests

    • Added comprehensive tests validating timeout parsing, clamping, defaults, and proxy abort behavior.

…aults to 600 s

Hardcoded 15 s proxy timeout causes memory_consolidate and memory_reflect
to abort on large stores (1 100+ semantic memories, 630+ insights) before
the server finishes the LLM-backed operation.

- Replace CALL_TIMEOUT_MS = 15_000 with DEFAULT_CALL_TIMEOUT_MS = 600_000
  and a callTimeoutMs() helper (mirrors existing probeTimeoutMs() pattern)
  that reads AGENTMEMORY_CALL_TIMEOUT_MS from the environment so users can
  tune the ceiling without changing code.
- Raise iii-config.yaml default_timeout from 180 000 ms to 600 000 ms for
  the HTTP worker, keeping both ceilings in sync.
- Export callTimeoutMs() and add test/mcp-call-timeout.test.ts covering
  the default value, env-var parsing, malformed-value fallback, and the
  abort behaviour under a hanging server response.

Fixes rohitg00#866

Signed-off-by: George Petrakis <g.petrakis@natechbanking.com>
@vercel

vercel Bot commented Jun 9, 2026

Copy link
Copy Markdown

@kek-Sec is attempting to deploy a commit to the rohitg00's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Raise the MCP proxy default call timeout to 600000 ms, add exported callTimeoutMs() that reads and validates AGENTMEMORY_CALL_TIMEOUT_MS (floors floats, clamps to Node.js timer ceiling), use it with AbortSignal.timeout() for proxied fetch calls, update iii-http worker default_timeout, and add unit/integration tests for parsing and runtime behavior.

Changes

MCP Proxy Call Timeout Configuration

Layer / File(s) Summary
Call timeout configuration and helper
src/mcp/rest-proxy.ts
Introduce DEFAULT_CALL_TIMEOUT_MS (600_000) and export callTimeoutMs() that parses AGENTMEMORY_CALL_TIMEOUT_MS, validates positive finite numbers, floors floats, clamps to MAX_TIMER_MS, and falls back to the default.
Proxy timeout application and config update
src/mcp/rest-proxy.ts, iii-config.yaml, iii-config.docker.yaml
Use AbortSignal.timeout(callTimeoutMs()) for proxied MCP fetch calls and raise iii-http worker default_timeout from 180000 to 600000 in config files.
Timeout behavior test coverage
test/mcp-call-timeout.test.ts
Add Vitest unit tests for callTimeoutMs() (default, empty, integer/float parsing, zero/negative/malformed fallback, clamping at Node.js timer ceiling) and integration-style tests mocking fetch to verify abort-on-timeout and successful completion scenarios.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

I’m a rabbit with a stopwatch bright,
Fifteen seconds froze my hop in flight.
Now six hundred seconds stretch the race,
Env var helps me set the pace.
Hooray — long runs finish in warm light! 🐰⏱️

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the primary changes: making CALL_TIMEOUT_MS environment-overridable and raising HTTP worker timeout to 600 seconds.
Linked Issues check ✅ Passed All coding requirements from #866 are met: CALL_TIMEOUT_MS is env-overridable via AGENTMEMORY_CALL_TIMEOUT_MS with 600s default, iii-config files updated to 600s, helper function exports callTimeoutMs(), and comprehensive tests added.
Out of Scope Changes check ✅ Passed All changes are directly scoped to requirements in #866: timeout configuration updates, environment variable handling, and corresponding test coverage; no extraneous modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@iii-config.yaml`:
- Line 6: Update the Docker worker timeout to match the new default_timeout of
600000 by changing the timeout value in iii-config.docker.yaml from 180000 to
600000; locate the Docker-specific timeout setting (the default_timeout or
docker worker timeout key) in iii-config.docker.yaml and set it to 600000 so
Docker users use the same 600s ceiling as the main default_timeout.

In `@src/mcp/rest-proxy.ts`:
- Around line 13-18: callTimeoutMs() currently validates positive numeric input
but doesn't cap huge values; clamp the computed timeout to Node's safe maximum
timer value (2147483647 ms) before returning so values passed to
AbortSignal.timeout(...) (used later) won't be misinterpreted or immediately
fire. Update callTimeoutMs() to compute n = Math.floor(Number(raw)) as now, then
return Math.min(n, 2147483647) (falling back to DEFAULT_CALL_TIMEOUT_MS when
invalid) so timeouts are both positive and within the safe upper bound.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0fc4e594-d8ae-4cd5-b764-9c6b1ba71eb7

📥 Commits

Reviewing files that changed from the base of the PR and between 749c280 and 450b6e3.

📒 Files selected for processing (3)
  • iii-config.yaml
  • src/mcp/rest-proxy.ts
  • test/mcp-call-timeout.test.ts

Comment thread iii-config.yaml
Comment thread src/mcp/rest-proxy.ts
…e max

- iii-config.docker.yaml: raise default_timeout 180 000 → 600 000 to match
  iii-config.yaml (Docker users get the same ceiling as the default config)
- rest-proxy.ts: clamp AGENTMEMORY_CALL_TIMEOUT_MS to 2 147 483 647 ms
  (Node.js signed 32-bit timer ceiling); values above this wrap to negative
  and fire AbortSignal immediately
- test/mcp-call-timeout.test.ts: add two tests covering the clamp boundary

Signed-off-by: George Petrakis <g.petrakis@natechbanking.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
test/mcp-call-timeout.test.ts (1)

110-121: ⚡ Quick win

Consider asserting the specific error type for abort timeout.

The test currently uses a generic .rejects.toThrow() which passes for any error. Since AbortSignal.timeout() throws a specific DOMException with name "AbortError", consider asserting the error type to improve test precision and catch regressions more reliably.

✨ Proposed improvement
     await expect(
       handle.call("/agentmemory/smart-search", {
         method: "POST",
         body: JSON.stringify({ query: "test" }),
       }),
-    ).rejects.toThrow();
+    ).rejects.toThrow(/abort/i);

Or for even more precision:

-    ).rejects.toThrow();
+    ).rejects.toMatchObject({
+      name: "AbortError",
+    });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/mcp-call-timeout.test.ts` around lines 110 - 121, The test currently
uses a generic .rejects.toThrow() which accepts any error; update the assertion
to check for the specific abort error thrown by AbortSignal.timeout — assert
that the rejection is a DOMException/AbortError when calling
handle.call("/agentmemory/smart-search", ...) in the test named "aborts a proxy
call that hangs beyond the configured timeout" (or assert the error.name ===
"AbortError" / use toThrow with the AbortError constructor/message) so the test
only passes for the intended timeout abort.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@test/mcp-call-timeout.test.ts`:
- Around line 110-121: The test currently uses a generic .rejects.toThrow()
which accepts any error; update the assertion to check for the specific abort
error thrown by AbortSignal.timeout — assert that the rejection is a
DOMException/AbortError when calling handle.call("/agentmemory/smart-search",
...) in the test named "aborts a proxy call that hangs beyond the configured
timeout" (or assert the error.name === "AbortError" / use toThrow with the
AbortError constructor/message) so the test only passes for the intended timeout
abort.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7a27a95a-6a6b-40dd-bed3-f2017b8dca3b

📥 Commits

Reviewing files that changed from the base of the PR and between 450b6e3 and 6b1b780.

📒 Files selected for processing (3)
  • iii-config.docker.yaml
  • src/mcp/rest-proxy.ts
  • test/mcp-call-timeout.test.ts
✅ Files skipped from review due to trivial changes (1)
  • iii-config.docker.yaml
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/mcp/rest-proxy.ts

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.

fix: MCP proxy CALL_TIMEOUT_MS hardcoded at 15 s causes memory_consolidate / memory_reflect to abort on large stores

1 participant