11506 Commits

Author SHA1 Message Date
Peter Steinberger
bc4e8d46d2 ci: make changed-scope diff resilient on pr reruns 2026-02-16 12:48:32 +01:00
Peter Steinberger
1b64548caf fix: serialize cron force-run persistence 2026-02-16 11:35:52 +01:00
Peter Steinberger
9a6f7c9b23 test: retry cron delivery temp cleanup on windows 2026-02-16 11:29:14 +01:00
Peter Steinberger
7a7f8e480c fix: restore CI command and memory status behavior 2026-02-16 11:22:24 +01:00
Peter Steinberger
dc7063af88 fix(ci): resolve adabot type-check regressions 2026-02-16 11:09:05 +01:00
Tarun Sukhani
6ff248fd4e memory-neo4j: task-aware memory filtering (3 layers)
Layer 1 — Recall-time filter (task-filter.ts):
- New module that reads TASKS.md completed tasks and filters recalled
  memories that match completed task IDs or keywords
- Integrated into auto-recall hook as Feature 3 (after score/dedup filters)
- 60-second cache to avoid re-parsing TASKS.md on every message
- 29 new tests

Layer 2 — Sleep cycle Phase 7 (task-memory cleanup):
- New phase cross-references completed tasks with stored memories
- LLM classifies each matched memory as 'lasting' (keep) or 'noise' (delete)
- Conservative: keeps memories on any doubt or LLM failure
- Scans only tasks completed within last 7 days
- New searchMemoriesByKeywords() method on neo4j client
- 16 new tests

Layer 3 — Memory task metadata (taskId field):
- Optional taskId field on MemoryNode, StoreMemoryInput, and search results
- Auto-tags memories during auto-capture when exactly 1 active task exists
- Precise taskId-based filtering at recall time (complements Layer 1)
- findMemoriesByTaskId() and clearTaskIdFromMemories() on neo4j client
- taskId flows through vector, BM25, and graph search signals + RRF fusion
- 20 new tests

All 669 memory-neo4j tests pass. Zero regressions in full suite.
All changes are backward compatible — existing memories without taskId
continue to work. No migration needed.
2026-02-16 17:56:39 +08:00
Tarun Sukhani
18b8007d23 memory-neo4j: improve tag coverage with stronger extraction + retroactive tagging
- Strengthen extraction prompt to always generate 2-4 tags per memory
- Add Phase 2b: Retroactive Tagging to sleep cycle for untagged memories
- Include 'skipped' memories in extraction pipeline (imported memories)
- Add listUntaggedMemories() helper to neo4j-client
- Add extractTagsOnly() lightweight prompt for tag-only extraction
- Add CLI display for Phase 2b stats

Fixes: 79% of memories had zero tags due to weak prompt guidance
and imported memories never going through extraction.
2026-02-16 17:56:39 +08:00
Tarun Sukhani
f093be7b3a fix(telegram): prevent subsequent final payloads from overwriting preview message
When multiple final payloads were dispatched (e.g., model text + tool error
warning), each one tried to edit the draft preview message, causing the last
payload (tool error) to replace the model's text. Guard the preview-edit path
with `!finalizedViaPreviewMessage` so only the first final payload edits the
preview; subsequent payloads are sent as separate messages via deliverReplies.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:56:39 +08:00
Tarun Sukhani
fee43d505d refactor(memory-neo4j): remove in-process auto sleep cycle, use system cron instead
Sleep cycle is now triggered by a system cron job (`0 3 * * *`) calling
`openclaw memory neo4j sleep` rather than an in-process 6-hour interval
timer with mutex. Simpler, more reliable, and easier to manage.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:56:39 +08:00
Tarun Sukhani
1bc6cdd00c fix: classify read-only exec/bash commands as non-mutating
Read-only commands like find, ls, grep no longer trigger forced error
messages when they exit with non-zero codes, preserving the LLM's
actual response instead of replacing it with a tool error warning.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:56:39 +08:00
Tarun Sukhani
85ae75882c feat(memory-neo4j): add signal attribution, sleep --report, and health dashboard
- Search results now include per-signal attribution (vec/bm25/graph rank+score)
  threaded through RRF fusion to memory_recall output and auto-recall debug logs
- New --report flag on sleep command shows post-cycle quality metrics
  (extraction coverage, entity graph density, decay distribution)
