Skip to content

fix(active-memory): preserve setup time outside recall timeout#72620

Merged
Takhoffman merged 1 commit into
openclaw:mainfrom
hyspacex:fix/active-memory-timeout-72606
Apr 28, 2026
Merged

fix(active-memory): preserve setup time outside recall timeout#72620
Takhoffman merged 1 commit into
openclaw:mainfrom
hyspacex:fix/active-memory-timeout-72606

Conversation

@hyspacex

Copy link
Copy Markdown
Contributor

Summary

  • keep Active Memory's configured timeoutMs scoped to the embedded recall/model run
  • add a plugin-level setup grace window so embedded-run initialization does not consume the recall timeout budget before the LLM call starts
  • cover the regression where wrapper/setup time exceeds timeoutMs but the recall itself still succeeds

Fixes #72606

Testing

  • pnpm exec vitest run extensions/active-memory/index.test.ts
  • pnpm exec oxfmt --check extensions/active-memory/index.ts extensions/active-memory/index.test.ts
  • git diff --check

@greptile-apps

greptile-apps Bot commented Apr 27, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a regression where active-memory's setup/initialization overhead consumed the user-configured timeoutMs budget before the embedded model call even started. The fix widens the watchdog AbortController to timeoutMs + setupGraceTimeoutMs (default 30 s) while leaving runEmbeddedPiAgent called with the original configured timeoutMs, so the LLM always gets its full timeout slice. Existing tests pin the new grace value to 0 to stay valid, and a dedicated new test confirms the intended behavior.

Confidence Score: 4/5

Safe to merge; the only finding is a minor observability inconsistency in the abort error message.

No logic bugs or security issues found. The single comment is P2 (the abort message now reports the watchdog time rather than the user-configured timeout, which could confuse operators). P2-only findings cap confidence at 4/5.

extensions/active-memory/index.ts — abort message wording (line 1792)

Prompt To Fix All With AI
This is a comment left during a code review.
Path: extensions/active-memory/index.ts
Line: 1792

Comment:
**Abort message shows watchdog time, not configured timeout**

The error embedded in the abort signal now reports `watchdogTimeoutMs` (configured `timeoutMs` + 30 s grace), while the `start` log just above (line 1784) reports the user-facing `params.config.timeoutMs`. An operator seeing the abort message "active-memory timeout after 30010ms" for a plugin configured with `timeoutMs: 10` may be confused about which value to tune.

Consider keeping the configured timeout in the message and mentioning the watchdog separately:

```suggestion
    controller.abort(new Error(`active-memory timeout after ${params.config.timeoutMs}ms (watchdog ${watchdogTimeoutMs}ms)`));
```

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "fix(active-memory): preserve setup time ..." | Re-trigger Greptile

const timeoutId = setTimeout(() => {
controller.abort(new Error(`active-memory timeout after ${params.config.timeoutMs}ms`));
}, params.config.timeoutMs);
controller.abort(new Error(`active-memory timeout after ${watchdogTimeoutMs}ms`));

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.

P2 Abort message shows watchdog time, not configured timeout

The error embedded in the abort signal now reports watchdogTimeoutMs (configured timeoutMs + 30 s grace), while the start log just above (line 1784) reports the user-facing params.config.timeoutMs. An operator seeing the abort message "active-memory timeout after 30010ms" for a plugin configured with timeoutMs: 10 may be confused about which value to tune.

Consider keeping the configured timeout in the message and mentioning the watchdog separately:

Suggested change
controller.abort(new Error(`active-memory timeout after ${watchdogTimeoutMs}ms`));
controller.abort(new Error(`active-memory timeout after ${params.config.timeoutMs}ms (watchdog ${watchdogTimeoutMs}ms)`));
Prompt To Fix With AI
This is a comment left during a code review.
Path: extensions/active-memory/index.ts
Line: 1792

Comment:
**Abort message shows watchdog time, not configured timeout**

