Skip to content

feat(semantic-cache): runtime-configurable defaultTtl via __config hash #147

@KIvanow

Description

@KIvanow

Background

The feature/cache-proposal-data-model---libs-support branch added periodic refresh of two Valkey hashes so that BetterDB Monitor proposals take effect without a process restart:

  • {name}:__configSemanticCache threshold (global + per-category)
  • {name}:__tool_policiesAgentCache per-tool TTL

Both are now covered by the cache_propose_threshold_adjust and cache_propose_tool_ttl_adjust MCP tools.

Gap

SemanticCache.defaultTtl — how long stored entries live in Valkey — is not runtime-configurable. It is set at construction time and never re-read. If an operator wants to shorten or extend entry lifetime (for example, to reclaim memory under load, or to keep entries alive longer during a traffic spike), they currently need a code change and a deployment.

This is the most obvious missing piece given what's already in place: the __config hash, the refresh timer, and the Monitor proposal pipeline are all there. Adding a ttl field to the hash and a ttl_adjust proposal type is the natural extension.

Proposed change

Library (@betterdb/semantic-cache)

Read a ttl field from {name}:__config during each refreshConfig() tick:

threshold        → this.defaultThreshold   (already done)
threshold:{cat}  → this.categoryThresholds (already done)
ttl              → this.defaultTtl         (new)

Validation: must be a positive integer (seconds). Out-of-range or non-integer values are ignored and the constructor value is kept as fallback — same pattern as threshold.

Drop readonly from this.defaultTtl (mirrors what was done for defaultThreshold).

Capture this._initialDefaultTtl at construction as the fallback when the hash field is absent.

Monitor dispatcher (CacheApplyDispatcher)

Add a new applySemanticTtlAdjust path under proposal_type: 'ttl_adjust':

await client.hset(configKey, 'ttl', String(payload.new_ttl_seconds));

Monitor MCP tool

Register cache_propose_ttl_adjust:

cache_name      string  — the semantic cache to adjust
new_ttl_seconds int     — proposed TTL in seconds (min: 1, max: 604800 / 7 days)
reasoning       string  — ≥20 chars

Discovery marker

Add 'ttl_adjust' to the capabilities array in buildSemanticMetadata() (alongside the threshold_adjust added in this branch).

Acceptance criteria

  • refreshConfig() reads the ttl field and updates this.defaultTtl in-place
  • Constructor value is used as fallback when the field is absent from the hash
  • Values ≤ 0, non-integer, or non-finite are rejected silently (no throw)
  • CacheApplyDispatcher writes HSET {prefix}:__config ttl {value}
  • cache_propose_ttl_adjust MCP tool creates and queues a proposal
  • Discovery marker advertises ttl_adjust capability
  • Unit tests cover: field read, fallback, invalid values, timer propagation
  • examples/monitor-proposals/index.ts in @betterdb/semantic-cache is extended to demonstrate the TTL loop alongside the threshold loop

Out of scope

  • Per-category TTL overrides (threshold has per-category support; TTL does not need it for the first iteration)
  • Runtime TTL configuration for @betterdb/agent-cache (agent-cache TTL is already per-tool via __tool_policies; the AgentCacheOptions.defaultTtl has much lower operational value)
  • Retroactively updating TTL on already-stored entries (only affects new store() calls)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions