Skip to content

Commit 248b89d

Browse files
Merge dev into main for v0.4.2 release
2 parents d28bb9e + 68cb675 commit 248b89d

20 files changed

Lines changed: 653 additions & 160 deletions
Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
---
2+
name: Neotoma Harness Hooks Integration
3+
overview: Extract Neotoma's core operations into an importable client library and build native hook/middleware adapters for programmatic agent frameworks (Claude Agent SDK, OpenAI Agents SDK, Vercel AI SDK, LangChain/LangGraph), replacing MCP as the integration mechanism for these harnesses.
4+
todos:
5+
- id: extract-core-ops
6+
content: Extract executeTool operations from src/server.ts into importable src/core/operations.ts module
7+
status: pending
8+
- id: ts-client
9+
content: Create @neotoma/client TypeScript package with HTTP and local transports
10+
status: pending
11+
- id: py-client
12+
content: Create neotoma-client Python package (HTTP transport, aligned with openapi.yaml)
13+
status: pending
14+
- id: vercel-adapter
15+
content: Build @neotoma/vercel-ai middleware adapter (transformParams + wrapGenerate)
16+
status: pending
17+
- id: claude-sdk-adapter
18+
content: Build @neotoma/claude-agent-sdk hooks adapter (SessionStart, PostToolUse, Stop)
19+
status: pending
20+
- id: openai-agents-adapter
21+
content: Build neotoma-openai-agents Python RunHooks adapter
22+
status: pending
23+
- id: langchain-adapter
24+
content: Build @neotoma/langchain callback handler and optional Store adapter
25+
status: pending
26+
- id: docs-and-site
27+
content: Add hook integration guides and update site subpages to show hooks as primary path for programmatic SDKs
28+
status: pending
29+
isProject: false
30+
---
31+
32+
# Neotoma Harness Hooks Integration
33+
34+
## Problem
35+
36+
Neotoma currently integrates with all harnesses exclusively via MCP (Model Context Protocol). For programmatic agent SDKs -- where developers write code and control the agent loop -- MCP adds unnecessary protocol overhead and configuration friction. These frameworks have native hook/middleware/callback systems designed for exactly this kind of integration.
37+
38+
## Target Frameworks and Their Hook Surfaces
39+
40+
- **Vercel AI SDK (TypeScript):** `wrapLanguageModel` middleware with `transformParams`, `wrapGenerate`, `wrapStream`; plus `onStepFinish`/`onFinish` callbacks
41+
- **Claude Agent SDK (TypeScript + Python):** `PreToolUse`, `PostToolUse`, `SessionStart`, `SessionEnd`, `Stop`, `UserPromptSubmit` hooks via `ClaudeAgentOptions.hooks`
42+
- **OpenAI Agents SDK (Python):** `RunHooks` / `AgentHooks` with `on_agent_start/end`, `on_llm_start/end`, `on_tool_start/end`, `on_handoff`
43+
- **LangChain/LangGraph (TypeScript + Python):** `BaseCallbackHandler` with `on_llm_start/end`, `on_tool_start/end`; plus `Store` interface for long-term memory
44+
45+
## Language Recommendation
46+
47+
**TypeScript first** (matches Neotoma codebase, covers Vercel AI SDK + Claude Agent SDK TS + LangChain.js). **Python second** (covers OpenAI Agents SDK + Claude Agent SDK Python + LangGraph Python). The client library needs both from the start since OpenAI Agents SDK is Python-primary.
48+
49+
## Architecture
50+
51+
```mermaid
52+
flowchart TD
53+
subgraph frameworks [Agent Frameworks]
54+
VercelAI[Vercel AI SDK]
55+
ClaudeSDK[Claude Agent SDK]
56+
OpenAISDK[OpenAI Agents SDK]
57+
LangChain[LangChain/LangGraph]
58+
end
59+
60+
subgraph adapters [Hook Adapters]
61+
VercelAdapter["@neotoma/vercel-ai"]
62+
ClaudeAdapter["@neotoma/claude-agent-sdk"]
63+
OpenAIAdapter["neotoma-openai-agents"]
64+
LangChainAdapter["@neotoma/langchain"]
65+
end
66+
67+
subgraph client [Client Library]
68+
TSClient["@neotoma/client (TS)"]
69+
PyClient["neotoma-client (Python)"]
70+
end
71+
72+
subgraph transport [Transport]
73+
LocalImport["Local import (in-process)"]
74+
HTTP["REST API (HTTP)"]
75+
end
76+
77+
subgraph neotoma [Neotoma Core]
78+
CoreAPI["Exported core operations"]
79+
Server["API server (src/actions.ts)"]
80+
end
81+
82+
VercelAI --> VercelAdapter
83+
ClaudeSDK --> ClaudeAdapter
84+
OpenAISDK --> OpenAIAdapter
85+
LangChain --> LangChainAdapter
86+
87+
VercelAdapter --> TSClient
88+
ClaudeAdapter --> TSClient
89+
OpenAIAdapter --> PyClient
90+
LangChainAdapter --> TSClient
91+
LangChainAdapter --> PyClient
92+
93+
TSClient --> LocalImport
94+
TSClient --> HTTP
95+
PyClient --> HTTP
96+
97+
LocalImport --> CoreAPI
98+
HTTP --> Server
99+
Server --> CoreAPI
100+
```
101+
102+
## Key Files to Change / Create
103+
104+
### Phase 1: Core Client Library
105+
106+
**Problem:** Neotoma's domain logic is only accessible via MCP (`src/server.ts` `executeTool`) or CLI. No importable API exists.
107+
108+
- **Extract core operations** from [`src/server.ts`](src/server.ts) `executeTool` (line ~1714) into a standalone module (e.g. `src/core/operations.ts`) that can be imported directly without MCP protocol
109+
- **Create `@neotoma/client` package** in `packages/client/` -- a TypeScript client that can use either:
110+
- **Local transport:** Direct import of core operations (in-process, no HTTP)
111+
- **HTTP transport:** REST calls to the API server via `openapi.yaml` contract
112+
- **Create `neotoma-client` Python package** in `packages/client-python/` -- HTTP-only client generated from or aligned with `openapi.yaml`
113+
- **Update `package.json` exports** to expose the core operations module
114+
115+
### Phase 2: Framework Hook Adapters (TypeScript first)
116+
117+
Each adapter is a thin package that depends on `@neotoma/client` and implements the framework's native hook interface.
118+
119+
**`@neotoma/vercel-ai`** (in `packages/vercel-ai/`):
120+
- Implements `LanguageModelV3Middleware` with:
121+
- `transformParams`: retrieves relevant entities from Neotoma and injects as system prompt context
122+
- `wrapGenerate` / `wrapStream`: stores conversation turns and extracts entities after each generation
123+
- Exports `createNeotomaMiddleware(config)` and `onStepFinish` / `onFinish` callback helpers
124+
125+
**`@neotoma/claude-agent-sdk`** (in `packages/claude-agent-sdk/`):
126+
- Provides hook functions for `ClaudeAgentOptions.hooks`:
127+
- `SessionStart`: initializes Neotoma session, retrieves prior context
128+
- `PostToolUse`: stores tool results as observations with provenance
129+
- `Stop`: persists final conversation state
130+
- Exports `createNeotomaHooks(config)` returning a hooks object
131+
132+
**`@neotoma/langchain`** (in `packages/langchain/`):
133+
- Implements `BaseCallbackHandler` with `on_llm_end` / `on_tool_end` for persistence
134+
- Optionally implements LangGraph `Store` interface so Neotoma serves as the long-term memory backend
135+
136+
### Phase 3: Python Adapters
137+
138+
**`neotoma-openai-agents`** (in `packages/openai-agents-python/`):
139+
- Subclasses `RunHooks` with:
140+
- `on_agent_start`: retrieves context from Neotoma
141+
- `on_agent_end`: stores final output
142+
- `on_tool_end`: stores tool results
143+
- `on_handoff`: records agent handoff provenance
144+
- Exports `NeotomaRunHooks(client, session_id)` and `NeotomaAgentHooks(client)`
145+
146+
**`neotoma-claude-agent-sdk-python`** (in `packages/claude-agent-sdk-python/`):
147+
- Same hook pattern as TypeScript but for `claude_agent_sdk` Python package
148+
149+
### Phase 4: Documentation and Site
150+
151+
- Add integration guide docs in `docs/developer/hooks/` for each framework
152+
- Update existing subpages (e.g. `NeotomaWithClaudeAgentSdkPage.tsx`) to show hooks as the primary integration path (MCP as alternative)
153+
- Add new subpages for Vercel AI SDK, OpenAI Agents SDK, LangChain if they don't exist
154+
- Update `docs/developer/mcp_overview.md` to position MCP for IDE tools, hooks for programmatic SDKs
155+
156+
## What Each Hook Does (Across All Frameworks)
157+
158+
Regardless of framework, every Neotoma hook adapter provides these capabilities:
159+
160+
- **Context retrieval:** Before LLM calls, retrieve relevant entities from Neotoma and inject into the prompt/context (replaces the "bounded retrieval" step from MCP instructions)
161+
- **Turn persistence:** After each agent step/turn, store the conversation as `agent_message` entities with `PART_OF` relationships to a `conversation` entity (replaces the mandatory store-first rule from MCP instructions)
162+
- **Entity extraction:** Parse agent outputs for mentions of people, tasks, events, etc. and store as structured entities with `REFERS_TO` relationships
163+
- **Provenance tagging:** Every observation stored includes `data_source` metadata identifying the framework, agent, session, and timestamp
164+
- **Idempotency:** Use turn-based idempotency keys (`conversation-{id}-{turn}-{ts}`) consistent with existing MCP conventions
165+
166+
## Relationship to MCP
167+
168+
This does NOT replace MCP. The integration matrix becomes:
169+
170+
- **IDE/chat tools (Cursor, Claude Code, ChatGPT, Codex, OpenClaw):** MCP remains the only path -- these are closed applications
171+
- **Programmatic SDKs (Vercel AI, Claude Agent SDK, OpenAI Agents, LangChain):** Native hooks become the primary recommended path; MCP remains available as fallback
172+
173+
## Monorepo Structure
174+
175+
```
176+
packages/
177+
client/ # @neotoma/client (TypeScript)
178+
src/
179+
index.ts
180+
transports/
181+
http.ts # REST API transport
182+
local.ts # In-process import transport
183+
operations.ts # Typed operation wrappers
184+
package.json
185+
client-python/ # neotoma-client (Python)
186+
neotoma_client/
187+
__init__.py
188+
client.py
189+
transport.py
190+
pyproject.toml
191+
vercel-ai/ # @neotoma/vercel-ai
192+
src/
193+
middleware.ts
194+
callbacks.ts
195+
package.json
196+
claude-agent-sdk/ # @neotoma/claude-agent-sdk (TS)
197+
src/
198+
hooks.ts
199+
package.json
200+
openai-agents-python/ # neotoma-openai-agents (Python)
201+
neotoma_openai_agents/
202+
hooks.py
203+
pyproject.toml
204+
langchain/ # @neotoma/langchain (TS + Python)
205+
src/
206+
callback_handler.ts
207+
store.ts
208+
package.json
209+
```
210+
211+
## Risks and Mitigations
212+
213+
- **API stability:** Framework hook APIs may change. Pin to specific SDK versions and document compatibility.
214+
- **Scope creep:** Start with store/retrieve in hooks; do NOT implement strategy/execution logic in adapters (State Layer boundary).
215+
- **Duplicate persistence:** If a developer uses both hooks AND MCP, idempotency keys prevent duplicate storage.
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
---
2+
name: Revised Neotoma Hooks Plan
3+
overview: Revise the Neotoma hooks integration plan to prioritize CLI/IDE tool hooks (Claude Code, Cursor, OpenCode, Codex) as the primary targets, update the Wooders analysis report with corrected findings, and build a client library as the shared foundation.
4+
todos:
5+
- id: update-wooders-report
6+
content: Update wooders_memory_harness_argument_analysis.md with corrected findings about CLI/IDE hook support, OpenCode compaction control, Hindsight competitive validation, and revised force assessment
7+
status: pending
8+
- id: extract-core-ops
9+
content: Extract executeTool operations from src/server.ts into importable src/core/operations.ts module
10+
status: pending
11+
- id: ts-client
12+
content: Create @neotoma/client TypeScript package with HTTP and local transports
13+
status: pending
14+
- id: py-client
15+
content: Create neotoma-client Python package (HTTP transport)
16+
status: pending
17+
- id: claude-code-plugin
18+
content: Build Claude Code hook plugin (SessionStart, UserPromptSubmit recall, PostToolUse, Stop retain, PreCompact) with plugin marketplace distribution
19+
status: pending
20+
- id: cursor-hooks
21+
content: Build Cursor hooks.json + scripts for sessionStart, beforeSubmitPrompt, afterFileEdit, stop
22+
status: pending
23+
- id: opencode-plugin
24+
content: Build OpenCode TypeScript plugin with tool.execute.before/after, session hooks, and experimental.chat.system.transform
25+
status: pending
26+
- id: codex-hooks
27+
content: Build Codex CLI SessionStart/Stop hooks; monitor for PreToolUse/PostToolUse availability
28+
status: pending
29+
- id: claude-sdk-adapter
30+
content: Build Claude Agent SDK reference hook adapter (lower priority, building mode)
31+
status: pending
32+
- id: docs-and-site
33+
content: Add hook integration guides, update site subpages to show hooks as primary integration for CLI/IDE tools
34+
status: pending
35+
isProject: false
36+
---
37+
38+
# Revised Neotoma Hooks Integration Plan
39+
40+
## What Changed
41+
42+
The original plan incorrectly categorized CLI/IDE tools (Cursor, Claude Code, Codex) as "closed applications where MCP is the only path." All four primary ICP tools support lifecycle hooks:
43+
44+
- **Claude Code:** 12+ events, plugin marketplace, 4 handler types
45+
- **Cursor:** 14+ events (beta), `.cursor/hooks.json`
46+
- **OpenCode:** 20+ events via TypeScript plugin system, including system prompt injection and compaction control
47+
- **Codex CLI:** `SessionStart`/`Stop` (experimental), `PreToolUse`/`PostToolUse` in active development
48+
49+
Hindsight (8.8K stars) already validates this pattern for Claude Code with a hook-based memory plugin. This shifts hooks from serving ~1/3 of the primary ICP's workflow (building mode) to serving all three operational modes.
50+
51+
## Revised Architecture
52+
53+
```mermaid
54+
flowchart TD
55+
subgraph daily [Daily ICP Tools - Hooks]
56+
ClaudeCode["Claude Code (plugin)"]
57+
CursorIDE["Cursor (hooks.json)"]
58+
OpenCodeTool["OpenCode (TS plugin)"]
59+
CodexCLI["Codex CLI (hooks.json)"]
60+
end
61+
62+
subgraph programmatic [Programmatic SDKs - Hooks]
63+
ClaudeSDK["Claude Agent SDK"]
64+
VercelAI["Vercel AI SDK"]
65+
end
66+
67+
subgraph mcpOnly [MCP Only]
68+
ChatGPT["ChatGPT"]
69+
end
70+
71+
subgraph neotomaLayer [Neotoma Layer]
72+
Client["@neotoma/client (TS + Python)"]
73+
CoreOps["Core operations module"]
74+
end
75+
76+
ClaudeCode --> Client
77+
CursorIDE --> Client
78+
OpenCodeTool --> Client
79+
CodexCLI --> Client
80+
ClaudeSDK --> Client
81+
VercelAI --> Client
82+
83+
Client -->|"local import"| CoreOps
84+
Client -->|"HTTP"| CoreOps
85+
```
86+
87+
## Phase 1: Client Library (foundation for all hooks)
88+
89+
Extract core operations from [`src/server.ts`](src/server.ts) `executeTool` (~line 1714) into an importable module. Build `@neotoma/client` (TypeScript) with HTTP and local transports.
90+
91+
- **`src/core/operations.ts`** — standalone module wrapping store, retrieve, create_relationship, etc.
92+
- **`packages/client/`**`@neotoma/client` npm package with typed wrappers
93+
- **`packages/client-python/`**`neotoma-client` pip package (HTTP only)
94+
- Update [`package.json`](package.json) exports to expose core operations
95+
96+
## Phase 2: Claude Code Hook Plugin (highest priority)
97+
98+
Build a Claude Code plugin distributed via `claude plugin marketplace add`. Follows the same pattern Hindsight uses (validated at 8.8K stars).
99+
100+
**Hook mapping:**
101+
102+
| Hook | Neotoma behavior |
103+
|---|---|
104+
| `SessionStart` | Initialize session, retrieve recent entities for context |
105+
| `UserPromptSubmit` | Retrieve relevant entities, inject as `additionalContext` |
106+
| `PostToolUse` | Store tool results as observations with provenance (session_id, tool_name, timestamp) |
107+
| `Stop` | Persist full conversation turn (agent_message entities, PART_OF conversation) |
108+
| `PreCompact` | Observe what will be compacted; ensure critical entities are already persisted |
109+
110+
**Distribution:** `.claude-plugin/` directory structure per Claude Code plugin spec. Shell command handlers calling `@neotoma/client`. Config in `~/.hindsight/claude-code.json` pattern (adapted: `~/.neotoma/claude-code.json`).
111+
112+
**Key file:** `packages/claude-code-plugin/` with `hooks/` directory containing `session_start.py`, `recall.py` (UserPromptSubmit), `retain.py` (Stop), `post_tool_use.py`.
113+
114+
## Phase 3: Cursor Hook Integration
115+
116+
Build a `.cursor/hooks.json` configuration and companion scripts.
117+
118+
**Hook mapping:**
119+
120+
| Hook | Neotoma behavior |
121+
|---|---|
122+
| `sessionStart` | Retrieve recent entities |
123+
| `beforeSubmitPrompt` | Inject Neotoma context into prompt |
124+
| `afterFileEdit` | Store file edit observations with provenance |
125+
| `afterShellExecution` | Store command results as observations |
126+
| `stop` | Persist conversation turn |
127+
| `preCompact` | Observe compaction |
128+
129+
**Distribution:** Installable via npm script or manual `.cursor/hooks.json` + scripts directory. Could also be a Cursor skill.
130+
131+
**Key file:** `packages/cursor-hooks/` with `hooks.json` template and `scripts/` directory.
132+
133+
## Phase 4: OpenCode Plugin
134+
135+
Build a TypeScript plugin for OpenCode's plugin system. OpenCode is the richest hook surface — `experimental.chat.system.transform` for system prompt injection and `experimental.session.compacting` for compaction control.
136+
137+
**Key file:** `packages/opencode-plugin/` with TypeScript plugin exporting hook handlers.
138+
139+
## Phase 5: Codex CLI Hooks (when PreToolUse/PostToolUse land)
140+
141+
Monitor Codex hook engine development. Build `SessionStart`/`Stop` hooks now; add `PreToolUse`/`PostToolUse` when available.
142+
143+
**Key file:** `packages/codex-hooks/` with `hooks.json` template.
144+
145+
## Phase 6: Update Wooders Analysis Report
146+
147+
Update [`docs/private/competitive/wooders_memory_harness_argument_analysis.md`](docs/private/competitive/wooders_memory_harness_argument_analysis.md) with:
148+
149+
- Corrected finding: CLI/IDE tools DO support hooks, contradicting the "closed applications" assumption
150+
- OpenCode's `experimental.session.compacting` and `experimental.chat.system.transform` directly address two of Wooders' "invisible decisions" (compaction and system prompt)
151+
- Claude Code's `PreCompact` hook observes compaction
152+
- Hindsight (8.8K stars) as competitive validation that hook-based memory integration works
153+
- Revised force assessment: Wooders' argument is weaker than initially assessed because hooks ARE giving external tools access to harness-level decisions
154+
- Hindsight as a direct competitor to add to competitive tracking (Neotoma differentiators: deterministic state, cross-tool, field-level provenance vs Hindsight's biomimetic learning-focused memory)
155+
156+
## Phase 7: Programmatic SDK Adapters (lower priority)
157+
158+
Build reference integrations for Claude Agent SDK and optionally Vercel AI SDK. These serve the building mode and secondary ICP (toolchain integrators). Lower priority than the CLI/IDE hooks that serve daily usage.
159+
160+
## What Each Hook Does (Across All Tools)
161+
162+
Consistent behavior regardless of which tool:
163+
164+
- **Context retrieval:** Before each prompt/LLM call, retrieve relevant entities and inject as context
165+
- **Turn persistence:** After each agent step, store the conversation as agent_message entities
166+
- **Observation capture:** After tool use, store results as observations with full provenance (tool_name, session_id, timestamp, source harness)
167+
- **Compaction awareness:** Before compaction, ensure critical state is persisted to Neotoma (survives what the harness destroys)
168+
- **Cross-tool consistency:** Same entities accessible from any tool — the defining value prop over Hindsight and harness-native memory
169+
170+
## Competitive Positioning vs Hindsight
171+
172+
Hindsight validates the hook-based integration pattern but has different architectural properties:
173+
174+
| Property | Hindsight | Neotoma |
175+
|---|---|---|
176+
| Memory model | Biomimetic (world facts, experiences, mental models) | Deterministic (schema-bound entities, append-only observations) |
177+
| Learning | LLM-driven reflection and mental model formation | No inference — stores what is provided, deterministically |
178+
| Cross-tool | Claude Code, OpenClaw, LangGraph (separate integrations, separate banks) | Unified state across all tools via shared entity store |
179+
| Provenance | Not a primary concern | Field-level provenance on every observation |
180+
| Versioning | Not mentioned | Append-only observations, temporal queries |
181+
| State guarantees | Probabilistic (LLM-extracted) | Deterministic (schema-validated, hash-based IDs) |

0 commit comments

Comments
 (0)