The error embedded in the abort signal now reports `watchdogTimeoutMs` (configured `timeoutMs` + 30 s grace), while the `start` log just above (line 1784) reports the user-facing `params.config.timeoutMs`. An operator seeing the abort message "active-memory timeout after 30010ms" for a plugin configured with `timeoutMs: 10` may be confused about which value to tune.

Consider keeping the configured timeout in the message and mentioning the watchdog separately:

```suggestion
    controller.abort(new Error(`active-memory timeout after ${params.config.timeoutMs}ms (watchdog ${watchdogTimeoutMs}ms)`));
```

How can I resolve this? If you propose a fix, please make it concise.

@clawsweeper

clawsweeper Bot commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

Codex review: keeping this open for maintainer follow-up; there is still a little grit to resolve.

Keep this PR open. Current main still does not implement the PR's intended fix: Active Memory starts its outer abort watchdog at hook entry using the configured model timeoutMs, passes that same timeout into runEmbeddedPiAgent, and has no per-registration hook timeout support. The PR remains an active implementation candidate for the linked Active Memory timeout bug rather than cleanup-closeable.

Best possible solution:

Keep this PR open for maintainer review. The best path is to revise or land the PR so Active Memory preserves the configured timeoutMs for the embedded model run, gives setup/hook execution a bounded separate budget, updates public plugin hook docs/API contract checks if { timeoutMs } is accepted, and resolves the abort-message wording before merge.

What I checked:

  • Current Active Memory watchdog still starts at plugin scope: maybeResolveActiveRecall creates an AbortController and aborts after exactly params.config.timeoutMs, so setup/wrapper time is still inside the same wall-clock budget reported in the linked bug. (extensions/active-memory/index.ts:2188, f256eeba431b)
  • Embedded recall receives the same configured model timeout: The embedded Active Memory run is called with timeoutMs: params.config.timeoutMs, so current main has no separate setup grace or outer watchdog budget around embedded-run initialization. (extensions/active-memory/index.ts:2065, f256eeba431b)
  • Active Memory hook has no per-hook timeout on main: The plugin registers before_prompt_build with only the hook name and handler. The public OpenClawPluginApi.on type and registry registration options also accept only priority, not timeoutMs. (extensions/active-memory/index.ts:2431, f256eeba431b)
  • Core hook runner still applies the 15s before_prompt_build default without per-registration override: Current main defines before_prompt_build: 15_000 in DEFAULT_MODIFYING_HOOK_TIMEOUT_MS_BY_HOOK, and getModifyingHookTimeoutMs reads only the hook-name default. Commit d55c7ea introduced that default after the linked issue was opened. (src/plugins/hooks.ts:181, d55c7ea997c0)
  • Current tests still pin the old hard-deadline behavior: The Active Memory test suite currently expects the hook to return near timeoutMs even when the subagent blocks for 30 seconds. The PR patch adds a new regression test for setup grace instead. (extensions/active-memory/index.test.ts:2137, f256eeba431b)
  • PR head targets the missing behavior: The latest PR patch adds setupGraceTimeoutMs, changes the Active Memory watchdog to timeoutMs + setupGraceTimeoutMs, registers before_prompt_build with a 150s timeout budget, adds timeoutMs to hook registrations/API plumbing, and adds hook-runner timeout tests. (extensions/active-memory/index.ts, 4203f288fcba)

Remaining risk / open question:

  • The PR expands the public plugin hook registration contract with api.on(..., { timeoutMs }), but current plugin docs only document priority; maintainers should decide and document whether third-party plugins may extend hook-runner latency.
  • The PR still reports the watchdog timeout in the Active Memory abort message (timeoutMs + setupGraceTimeoutMs), matching Greptile's observability concern that operators may confuse it with the configured model timeout.
  • Per-registration hook timeouts appear normalized only as positive finite numbers with no upper bound in the PR patch, so maintainers should confirm that is acceptable for fail-open hook latency and plugin policy.

Codex review notes: model gpt-5.5, reasoning high; reviewed against f256eeba431b.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Active Memory timeoutMs clock starts at plugin level, not at LLM call — embedded run setup overhead causes 100% timeout

2 participants