- New `health` subcommand with 5-section dashboard: memory overview,
  extraction health, entity graph, tag health, decay distribution
  Supports --agent scoping and --json output

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:56:39 +08:00
Tarun Sukhani
8d88f2f8de fix: handle undefined agentId in sandbox registry listing
resolveSandboxAgentId returns string | undefined but was passed
directly to resolveConfiguredImage which expects string.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:56:39 +08:00
Tarun Sukhani
c33a0f21cc updated pnpm 2026-02-16 17:56:39 +08:00
Tarun Sukhani
1a8e46b037 feat(memory-neo4j): add automatic sleep cycle + cleanup sleep/extraction pipeline
Auto-trigger sleep cycle (dedup, extraction, decay, cleanup) in the
background after agent_end when 6h+ have elapsed. Configurable via
sleepCycle.auto and sleepCycle.autoIntervalMs. Removes need for
external cron job with regular gateway usage.

Also includes: removal of Pareto promotion (replaced by manual core
promotion), entity dedup in sleep cycle, and sleep cycle pipeline
cleanup.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:56:39 +08:00
Tarun Sukhani
0a55711110 fix: guard against undefined path in bootstrap file entries
The session-context hook pushed bootstrap entries without the required
`path` property, causing a TypeError in buildInjectedWorkspaceFiles when
it called .replace() on undefined. Add fallback to file.name when path
is missing, and skip entries with no path in the report builder.

Also add stack trace logging to lane task errors and embedded agent
failures to make future debugging faster.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:56:39 +08:00
Tarun Sukhani
fc92b05046 push to repos 2026-02-16 17:56:39 +08:00
Tarun Sukhani
624ba65554 check key 2026-02-16 17:56:39 +08:00
Tarun Sukhani
a5e0487647 fix: allow plugin CLI registration for builtin memory command
The performance optimization that skips plugin loading for builtin
commands prevented memory-neo4j from registering its "neo4j" subcommand,
causing "openclaw memory neo4j sleep" to fail with "unknown command".

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:56:39 +08:00
Tarun Sukhani
68d4ca1e0d updated script 2026-02-16 17:56:39 +08:00
Tarun Sukhani
ed5d6db833 updated script 2026-02-16 17:56:39 +08:00
Tarun Sukhani
a170e25494 task continuity: TASKS.md ledger, post-compaction recovery, entity dedup, credential scanning
Add task ledger (TASKS.md) parsing and stale-task archival for maintaining
agent task state across context compactions. Post-compaction recovery injects
memory_recall + TASKS.md read steps after auto-compaction. Sleep cycle gains
entity dedup (Phase 1d) and credential scanning. Memory flush now extracts
active task checkpoints. Compaction instructions prioritize active tasks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:56:39 +08:00
Tarun Sukhani
4d54736b98 memory-neo4j: single-use tag pruning, alias-based entity dedup, tag normalization
- Add findSingleUseTags() to prune tags with only 1 reference after 14 days
- Enhance findDuplicateEntityPairs() to match on entity aliases
- Add normalizeTagName() to collapse hyphens/underscores to spaces
- Monitor 'other' category accumulation in sleep cycle Phase 2
- Tighten extraction prompt with explicit entity blocklist (80 terms)
- Raise auto-capture threshold from 0.5 to 0.65
- Fix tests for entity dedup phase and skipPromotion default
2026-02-16 17:56:39 +08:00
Tarun Sukhani
08b08c66f1 memory-neo4j: filter open proposals and cron noise from memory
Open proposals ("Want me to...?", "Should I...?") are dangerous in
long-term memory because other sessions interpret them as active
instructions and attempt to carry them out. This adds:
- Attention gate patterns for cron delivery outputs and assistant proposals
- Extractor scoring rules to rate proposals/action items as low importance
- Sleep-cycle Phase 7 to retroactively clean existing noise-pattern memories

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:56:39 +08:00
Tarun Sukhani
e85dd19092 updated killmode to mixed 2026-02-16 17:56:39 +08:00
Tarun Sukhani
7704e5cc44 fix: remove dead localTime param from formatLogTimestamp after rebase
The upstream added --local-time as an opt-in flag, but our branch
already makes all timestamps local. Remove the dead parameter,
CLI option, and update tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:56:39 +08:00
Tarun Sukhani
4082d2657e memory-neo4j: improve extraction quality and sleep-cycle tuning
- Add attention gate patterns for voice mode context and session
  completion summaries (ephemeral, not user knowledge)
