Commit Graph

11 Commits

Author SHA1 Message Date
Glucksberg 9361e33b6d fix(openclaw): inject context via system prompt instead of overwriting MEMORY.md (#1386)
* fix(openclaw): inject context via system prompt instead of overwriting MEMORY.md

The OpenClaw plugin was overwriting each agent's MEMORY.md with a large
auto-generated observation dump (~12-15KB) on every before_agent_start
and tool_result_persist event. This conflicts with OpenClaw's design
where MEMORY.md is agent-curated long-term memory.

Migrate context injection from file-based (writeFile MEMORY.md) to
OpenClaw's native before_prompt_build hook, which returns context via
appendSystemContext. This keeps MEMORY.md under agent control while
still providing cross-session observation context to the LLM.

Changes:
- Add before_prompt_build hook that returns { appendSystemContext }
- Remove writeFile/MEMORY.md sync from before_agent_start
- Remove MEMORY.md sync from tool_result_persist (observations still recorded)
- Add 60s TTL cache to avoid re-fetching context on every LLM turn
- Add syncMemoryFileExclude config for per-agent opt-out
- Remove dead workspaceDirsBySessionKey tracking map
- Rewrite test suite to verify prompt injection instead of file writes

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix(ui): align settings defaults with backend and use nullish coalescing

The web UI had two issues causing settings inflation:

1. DEFAULT_SETTINGS in the UI used FULL_COUNT='5' and all token columns
   'true', while SettingsDefaultsManager (backend) uses FULL_COUNT='0'
   and token columns 'false'. Opening the settings modal and saving
   without changes would silently inflate the context.

2. useSettings used || for fallback, which treats '0' and 'false' as
   falsy — even when the backend correctly returns these values, the UI
   would replace them with inflated defaults. Changed to ?? (nullish
   coalescing) so only null/undefined trigger the fallback.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs(openclaw): update integration docs for system prompt injection

Reflect the migration from MEMORY.md file writes to before_prompt_build
hook-based context injection:

- Update architecture diagram and overview to show new hook flow
- Replace "MEMORY.md Live Sync" section with "System Prompt Context Injection"
- Update event lifecycle steps (before_agent_start, tool_result_persist)
- Add before_prompt_build step with TTL cache description
- Document new syncMemoryFileExclude config parameter
- Update session tracking to reflect removed workspaceDirsBySessionKey

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: fix terminology and update SKILL.md for system prompt injection

Replace "prompt injection" with "context injection" in docs to avoid
confusion with the OWASP security term. Update openclaw/SKILL.md to
reflect the new before_prompt_build hook and remove stale MEMORY.md
references.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Alex Newman <thedotmack@gmail.com>
2026-03-17 17:14:30 -07:00
Alex Newman ab2dbb7dc7 Rename Telegram bot commands from hyphens to underscores (#1126)
Telegram Bot API only allows a-z, 0-9, and underscores in command
names. Rename /claude-mem-feed → /claude_mem_feed and
/claude-mem-status → /claude_mem_status.

Fixes #1108

Co-authored-by: Manantra <113709296+Manantra@users.noreply.github.com>
2026-02-16 00:33:55 -05:00
Daniel M. be474ea595 Fix command handlers to return { text } per OpenClaw plugin API (#1115)
The OpenClaw plugin API requires command handlers to return
{ text: string } objects. Returning plain strings causes
"reply missing text/media" errors and commands silently fail
to send responses to Telegram/other channels.
2026-02-16 00:32:04 -05:00
Glucksberg 55e0e323b9 feat: universalize observation feed emojis (#1100)
* feat: universalize observation feed emojis with config-driven system

Replace hardcoded AGENT_EMOJI_MAP with a three-tier approach:
1. User-pinned emojis via observationFeed.emojis.agents config
2. Deterministic auto-assign from pool using agentId hash
3. Configurable fallbacks for primary, Claude Code, and default emojis

Claude Code sessions now display "Claude Code Session" instead of the
working directory name. All emoji settings are exposed in the plugin
configSchema so the onboarding wizard AI can discover and configure them.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

* fix(feed): keep Claude Code project id in source labels

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 00:29:55 -05:00
Glucksberg 809175612c feat(openclaw): enable observation feed for OpenClaw agent sessions
Three fixes to make OpenClaw agent observations work end-to-end:

1. Session init in before_agent_start — the worker's privacy check
   requires a stored user prompt; without calling /api/sessions/init,
   all observations were skipped as "private"

2. Race condition fix in agent_end — await summarize before sending
   complete, preventing session deletion before in-flight observation
   POSTs arrive

3. OAuth token pass-through in buildIsolatedEnv — spawned Claude CLI
   processes now receive CLAUDE_CODE_OAUTH_TOKEN from the worker's
   env when no explicit API key is configured

Also adds agent-specific emoji mapping and dynamic project naming
for the Telegram observation feed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 02:30:18 +00:00
Alex Newman 05b615c858 Fix SSE stream URL consistency, multi-line data parsing, and test mocks
- Use workerBaseUrl() for SSE stream URL instead of hardcoded localhost
- Concatenate all SSE data: lines per frame per SSE spec
- Update WhatsApp mock to accept third options argument
- Restrict SSE mock server to only respond on /stream path

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 21:54:02 -05:00
Alex Newman c7f7f87321 Move session init to session_start and after_compaction hooks
Init was incorrectly placed in before_agent_start, which fires on every
agent attempt (retries, context overflow, auth rotation). Session init
should fire once on /new or /reset (session_start) and after compaction
(after_compaction). before_agent_start now only syncs MEMORY.md and
tracks workspace dirs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 21:04:52 -05:00
Alex Newman 11532a36fb Fix sendToChannel to use explicit OpenClaw SDK function mapping
Replace dynamic function name construction with CHANNEL_SEND_MAP that
matches the actual PluginRuntime.channel structure. Fixes WhatsApp
(sendMessageWhatsApp) and iMessage (sendMessageIMessage) casing, and
adds WhatsApp's required verbose option. Also adds null guard on SSE
observation payload before type casting.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 20:14:41 -05:00
Alex Newman 7b7a92e35a MAESTRO: Add observation I/O, MEMORY.md live sync, and gateway lifecycle support
Merge crab-mem observation recording with existing SSE broadcasting to
create a complete OpenClaw plugin. Records observations from embedded
runner sessions via worker HTTP API, and continuously syncs MEMORY.md
to agent workspaces so agents always have fresh context.

- Add event handlers: before_agent_start, tool_result_persist, agent_end, gateway_start
- Add MEMORY.md live sync on every agent start and tool use (fire-and-forget)
- Add worker HTTP client (POST, fire-and-forget POST, GET text)
- Add /claude-mem-status health check command
- Add workspace dir tracking across session events
- Expand test suite from 17 to 36 tests

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-09 19:12:12 -05:00
Alex Newman 1b9f601c41 MAESTRO: Fix OpenClaw SDK API mismatch — use real PluginApi interface
E2E testing against the official OpenClaw Docker image revealed the plugin
was built against a custom interface that didn't match the real SDK:
- api.log() → api.logger.info/warn/error() (PluginLogger interface)
- api.getConfig() → api.pluginConfig (direct property)
- command handler (args[], ctx) → (ctx) with ctx.args string
- service stop optional, service context typed

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 21:28:08 -05:00
Alex Newman f8d8de53e8 MAESTRO: Implement SSE observation feed consumer with channel routing and exponential backoff
Replaces stub start/stop methods with working SSE consumer that connects to
claude-mem worker's /stream endpoint, parses new_observation events, and
forwards formatted messages to configured OpenClaw channels (Telegram, Discord,
Signal, Slack, WhatsApp, Line). Includes reconnection with exponential backoff
(1s-30s), connection state tracking, and on/off command toggle. Added 17 tests
covering unit and SSE integration scenarios.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 18:44:35 -05:00