mirror of
https://github.com/rohitg00/agentmemory.git
synced 2026-09-14 20:16:33 +08:00
fix/engine-spawn-absolute-paths
13 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
be89b222b0 |
feat: devin support (cli adapter, plugin, cloud mcp) (#1214)
* feat: devin support replacing windsurf * feat: devin cli adapter, plugin manifest, and hook payload compat * fix: stale tool counts in translations and cwd validation |
||
|
|
37ea1b99ad |
feat: cursor marketplace plugin with hooks, mcp, and skills (#1213)
* feat: cursor marketplace plugin with native hooks and mcp config * fix: cursor payload compat and transcript prompt backfill in hooks * fix: plugin-root hook paths, backfill ordering, session-id fallbacks * docs: cursor plugin rows in readme, translations, and changelog * fix: cursor native-plugin card, broken agent logos * chore: sync openclaw and hermes plugin manifest versions * docs: openclaw hook permission and hermes tool count * chore: clawhub compat metadata for openclaw plugin * docs: tested openclaw and hermes install rows in readme |
||
|
|
6cc9b9f0fe |
fix: env hydration, indexing, consolidation lifecycle, connector activation, hardening (#1136)
* fix: env hydration, indexing, consolidation, connectors, hardening - config: hydrate ~/.agentmemory/.env into process.env at boot so all modules see it - search: shared indexRecords() so export-import and replay populate BM25 and vector (#1072) - snapshot: wire the periodic timer (#1006), clamp non-positive intervals, add a reentrancy guard - schema: CJK-aware jaccard dedup plus exact-match fallback for short memories - embeddings: shared resolveDimensions() so openrouter stops hardcoding 1536 (#1002) - viewer: buffer request bodies before decoding to fix multibyte corruption (#930) - providers: retry 429/503 with Retry-After under a total-elapsed budget cap - consolidation: fire on session stop (#1087), gate keyless installs, debounce the per-turn stop hook, drop the client-side double-fire - evict: bound stale-session recovery to one consolidation pass - api/patterns: bound session fan-out (#1100) - connect: write a memory-usage guideline into each hook-less agent's native rules file (12 agents, doc-verified paths, --no-guidelines opt-out) - graph: import graphify's graph.json via mem::graph::import-graphify + POST /agentmemory/graph/import-graphify; shared persistGraphDelta with endpoint remap so merged nodes never leave dangling or duplicate edges - fs-watcher: stat roots before fs.watch so missing roots fail deterministically on Node 24+ - test: regression tests for every fix * fix: address review findings on import, debounce, and connect paths - guidelines: refuse to touch files with a lone or reversed marker pair - export-import/replay: indexing after committed writes is best-effort, logged instead of failing the import; flatten the nested runChunked so replace-mode deletes stay bounded to one chunk - graph: persist the snapshot when merge-only batches mutate cached topNodes/topEdges entries - graph-import: async fs, typeof validation on path/cwd; REST handler whitelists the payload and 400s non-string values - fetch: cancel discarded response bodies before retrying - events: serialize the consolidation cooldown check so concurrent stops cannot both pass the read-check-write window - evict: gate recovered-session consolidation on isConsolidationEnabled and mirror the stop path's force flag - search: rebuild indexes per session chunk to bound peak memory - test: regression coverage for each (malformed markers, concurrent stops, snapshot persistence, AMBIGUOUS/default mappings, env isolation) |
||
|
|
6761a99ba1 |
fix: guard hooks against null payload (#1074)
#1047: JSON.parse("null") returns null without throwing, so every hook's parse guard passed it through and the first data.xxx access threw a TypeError. Bare main() turned that into an unhandled rejection -> exit 1 -> host reported 'hook failed' on every affected tool call. All 13 hook entrypoints now guard non-object payloads before dereferencing and wrap main() in .catch() to fail closed (silent exit 0). #1057: mem::context and api::context filtered candidate sessions by project only, leaking cross-agent observations/summaries under AGENTMEMORY_AGENT_SCOPE=isolated. Now applies the same agent-scope filter as mem::search (#817); api::context, api::session::start, and event::session::started forward agentId. Also: bump 0.9.28 across manifests/deploy/export-import set; refresh stale README/AGENTS stats (files/LOC/functions/KV; AGENTS tests 950+ -> 1,428+) and regenerate the website meta snapshot to 0.9.28; CHANGELOG 0.9.28 section; remove the rate-limited star-history chart from README and all 11 translations. |
||
|
|
a0da02b6b3 |
Add GitHub Copilot CLI support (#534)
* feat: add Copilot CLI plugin asset slice - plugin/.plugin/plugin.json: Copilot manifest with name/version/skills/mcpServers/hooks refs - plugin/.mcp.copilot.json: MCP server config with type:local, npx, env passthrough, tools:[*] - plugin/hooks/hooks.copilot.json: Copilot hooks (version:1) with 11 supported events and PreToolUse matcher - test/copilot-plugin.test.ts: 11 tests covering manifest, MCP config, and hooks validation Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add Copilot CLI connect support Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add GitHub Copilot CLI support Adds Copilot CLI support through a root plugin manifest, Copilot-specific MCP and hook configuration, and a connect adapter for MCP-only setup. Includes Windows-safe Copilot MCP command generation, COPILOT_HOME handling, Copilot hook payload normalization, generated hook scripts, and targeted tests for plugin shape, hook execution, and connect behavior. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Harden Copilot hook handling Addresses upstream AI review suggestions by aligning the Copilot preToolUse matcher with the hook allowlist, narrowing hook payload fields at runtime, normalizing subagent fallbacks, and tightening hook config validation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add Copilot to first-run onboarding Includes GitHub Copilot CLI in the first-run agent picker and adds a regression test so the Copilot setup path remains discoverable. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Default onboarding to Copilot inside Copilot CLI Detect Copilot CLI environment markers during first-run setup so pressing Enter wires the current agent instead of the historical Claude Code default. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Support framed stdio MCP transport Accept Content-Length framed JSON-RPC messages in addition to the existing newline-delimited transport so Copilot CLI can initialize the standalone MCP server. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Narrow Copilot pre-tool session ids Ensures pre-tool-use only forwards string session IDs and falls back to unknown for invalid Copilot payload values, with regression coverage for the generated plugin script. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Ross Story <rostory@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Rohit Ghumare <ghumare64@gmail.com> |
||
|
|
d626b4ea60 |
perf(hooks): fire-and-forget telemetry hooks (#573) (#688)
* perf(hooks): fire-and-forget telemetry hooks (closes #573) Telemetry hooks (notification, post-tool-failure, post-tool-use, prompt-submit, stop, session-end, subagent-start, subagent-stop, task-completed) previously `await fetch(..., AbortSignal.timeout(N))` inside a try/catch. The await kept the hook process alive until the response arrived — up to N ms per request — which blocks Claude Code's next-prompt boundary on every assistant turn. Switch to fire-and-forget: fetch(url, { signal: AbortSignal.timeout(N) }).catch(() => {}); setTimeout(() => process.exit(0), 500).unref(); The unawaited fetch dispatches the request; the unref'd setTimeout force-exits the process after the request has been flushed to the local daemon's socket buffer (~500ms is enough). Without the setTimeout Node keeps the event loop alive waiting for any in-flight fetch to settle, which means the hook still blocks Claude Code's next-prompt boundary for up to the AbortSignal duration. Context-injecting hooks (pre-tool-use, pre-compact, session-start) still use `await fetch` because Claude Code reads their stdout for context injection — left untouched. AGENTS.md updated with the two-pattern guidance. * chore(hooks): drop verbose comments on fire-and-forget hooks * fix(hooks): bump stop+session-end exit delay to 1500ms Multi-request hooks (stop fires 2, session-end up to 4) need more than 500ms to initiate all fetches when AGENTMEMORY_URL points to a remote daemon — DNS + TCP + TLS handshakes can eat the budget before the second/third fetch is even dispatched. Bump to 1500ms on those two hooks only; single-request hooks keep 500ms. AGENTS.md updated with the multi-request exception. |
||
|
|
0c73d868be |
chore(release): v0.9.5 — search recall + plugin compatibility (#261)
Bug-fix patch focused on search recall correctness and plugin compatibility. Pins iii-engine to v0.11.2 because v0.11.6 introduces a new sandbox-everything-via-`iii worker add` model that agentmemory hasn't been refactored for yet — pin lifts once that refactor lands. Adds a hard guard against silent vector-index corruption, fixes BM25 indexing for memories saved via memory_save, and lands four Hermes plugin fixes. Per AGENTS.md release checklist: - package.json version 0.9.4 -> 0.9.5 - src/version.ts VERSION constant - src/types.ts ExportData version union - src/functions/export-import.ts supportedVersions Set - test/export-import.test.ts assertion - plugin/.claude-plugin/plugin.json version - CHANGELOG.md detailed entries with contributor shoutouts Headlines (full detail in CHANGELOG): Fixed: - BM25 search now indexes memories saved via memory_save (#258, #257) Thanks @Nizar-BenHamida for the precise repro. - Embedding providers no longer silently corrupt the vector index when an API returns wrong-dimension vectors (#248, #247, #256) Thanks @AmmarSaleh50 for issue + fix + tests. - Hermes handle_tool_call returns JSON strings, not raw dicts (#255, #254) Thanks @KyoMio for the Anthropic-protocol repro. - Hermes status reflects real service state on systemd installs (#253, #250) Thanks @OptionalCoin for tracing it to env-source divergence. - Hermes hooks accept passthrough kwargs (#252, #249) Thanks @OptionalCoin again for the log analysis. - agentmemory demo now seeds observations correctly (#251, #229) Thanks @seishonagon for root-cause analysis. - LLM compression / summarization timeouts increased (#213) Thanks @xuli500177. - Pi / OpenClaw / Hermes integration plugin fixes (#230) Thanks @deepmroot. Changed: - iii-engine pinned to v0.11.2 across every install path (#260). v0.11.6 introduces a new `iii worker add` sandbox model that agentmemory still pre-dates; pin lifts when we refactor agentmemory to register as a sandboxed worker. Override with AGENTMEMORY_III_VERSION=<version> for users who've migrated manually. - README documents iii worker add extension surface (#242). - README iii Console install/launch commands corrected (#243). Validated: 852/852 tests pass, npm run build clean. |
||
|
|
51bcb09104 |
address CodeRabbit review on #187 + fix CI
Findings verified against current code on this branch; all four valid. 1. config.ts loadFallbackConfig (L281) — user could set FALLBACK_PROVIDERS=agent-sdk and bypass the AGENTMEMORY_ALLOW_AGENT_SDK gate added to detectProvider. Filter it out at the fallback layer too, with the same warning pointing at the opt-in flag. 2. summarize.ts (L87-92) — the empty_provider_response branch returned without recording failure metrics or a diagnostic log, unlike the parse/validation paths. Record the same metricsStore failure event and log provider name, prompt size, system size, and observation count so empty responses are visible in telemetry. 3. providers/agent-sdk.ts (L14-45) — setting process.env.AGENTMEMORY_SDK_CHILD = '1' without restoring it caused every subsequent .query() in the same parent process to hit the short-circuit guard and return '' (classified as a SDK child it is not). Capture prev, set in try, restore in finally (delete if prev was undefined). Child processes spawned during the for-await loop still inherit the marker because env is inherited at spawn time; we only restore after the loop completes. 4. plugin/scripts/sdk-guard-DI1NUOS9.mjs — tsdown extracted the shared guard helper into a hashed chunk. Hash rotates on every rebuild and churns the diff. Stopped using the shared module from hooks entirely and inlined the 6-line guard function into each hook .ts file instead. sdk-guard.ts stays in the tree because the unit tests cover it directly. Deleted the tracked hashed .mjs and confirmed no new chunk is emitted. Also applied the CI two-step install (npm install --package-lock-only then npm ci) on this branch, matching #184. Without it, npm ci fails because lockfiles are gitignored. Tests: 74 files / 819 tests pass. |
||
|
|
5e63846b29 |
fix(hooks): break Stop-hook infinite recursion via agent-sdk fallback
Reported: a user with no provider API key and AGENTMEMORY_AUTO_COMPRESS=false (which they believed protected them) hit unbounded recursion — Stop hook POSTs /agentmemory/summarize, handler calls provider.summarize(), agent-sdk provider spawns @anthropic-ai/claude-agent-sdk query(), which creates a full CC-style child session that reads ~/.claude/settings.json, registers the same plugin hooks, and fires its own Stop -> another child -> loop. ~579 ghost 'entrypoint: sdk-ts' sessions accumulated in a few minutes, draining Claude Pro tokens. #149 only added a stderr warning. AGENTMEMORY_AUTO_COMPRESS gated /compress but never /summarize, so users who followed the warning's implied guidance still got hit. Fix the loop at every layer: 1. config.ts detectProvider - Treat empty-string provider keys (ANTHROPIC_API_KEY=) as unset; they previously passed the truthiness check identically to a real key. - Stop defaulting to agent-sdk. When no key is set, return a 'noop' provider config and warn. Agent-sdk fallback now requires an explicit AGENTMEMORY_ALLOW_AGENT_SDK=true opt-in with a loud second warning. 2. providers/noop.ts (new) + providers/index.ts - NoopProvider implements MemoryProvider and returns empty strings for compress and summarize so callers can detect .name === 'noop' and short-circuit without spawning anything. - Add ProviderType 'noop' and wire it through createBaseProvider. 3. providers/agent-sdk.ts - Before spawning query(), check process.env.AGENTMEMORY_SDK_CHILD === '1' and return '' instead of recursing. Set the env var to '1' before the spawn so any child process (including the Agent SDK session's hooks) inherits it. 4. hooks/sdk-guard.ts (new) + all 12 hook scripts - Shared isSdkChildContext(payload) checks both AGENTMEMORY_SDK_CHILD=1 and payload.entrypoint === 'sdk-ts' (CC writes this into the stdin jsonl for SDK-spawned sessions). Every hook script now bails early when that returns true, so even if one guard layer fails the others break the loop. 5. functions/summarize.ts - Short-circuit with {success:false, error:'no_provider'} when provider.name === 'noop' — never reach .summarize(). - Treat an empty provider response as empty_provider_response instead of trying to parse it. Tests: 74 files / 819 tests pass (+7 new in stop-hook-recursion-guard.test.ts). Defense in depth means any ONE of the five layers breaks the loop. |
||
|
|
e8f410b537 |
feat: v0.7.0 — lessons, tool visibility, auto-consolidation, obsidian export, npx bootstrap (#82)
* feat: v0.7.0 — lessons, tool visibility, auto-consolidation, obsidian export, npx bootstrap Five DX improvements based on competitive research against Mem0, Engram, CodeMem: 1. `npx agentmemory` zero-config startup - New CLI bootstrap (src/cli.ts) auto-detects and starts iii-engine - Tries `iii` binary first, falls back to `docker compose up -d` - Bundles iii-config.yaml and docker-compose.yml in dist/ 2. Simplified MCP tool surface (7 core tools by default) - AGENTMEMORY_TOOLS=all unlocks all 49 tools - Default: save, recall, consolidate, forget, sessions, diagnose, lesson_save - Call handler remains unfiltered — any tool callable by name 3. Auto-consolidation on session end - CONSOLIDATION_ENABLED defaults to true (was false) - Session-end hook: session/end → crystallize → consolidate → bridge sync - Consolidation pipeline always registered (timer gated by config) 4. First-class lesson memory type with confidence decay - Lesson interface: confidence (0-1), reinforcements, decayRate, source - 5 functions: lesson-save, lesson-recall, lesson-list, lesson-strengthen, lesson-decay-sweep - Dedup via SHA-256 fingerprint — duplicate saves strengthen existing - Crystal lessons auto-flow into lesson system at confidence 0.6 - Daily decay sweep with parallel KV writes 5. Obsidian-compatible Markdown export - Export to ~/.agentmemory/vault/ with YAML frontmatter + wikilinks - MOC.md (Map of Content) index file - Parallel KV reads, auto-export via OBSIDIAN_AUTO_EXPORT=true Stats: 49 MCP tools, 99 REST endpoints, 573 tests passing * docs: add AGENTS.md, fix tool/endpoint counts across README, plugin, cli - Create AGENTS.md with strict consistency rules for MCP tools, REST endpoints, versions, KV scopes, and audit operations - Fix MCP tool count: 38 → 41 across README.md (4 occurrences) - Fix REST endpoint count: 93/95 → 99 across README.md and index.ts - Fix plugin.json: version 0.6.1 → 0.7.0, tool count 5 → 41 - Fix cli.ts help text: 48+ → 41 MCP tools - Fix README api.ts path reference → triggers/api.ts * fix: address code review findings — consolidation guard, decay bug, async fs, export-import lessons Inline fixes: - Revert CONSOLIDATION_ENABLED to opt-in (=== "true"), matching original behavior - Add early-exit guard in consolidation-pipeline handler when disabled - Gate session-end crystallize+consolidation calls on CONSOLIDATION_ENABLED - Fix lesson decay over-decay bug: add lastDecayedAt to Lesson, compute incremental delta instead of reapplying full age every sweep run - Add LESSON_DECAY_ENABLED flag (default true) to gate the sweep timer Outside diff fixes: - Add lessons to export-import (export + import + replace cleanup) - Log warning instead of swallowing obsidian auto-export errors Nitpick fixes: - Switch obsidian-export to async fs/promises (mkdir, writeFile) - Add per-item try/catch in obsidian-export, return errors array - Replace governance_delete with smart_search in ESSENTIAL_TOOLS (non-destructive default) - Fix CLI whichBinary for Windows (uses "where" on win32) - Use dynamic port in CLI error message instead of hardcoded 3111 - Return 201 for newly created lessons, 200 for strengthened - Wrap lesson audit calls in try/catch so audit failure doesn't surface - Fix build script to not swallow tsdown failure - Remove exact tool count from test, use >=41 + uniqueness + required names - Add test/consistency.test.ts: validates version, tool count, README consistency - Add isConsolidationEnabled mock to consolidation-pipeline test 579 tests passing (573 original + 6 new consistency checks) * fix: guard remaining audit calls, correct endpoint count, add CI + npm publish Review fixes: - Wrap lesson_recall and lesson_strengthen audit calls in try/catch - Fix REST endpoint count: 99 → 100 (verified via grep) across index.ts, README.md, and AGENTS.md - Use regex in consistency test for README assertions (flexible phrasing) - Add consolidation gate tests: disabled returns early, force=true bypasses CI/CD: - Add .github/workflows/ci.yml — test on Node 18/20/22 - Add .github/workflows/publish.yml — auto-publish to npm on GitHub release (uses NPM_TOKEN secret + provenance) Nitpick: - Single-char term filter (t.length > 1) kept intentionally — prevents noise from single-letter matches; documented in AGENTS.md if needed 581 tests passing * fix(ci): add --legacy-peer-deps for zod v3/v4 peer conflict @anthropic-ai/claude-agent-sdk@0.2.56 requires zod@^4.0.0 as a peer dependency but the project uses zod@^3.23.0. The lock file resolves this locally but npm ci is strict about peer deps in CI. * fix(ci): drop Node 18 from matrix — tsdown requires Node 20+ tsdown/rolldown uses node:util.styleText which is only available in Node 20.12+. Updated engines field to >=20.0.0 to match. * fix(ci): add inlineOnly: false to tsdown config, target node20 tsdown errors on CI with "Consider adding inlineOnly option" when dependencies are bundled. Setting inlineOnly: false suppresses this. Also updated target from node18 to node20 to match engines field. |
||
|
|
134cf96124 |
feat: agentmemory v0.4.0 — the memory layer for all AI coding agents (#9)
* feat: agentmemory v0.4.0 — the memory layer for all AI coding agents 7 new features: Claude Code memory bridge, standalone cross-agent MCP server, knowledge graph with entity extraction, 4-tier memory consolidation pipeline, team/shared memory, memory governance with audit trail, git-versioned snapshots. 33 functions, 18 MCP tools, 6 MCP resources, 3 MCP prompts, 49 REST endpoints, 21 KV scopes, 216 tests. All features opt-in via env vars. * fix: address 28 CodeRabbit findings across v0.4.0 codebase Critical: Fix bin path mismatch (dist/mcp-standalone.mjs -> dist/standalone.mjs) Bugs: Fix procedural decay, parseFloat||0.5 for zero values, snapshot restore missing graphNodes/observations, git catch too broad, N+1 graph query, BFS duplicate edges, array mutation in audit sort, date validation Improvements: Lazy readline in transport, JSON-RPC validation, persist error handling, ID collision prevention, defensive null coalescing for concepts/files, Windows backslash support in config, direction required for bridge sync tool, try-catch for audit/governance MCP, team profile fallback teamId, POST body for bridge sync hook, observations validation for graph-extract endpoint, await in test |
||
|
|
4c334b0a0e |
fix: system audit -- 10 bugs found and resolved
1. events.ts: Event triggers were calling api:: functions which require ApiRequest shape and auth headers. Rewrote to call core functions (kv.set, sdk.trigger) directly, bypassing auth. 2. All 5 hooks: Missing AGENTMEMORY_SECRET auth header. If secret was set, every hook would get 401 from the API. Now all hooks read AGENTMEMORY_SECRET and send Bearer token. 3. observe.ts: stripPrivateData on JSON string could break JSON structure when replacement text differs in length. Added try/catch fallback to string coercion. 4. post-tool-use.ts: truncate() for objects did JSON.parse(str.slice(0, max-1) + '}') which produces invalid JSON in nearly all cases. Changed to return truncated string. 5. compress.ts: LLM-returned importance was not clamped to 1-10 range. Added Math.max(1, Math.min(10, ...)) with NaN fallback. 6. compress.ts: LLM-returned observation type was not validated against ObservationType union. Invalid types now fall back to "other". 7. context.ts: Token estimate for observation blocks only counted inner content, not the "## Session..." header. Fixed to estimate the full block text. 8. viewer: WebSocket port now configurable via ?wsPort= query param for non-default III_STREAMS_PORT configurations. 9. plugin/scripts: Rebuilt with auth header support matching the updated hook source files. |
||
|
|
6df02d3e20 |
add plugin marketplace install support
- Add .claude-plugin/marketplace.json for /plugin marketplace add
- Build hook scripts into plugin/scripts/ (self-contained)
- Fix hooks.json to use ${CLAUDE_PLUGIN_ROOT} paths
- Update README with plugin install as primary quick start
|