- Rewrite importance rating prompt with detailed scoring guide and
  concrete examples to reduce over-scoring of assistant narration
- Raise dedup safety bound from 500 to 2000 pairs
- Add skipPromotion option (default true) so core tier stays
  user-curated only

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:56:39 +08:00
Tarun Sukhani
8762697d22 memory-neo4j: enhance list and stats CLI with bar graphs and memory listing
- stats: show per-agent bar graphs for category counts and avg importance
- list: show actual memory contents grouped by agent/category with importance bars
- list: add --agent, --category, --limit filters

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:56:39 +08:00
Tarun Sukhani
8086915187 fix: suppress low context window warning for explicitly configured models
When a model's contextWindow is explicitly set in modelsConfig (openclaw.json),
don't warn about it being below 32k. The user deliberately chose that value.

The warning still fires for auto-detected (model metadata) and default sources.
shouldBlock is unaffected — hard minimum still enforced regardless of source.

Closes #13933
2026-02-16 17:56:39 +08:00
Tarun Sukhani
0149f39e72 agents: lower context window hard minimum from 16k to 1024
Allow small-context models like ollama/qwen2.5:7b-2k (2048 tokens) to
run without being blocked by the guard.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:56:39 +08:00
Tarun Sukhani
0f6a15deca memory-neo4j: fix undefined variable in graph search agent filter
The agentFilter used `m.agentId` in both the direct-mentions and N-hop
sections of the Cypher query, but `m` is out of scope in the N-hop
section where the Memory node is aliased as `m2`.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:56:39 +08:00
Tarun Sukhani
e9b9da5a1f memory-neo4j: add userPinned flag, remove demotion, add benchmarking, audit fixes
- Add userPinned boolean on Memory nodes: user-stored core memories are
  immune from importance recalculation, decay, and pruning. Only removable
  via memory_forget. Importance locked at 1.0.
- Add listCoreForInjection(): always injects ALL userPinned core memories
  plus top N non-pinned core memories by importance (no silent drop-off
  for user-pinned memories regardless of maxEntries cap).
- Remove core demotion entirely: promotion is now one-way. Bad core
  memories are handled manually via memory_forget.
- Add [bench] performance timing to auto-recall, auto-capture, core
  memory injection, core refresh, and hybridSearch.
- Audit fixes: remove dead entity/tag methods, dead test blocks, orphaned
  demoteFromCore docstring, unnecessary .slice() in graphSearch.
- Refactor attention gate into shared checks for user/assistant gates.
- Consolidate LLM client, message utils, and config helpers.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:56:39 +08:00
Tarun Sukhani
e562ff4e31 memory-neo4j: tighten attention gate filters and add session skip patterns
Strip voice chat timestamps, conversation metadata blocks, and queued
message wrappers before the attention gate evaluates content. Expand
assistant narration patterns to catch UI interaction verbs, filler
responses ("I'm here", "Sure, tell me"), and page/step progress.
Add configurable autoCaptureSkipPattern and autoRecallSkipPattern
for bypassing memory on latency-sensitive sessions (e.g. voice).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:56:39 +08:00
Tarun Sukhani
a5ebbe4b55 memory-neo4j: make semantic dedup cap and LLM concurrency configurable
The hardcoded MAX_SEMANTIC_DEDUP_PAIRS (50) and LLM_CONCURRENCY (8) were
designed for expensive cloud LLM calls. For local Ollama inference these
caps are unnecessarily restrictive, especially during long sleep windows.

- Add maxSemanticDedupPairs to SleepCycleOptions (default: 500)
- Add llmConcurrency to SleepCycleOptions (default: 8)
- Add --max-semantic-pairs and --concurrency CLI flags
- Raise semantic dedup default from 50 → 500 pairs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:56:38 +08:00
Tarun Sukhani
e0e98c2c0d memory-neo4j: purge noise, tighten auto-capture filters, cap sleep cycle dedup
- Add 11 ASSISTANT_NARRATION_PATTERNS to reject play-by-play self-talk
  ("Let me check...", "I'll run...", "Starting...", "Good! The...", etc.)
- Cap Phase 1b semantic dedup to 50 pairs (sorted by similarity desc)
  to prevent sleep cycle timeouts on large memory sets
- Raise user auto-capture importance threshold from 0.3 to 0.5
- Raise assistant auto-capture importance threshold from 0.7 to 0.8
- Raise MIN_WORD_COUNT from 5 to 8 for user attention gate
- Neo4j cleanup: deleted 155 noise entries (394→242 memories),
  recategorized 2 misplaced entries, stripped Slack metadata from 1

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:56:38 +08:00
Tarun Sukhani
309c5b6029 memory-neo4j: add --skip-semantic flag to skip LLM-based dedup in sleep cycle
Adds skipSemanticDedup option to runSleepCycle that skips Phase 1b
(semantic dedup) and Phase 1c (conflict detection), both of which
require LLM calls. Useful for fast/cheap sleep runs that only need
vector-based dedup and decay.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:56:38 +08:00
Tarun Sukhani
d4e3549ed2 audit: fix 18 defects across gateway SSE streaming, voice-call security, and telephony
Gateway (pipecat compatibility):
- openai-http: add finish_reason:"stop" on final SSE chunk, fix ID format
  (chatcmpl- not chatcmpl_), capture timestamp once, use delta only, add
  writable checks and flush after writes
- http-common: add TCP_NODELAY, X-Accel-Buffering:no, flush after writes,
  writable checks on writeDone
- agent-events: fix seqByRun memory leak in clearAgentRunContext

Voice-call security:
- manager.ts, twiml.ts, twilio.ts: escape voice/language XML attributes
  to prevent XML injection
- voice-mapping: strip control characters in escapeXml

Voice-call bugs:
- tts-openai: fix broken resample24kTo8k (interpolation frac always 0)
- stt-openai-realtime: close zombie WebSocket on connection timeout
- telnyx: extract direction/from/to for inbound calls (were silently dropped)
- plivo: clean up 5 internal maps on terminal call states (memory leak)
- twilio: clean up callWebhookUrls on terminal call states

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:56:38 +08:00
Tarun Sukhani
806c5e2d13 memory-neo4j: fix high-severity review findings — security, concurrency, silent failures
- Add safety comment for RELATIONSHIP_TYPE_PATTERN Cypher interpolation
- Add concurrency batching (8) to findDuplicateClusters vector queries
- Bounds-validate memory_recall limit parameter (1-50)
- Fix maxRetries comment (default 2 = 3 attempts, not 1 = 2)
- Fix countByExtractionStatus passing undefined agentId to Cypher
- Fix assistant auto-capture silently disabled when extraction disabled
- Add agentId scoping to findSimilar (dedup + auto-capture)
- Fix BM25 single-result normalization (0.5 instead of inflated 1.0)
- Wrap pruneMemories in retryOnTransient for resilience
- Use UNWIND batch update in reindex instead of N individual queries
- Raise auto-delete threshold from 0.9 to 0.95 to reduce false positives

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:56:38 +08:00
Tarun Sukhani
03e4768732 memory-neo4j: code review fixes — search, decay, dedup, retry, tests
Search: fix entity classification order (proper nouns before word count),
BM25 min-max normalization with floor, empty query guard.

Decay: retrieval-reinforced half-life with effective age anchored to
lastRetrievedAt, parameterized category curves (no string interpolation).

Dedup: transfer TAGGED relationships to survivor during merge.

Orphans: use EXISTS pattern instead of stale mentionCount.

Embeddings: Ollama retry with exponential backoff (2 retries, 1s base).

Config: resolve env vars in neo4j.uri, re-export MemoryCategory from schema.

Extractor: abort-aware batch delay, anonymize prompt examples.

Tests: add 80 tests for index.ts (attention gates, message extraction,
wrapper stripping). Full suite: 480 tests across 8 files, all passing.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:56:38 +08:00
Tarun Sukhani
cb1c0658fc fix stray brace in memory-lancedb and bump pnpm to 10.29.2
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:56:38 +08:00
Tarun Sukhani
b70cecc307 memory-neo4j: long-term fixes — streaming, abort signals, configurable depth/decay
- Semantic dedup vector pre-screen: skip LLM calls when cosine similarity < 0.8
- Propagate abort signal into sleep cycle phases and extraction pipeline
- Configurable graph search depth (1-3 hops) via graphSearchDepth config
- Streaming extraction: SSE-based callOpenRouterStream with abort responsiveness
- Configurable per-category decay curves for memory consolidation
- Updated tests with SSE streaming mocks

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:56:38 +08:00
Tarun Sukhani
1f80d4f0d2 memory-neo4j: medium-term fixes — index, batching, parallelism, module extraction
- Add composite index on (agentId, category) for faster filtered queries
- Combine graph search into single UNION Cypher query (was 2 sequential)
- Parallelize conflict resolution with LLM_CONCURRENCY chunks
- Batch entity operations (merge, mentions, relationships, tags, category,
  extraction status) into a single managed transaction
- Make auto-capture fire-and-forget with shared captureMessage helper
- Extract attention-gate.ts and message-utils.ts modules from index.ts
  and extractor.ts for better separation of concerns
- Update tests to match new batched/combined APIs

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:56:38 +08:00
Tarun Sukhani
1ae3afbd6b memory-neo4j: code review quick wins — security, perf, docs fixes
- Fix initPromise retry: reset to null on failure so subsequent calls
  retry instead of returning cached rejected promise
- Remove dead code: findPromotionCandidates, findDemotionCandidates,
  calculateEffectiveImportance (~190 lines, never called)
- Add agentId filter to deleteMemory() to prevent cross-agent deletion
- Fix phase label swaps: 1b=Semantic Dedup, 1c=Conflict Detection
  (CLI banner, phaseNames map, SleepCycleResult/Options type comments)
- Add autoRecallMinScore and coreMemory config to plugin JSON schema
  so the UI can validate and display these options
- Add embedding LRU cache (200 entries, SHA-256 keyed) to eliminate
  redundant API calls across auto-recall, auto-capture, and tools
- Add Ollama concurrency limiter (chunks of 4) to prevent thundering
  herd on single-threaded embedding server

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:56:38 +08:00
Tarun Sukhani
d311438cb4 memory-neo4j: fix Ollama embedding context overflow for token-dense inputs 2026-02-16 17:56:38 +08:00
Tarun Sukhani
27cb766209 memory-neo4j: strengthen auto-capture filtering and add Slack metadata stripping
- Raise MIN_CAPTURE_CHARS from 10 to 30 to reject trivially short messages
- Add noise patterns for conversational filler (haha, lol, hmm, etc.)
- Add noise pattern to reject /new and /reset session prompts
- Raise importance threshold for assistant auto-captures to >= 0.7
- Add Slack protocol prefix/suffix stripping in stripMessageWrappers()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:56:38 +08:00
Tarun Sukhani
4a3d424890 updated dependency 2026-02-16 17:56:38 +08:00
Tarun Sukhani
fff48a146d memory-neo4j: add auto-recall filtering, assistant capture, importance scoring, conflict detection
Five high-impact improvements to the memory system:

1. Min RRF score threshold on auto-recall (default 0.25) — filters low-relevance
   results before injecting into context
2. Deduplicate auto-recall against core memories already present in context
3. Capture assistant messages (decisions, recommendations, synthesized facts)
   with stricter attention gating and "auto-capture-assistant" source type
4. LLM-judged importance scoring at capture time (0.1-1.0) with 5s timeout
   fallback to 0.5, replacing the flat 0.5 default
5. Conflict detection in sleep cycle (Phase 1b) — finds contradictory memories
   sharing entities, uses LLM to resolve, invalidates the loser

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 17:56:38 +08:00
Tarun Sukhani
9f6372241c hooks: fire session_end on /new and /reset so plugins clear bootstrap state 2026-02-16 17:56:38 +08:00
Tarun Sukhani
9cfb56696f memory-neo4j: extract stripMessageWrappers helper, use in cleanup for accurate gating 2026-02-16 17:56:38 +08:00
Tarun Sukhani
6747967b83 memory-neo4j: strip channel metadata wrappers, reject system infra messages in attention gate 2026-02-16 17:56:38 +08:00
Tarun Sukhani
7674fa8c15 memory-neo4j: cleanup targets auto-capture only, trust explicit memory_store 2026-02-16 17:56:38 +08:00