@neo4j-labs/agent-memory 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/integrations/strands.ts"],"names":[],"mappings":"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","file":"strands.js","sourcesContent":["/**\n * Strands Agents SDK integration — three orthogonal surfaces, exposed\n * through a single subpath.\n *\n * 1. {@link Neo4jSessionStorage} — implements `SnapshotStorage` so\n * Strands' `SessionManager` persists session state into a NAMS\n * conversation. Hybrid mapping: messages from each snapshot land as\n * real `Message` graph nodes via `addMessage`; the rest of the\n * framework's per-snapshot state is stashed losslessly in synthetic\n * Strands marker messages on that same conversation.\n *\n * 2. {@link Neo4jConversationManager} — a `ConversationManager`\n * subclass that delegates `reduce()` to an inner manager\n * (defaults to `SlidingWindowConversationManager`) AND registers\n * a `BeforeInvocationEvent` hook that prepends three-tier context\n * (reflections + observations from `getContext()`) to every model\n * call. Layered, not replacing — recent-history trimming still\n * behaves the way the inner manager defines.\n *\n * 3. {@link registerReasoningHooks} — wires Strands hook events to\n * our reasoning subclient. Each invocation opens a `ReasoningStep`;\n * each tool call records against that step.\n *\n * {@link connectMemoryToAgent} bundles all three for the common case.\n *\n * Strands lives in `devDependencies` only — every import below is a\n * type-only import, erased at compile time. The published\n * `dist/integrations/strands.js` has no runtime reference to\n * `@strands-agents/sdk`, so users without Strands installed pay zero\n * bundle cost.\n *\n * @example\n * ```ts\n * import { Agent } from \"@strands-agents/sdk\";\n * import { MemoryClient } from \"@neo4j-labs/agent-memory\";\n * import { connectMemoryToAgent } from \"@neo4j-labs/agent-memory/integrations/strands\";\n *\n * const memory = new MemoryClient();\n * const conv = await memory.shortTerm.createConversation({ userId: \"alice\" });\n *\n * const agent = new Agent({\n * ...await connectMemoryToAgent(memory, { conversationId: conv.id }),\n * model,\n * tools: [...],\n * });\n *\n * await agent.invoke(\"Tell me about graph databases.\");\n * ```\n */\n\nimport type {\n BeforeInvocationEvent as BeforeInvocationEventType,\n AfterInvocationEvent as AfterInvocationEventType,\n BeforeToolCallEvent as BeforeToolCallEventType,\n AfterToolCallEvent as AfterToolCallEventType,\n LocalAgent,\n Message as StrandsMessage,\n Snapshot,\n SnapshotManifest,\n SnapshotStorage,\n SnapshotLocation,\n ConversationManager as StrandsConversationManager,\n ConversationManagerReduceOptions,\n SlidingWindowConversationManager as SlidingWindowConversationManagerType,\n SessionManager as SessionManagerType,\n SessionManagerConfig,\n} from \"@strands-agents/sdk\";\n\nimport type { MemoryClient } from \"../client.js\";\nimport type { MessageRole } from \"../types.js\";\n\n// ---------------------------------------------------------------------------\n// Strands runtime imports are deferred to a small loader so callers who use\n// only types still pay zero runtime cost. Callers who instantiate the\n// classes below MUST have @strands-agents/sdk installed in their own\n// dependencies — same contract as every other duck-typed integration.\n// ---------------------------------------------------------------------------\n\ntype StrandsModule = typeof import(\"@strands-agents/sdk\");\n\nlet _strandsModule: StrandsModule | null = null;\n\nasync function loadStrands(): Promise<StrandsModule> {\n if (!_strandsModule) {\n // Dynamic import keeps the static export graph free of @strands-agents/sdk.\n _strandsModule = (await import(\"@strands-agents/sdk\")) as StrandsModule;\n }\n return _strandsModule;\n}\n\n// ---------------------------------------------------------------------------\n// Public options\n// ---------------------------------------------------------------------------\n\n/** Options shared by every public entrypoint in this module. */\nexport interface StrandsIntegrationOptions {\n /**\n * NAMS Conversation id to wire to. Required by the convenience factory and\n * by individual exports that need correlation across invocations.\n */\n conversationId: string;\n\n /** Include reflections from `getContext()` in prompt injection. Default: true. */\n includeReflections?: boolean;\n\n /** Include observations from `getContext()` in prompt injection. Default: true. */\n includeObservations?: boolean;\n}\n\n/** Options for {@link Neo4jConversationManager}. */\nexport interface Neo4jConversationManagerOptions\n extends Pick<StrandsIntegrationOptions, \"conversationId\" | \"includeReflections\" | \"includeObservations\"> {\n /**\n * Inner `ConversationManager` to delegate `reduce()` to. When omitted,\n * defaults to `SlidingWindowConversationManager` (constructed lazily so\n * Strands' module is only loaded if the manager is actually used).\n */\n inner?: StrandsConversationManager;\n}\n\n/** Options for {@link registerReasoningHooks}. */\nexport interface ReasoningHooksOptions {\n /** NAMS Conversation id to attribute reasoning steps and tool calls to. */\n conversationId: string;\n}\n\n// ---------------------------------------------------------------------------\n// SnapshotStorage\n// ---------------------------------------------------------------------------\n\n/**\n * Strands snapshot state is persisted as synthetic `role: \"user\"`\n * messages on the NAMS conversation. NAMS exposes no conversation-\n * metadata-update endpoint, so we use the only write surface that\n * works robustly: a message whose `content` carries both the marker\n * prefix AND the JSON-serialized blob, base64-encoded for safety.\n *\n * The historical choice of `role: \"system\"` + per-message metadata was\n * abandoned after live-service testing showed that NAMS' GET\n * /conversations/{id}/messages either filters out `system`-role\n * messages or doesn't surface per-message metadata on read (or both).\n * `role: \"user\"` is universally preserved, and stuffing the blob inline\n * in `content` removes the dependency on metadata round-tripping.\n *\n * Each distinct snapshot state writes ONE synthetic message:\n *\n * { role: \"user\", content: \"__strands_state__:{base64(JSON.stringify(blob))}\" }\n *\n * Manifests use a parallel prefix `__strands_manifest__:`. Consumers\n * walking the message list MUST filter these out — see\n * {@link isSyntheticStrandsMessage}. Strands' agent loop never sees\n * them because {@link Neo4jSessionStorage.loadSnapshot} strips them\n * before returning the reconstructed Snapshot.\n *\n * Per-snapshot synthetic messages mean `listSnapshotIds` is O(n) over\n * the message list, but repeated idempotent saves short-circuit when the\n * latest stored blob already matches. In practice snapshots are small\n * JSON deltas and the conversation's message count is bounded — fine for v0.x.\n */\nconst STATE_PREFIX = \"__strands_state__:\";\nconst MANIFEST_PREFIX = \"__strands_manifest__:\";\n\n/** Role used for synthetic state messages. */\nconst SYNTHETIC_ROLE: MessageRole = \"user\";\n\nfunction encodeBlob(blob: unknown): string {\n return base64Encode(JSON.stringify(blob));\n}\n\nfunction decodeBlob<T>(content: string, prefix: string): T | null {\n if (!content.startsWith(prefix)) return null;\n const payload = content.slice(prefix.length);\n try {\n return JSON.parse(base64Decode(payload)) as T;\n } catch {\n return null;\n }\n}\n\nfunction base64Encode(s: string): string {\n // Use Buffer when available (Node, Bun, edge runtimes with shims),\n // else fall back to a btoa-on-UTF8 path for purer browser-like runtimes.\n if (typeof Buffer !== \"undefined\") {\n return Buffer.from(s, \"utf8\").toString(\"base64\");\n }\n // eslint-disable-next-line no-restricted-globals\n const g = globalThis as { btoa?: (s: string) => string };\n if (typeof g.btoa === \"function\") {\n // btoa requires Latin-1; wrap UTF-8 bytes first.\n const bytes = new TextEncoder().encode(s);\n let bin = \"\";\n for (const b of bytes) bin += String.fromCharCode(b);\n return g.btoa(bin);\n }\n throw new Error(\"No base64 encoder available in this runtime\");\n}\n\nfunction base64Decode(b64: string): string {\n if (typeof Buffer !== \"undefined\") {\n return Buffer.from(b64, \"base64\").toString(\"utf8\");\n }\n // eslint-disable-next-line no-restricted-globals\n const g = globalThis as { atob?: (s: string) => string };\n if (typeof g.atob === \"function\") {\n const bin = g.atob(b64);\n const bytes = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i);\n return new TextDecoder().decode(bytes);\n }\n throw new Error(\"No base64 decoder available in this runtime\");\n}\n\ninterface StrandsStateBlob {\n /** snapshotId associated with this synthetic message. */\n snapshotId: string;\n /** Whether this save asserted itself as the latest. */\n isLatest: boolean;\n /** Snapshot data with messages stripped. */\n snapshot: Snapshot;\n /** Wall-clock save time (ISO 8601). Tie-breaker for \"latest\" elections. */\n savedAt: string;\n}\n\ninterface StrandsManifestBlob {\n /** SnapshotLocation.scopeId so multiple agents per session can co-exist. */\n scopeId: string;\n manifest: SnapshotManifest;\n savedAt: string;\n}\n\n/**\n * Returns true if a message is one of our synthetic state/manifest\n * markers. Exported so consumers walking the conversation can filter\n * them out of UI rendering. See `SYNTHETIC_MESSAGE_PREFIXES` for the\n * canonical prefix list.\n *\n * Recognizes ANY role — the storage role used by the integration is\n * `\"user\"`, but older saves may have used `\"system\"`. We match on the\n * content prefix alone for resilience.\n */\nexport function isSyntheticStrandsMessage(\n message: { role: string; content: string },\n): boolean {\n return (\n message.content.startsWith(STATE_PREFIX) ||\n message.content.startsWith(MANIFEST_PREFIX)\n );\n}\n\n/**\n * Canonical content prefixes used for synthetic messages. Consumers\n * (chat UIs, message-list renderers, Cypher queries) can filter on\n * these to skip the Strands-internal state messages.\n */\nexport const SYNTHETIC_MESSAGE_PREFIXES = [STATE_PREFIX, MANIFEST_PREFIX] as const;\n\n/**\n * Implements Strands' `SnapshotStorage` against a NAMS `MemoryClient`.\n *\n * One Strands session = one NAMS Conversation (keyed by `location.sessionId`).\n * Snapshots are versions within that conversation:\n *\n * - Real conversation messages from `snapshot.data.messages` land as real\n * `Message` graph nodes via `addMessage` (so entity extraction, search,\n * and the graph view all work on them).\n * - Non-message snapshot state (Strands' `data` minus `messages`, plus\n * `appData`, plus the manifest) is persisted as synthetic `role: \"user\"`\n * messages whose content carries both a marker prefix and a\n * base64-encoded JSON blob. NAMS exposes `POST /conversations/{id}/messages`\n * as the only documented conversation-scoped write, so this approach\n * stays within the documented API surface.\n *\n * Consumers walking the message list (chat UIs, Cypher queries) MUST\n * filter synthetic messages with {@link isSyntheticStrandsMessage}.\n * Strands itself never sees them: {@link Neo4jSessionStorage.loadSnapshot}\n * strips them from the reconstructed Snapshot before handing back to\n * `SessionManager`.\n *\n * Auth errors propagate — Strands needs to know if the backing store is\n * unreachable. Transient errors propagate too; Strands' own retry\n * semantics (in `SessionManager`) apply.\n */\nexport class Neo4jSessionStorage implements SnapshotStorage {\n constructor(private readonly memory: MemoryClient) {}\n\n async saveSnapshot(params: {\n location: SnapshotLocation;\n snapshotId: string;\n isLatest: boolean;\n snapshot: Snapshot;\n }): Promise<void> {\n const { location, snapshotId, isLatest, snapshot } = params;\n const conversationId = location.sessionId;\n const existingConversation = await this.memory.shortTerm.getConversation(conversationId);\n\n // 1. Extract conversation messages out of snapshot.data.messages and\n // persist any new ones as real Message nodes. Dedupe by role+content\n // so re-saving the same snapshot doesn't grow the message list.\n await this.extractAndPersistMessages(conversationId, snapshot, existingConversation.messages);\n\n // 2. Write a synthetic user message whose content carries the full\n // state blob (base64-encoded JSON after the marker prefix).\n const strippedSnapshot = stripMessagesFromSnapshot(snapshot);\n const blob: StrandsStateBlob = {\n snapshotId,\n isLatest,\n snapshot: strippedSnapshot,\n savedAt: new Date().toISOString(),\n };\n const previous = findLastStateBlobForSnapshotId(\n this.readStateBlobs(existingConversation.messages),\n snapshotId,\n );\n if (previous && sameStateBlob(previous, blob)) return;\n await this.memory.shortTerm.addMessage(\n conversationId,\n SYNTHETIC_ROLE,\n `${STATE_PREFIX}${encodeBlob(blob)}`,\n );\n }\n\n async loadSnapshot(params: {\n location: SnapshotLocation;\n snapshotId?: string;\n }): Promise<Snapshot | null> {\n const conversationId = params.location.sessionId;\n const conv = await this.memory.shortTerm.getConversation(conversationId);\n\n const stateBlobs = this.readStateBlobs(conv.messages);\n if (stateBlobs.length === 0) return null;\n\n // If a snapshotId was requested, find that specific save.\n // Otherwise fall back to the most recent save where isLatest=true,\n // or the latest save overall if none asserted \"latest\".\n let blob: StrandsStateBlob | undefined;\n if (params.snapshotId) {\n blob = findLastStateBlobForSnapshotId(stateBlobs, params.snapshotId);\n } else {\n blob = [...stateBlobs].reverse().find((b) => b.isLatest) ??\n stateBlobs[stateBlobs.length - 1];\n }\n if (!blob) return null;\n\n // Re-hydrate the snapshot: combine the stored data/appData with the\n // current conversation messages (filtered to drop our synthetic\n // markers so Strands doesn't replay them).\n const realMessages = conv.messages\n .filter((m) => !isSyntheticStrandsMessage(m))\n .map(toStrandsMessage);\n return mergeMessagesIntoSnapshot(blob.snapshot, realMessages);\n }\n\n async listSnapshotIds(params: {\n location: SnapshotLocation;\n limit?: number;\n startAfter?: string;\n }): Promise<string[]> {\n const conv = await this.memory.shortTerm.getConversation(params.location.sessionId);\n const stateBlobs = this.readStateBlobs(conv.messages);\n // Preserve save order. Dedupe per snapshotId in case a snapshotId is\n // saved more than once (Strands' contract permits re-saves).\n const seen = new Set<string>();\n const ids: string[] = [];\n for (const blob of stateBlobs) {\n if (seen.has(blob.snapshotId)) continue;\n seen.add(blob.snapshotId);\n ids.push(blob.snapshotId);\n }\n let start = 0;\n if (params.startAfter) {\n const idx = ids.indexOf(params.startAfter);\n start = idx >= 0 ? idx + 1 : 0;\n }\n return ids.slice(start, params.limit ? start + params.limit : undefined);\n }\n\n async deleteSession(params: { sessionId: string }): Promise<void> {\n await this.memory.shortTerm.deleteConversation(params.sessionId);\n }\n\n async loadManifest(params: { location: SnapshotLocation }): Promise<SnapshotManifest> {\n const conv = await this.memory.shortTerm.getConversation(params.location.sessionId);\n const blobs = this.readManifestBlobs(conv.messages);\n // Last write wins per scopeId — Strands writes manifests rarely so the\n // O(n) scan is fine.\n const matching = blobs.filter((b) => b.scopeId === params.location.scopeId);\n return matching[matching.length - 1]?.manifest ?? defaultManifest();\n }\n\n async saveManifest(params: {\n location: SnapshotLocation;\n manifest: SnapshotManifest;\n }): Promise<void> {\n const blob: StrandsManifestBlob = {\n scopeId: params.location.scopeId,\n manifest: params.manifest,\n savedAt: new Date().toISOString(),\n };\n await this.memory.shortTerm.addMessage(\n params.location.sessionId,\n SYNTHETIC_ROLE,\n `${MANIFEST_PREFIX}${encodeBlob(blob)}`,\n );\n }\n\n // --- Internals ------------------------------------------------------------\n\n /**\n * Scan a conversation's message list and parse any state markers into\n * blobs, in original order. Matches on the content prefix alone for\n * resilience against role normalization on the service side.\n */\n private readStateBlobs(\n messages: Array<{ role: string; content: string }>,\n ): StrandsStateBlob[] {\n const blobs: StrandsStateBlob[] = [];\n for (const msg of messages) {\n const blob = decodeBlob<StrandsStateBlob>(msg.content, STATE_PREFIX);\n if (blob) blobs.push(blob);\n }\n return blobs;\n }\n\n /** Same idea, for manifest markers. */\n private readManifestBlobs(\n messages: Array<{ role: string; content: string }>,\n ): StrandsManifestBlob[] {\n const blobs: StrandsManifestBlob[] = [];\n for (const msg of messages) {\n const blob = decodeBlob<StrandsManifestBlob>(msg.content, MANIFEST_PREFIX);\n if (blob) blobs.push(blob);\n }\n return blobs;\n }\n\n /**\n * Pull the message list out of `snapshot.data.messages` (the canonical\n * Strands layout), find ones not yet present on the conversation\n * (excluding our synthetic markers), and persist them via `addMessage`.\n * Returns the number of new messages written.\n */\n private async extractAndPersistMessages(\n conversationId: string,\n snapshot: Snapshot,\n existingMessages?: Array<{ role: string; content: string }>,\n ): Promise<number> {\n const messages = pickStrandsMessages(snapshot);\n if (messages.length === 0) return 0;\n\n const seen = new Set(\n (existingMessages ??\n (await this.memory.shortTerm.getConversation(conversationId)).messages)\n .filter((m) => !isSyntheticStrandsMessage(m))\n .map((m) => `${m.role}::${m.content}`),\n );\n\n let writes = 0;\n for (const msg of messages) {\n const text = strandsMessageToText(msg);\n const key = `${msg.role}::${text}`;\n if (seen.has(key)) continue;\n seen.add(key);\n await this.memory.shortTerm.addMessage(conversationId, msg.role as MessageRole, text);\n writes++;\n }\n return writes;\n }\n}\n\n// ---------------------------------------------------------------------------\n// ConversationManager\n// ---------------------------------------------------------------------------\n\n/**\n * Layered ConversationManager: context-injection hook + inner manager.\n *\n * The inner manager (defaults to `SlidingWindowConversationManager`) owns\n * trimming and summarization. This manager registers a\n * `BeforeInvocationEvent` hook that prepends reflections + observations from\n * `getContext()` as system messages, BEFORE the inner manager's reduce\n * logic runs.\n *\n * Lazily constructs an inner manager on first `initAgent` invocation so\n * importing this module doesn't load Strands' runtime unless the manager\n * is actually used.\n */\nexport class Neo4jConversationManager {\n public readonly name = \"neo4j:context-injection\";\n /**\n * Mirrored from Strands' `ConversationManager` to satisfy duck-typing\n * at compile time. We never set it — context injection has no notion\n * of a compression threshold.\n */\n protected readonly _compressionThreshold: number | undefined = undefined;\n\n // We can't extend Strands' abstract class via a static `extends` clause\n // because Strands is a dynamic import — the base class identity isn't\n // known at module-load time. Instead we *delegate* to a lazily-built\n // inner manager and implement the abstract surface explicitly. Strands\n // duck-types on shape, not on instanceof, so this works.\n\n private inner: StrandsConversationManager | null = null;\n\n constructor(\n private readonly memory: MemoryClient,\n private readonly options: Neo4jConversationManagerOptions,\n ) {}\n\n async reduce(opts: ConversationManagerReduceOptions): Promise<boolean> {\n const inner = await this.ensureInner();\n return inner.reduce(opts);\n }\n\n async initAgent(agent: LocalAgent): Promise<void> {\n const inner = await this.ensureInner();\n inner.initAgent(agent);\n\n const strands = await loadStrands();\n // Register a hook to inject three-tier context BEFORE every model call.\n agent.addHook(\n strands.BeforeInvocationEvent,\n async (event: BeforeInvocationEventType) => {\n await this.injectContext(event);\n },\n );\n }\n\n private async ensureInner(): Promise<StrandsConversationManager> {\n if (this.inner) return this.inner;\n if (this.options.inner) {\n this.inner = this.options.inner;\n return this.inner;\n }\n const strands = await loadStrands();\n const Ctor =\n strands.SlidingWindowConversationManager as new () => SlidingWindowConversationManagerType;\n this.inner = new Ctor();\n return this.inner;\n }\n\n private async injectContext(event: BeforeInvocationEventType): Promise<void> {\n try {\n const ctx = await this.memory.shortTerm.getContext(this.options.conversationId);\n const prepend: StrandsMessage[] = [];\n const includeReflections = this.options.includeReflections ?? true;\n const includeObservations = this.options.includeObservations ?? true;\n\n if (includeReflections && ctx.reflections.length > 0) {\n for (const r of ctx.reflections) {\n prepend.push(contextInjectionMessage(`[reflection] ${r.content}`));\n }\n }\n if (includeObservations && ctx.observations.length > 0) {\n for (const o of ctx.observations) {\n prepend.push(contextInjectionMessage(`[observation] ${o.content}`));\n }\n }\n\n if (prepend.length === 0) return;\n\n // Prepend by mutating agent.messages in place. The order MUST be\n // [context...] + [existing messages...]. Strands' inner manager\n // may later trim from the head — that's intentional (these\n // injections aren't sacred; staleness > overflow).\n const agentLike = event.agent as unknown as { messages: StrandsMessage[] };\n agentLike.messages = [...prepend, ...agentLike.messages];\n } catch {\n // Context injection is best-effort. A failed getContext() (transient,\n // not-supported, etc.) must not break the agent run — we just fall\n // back to whatever the inner manager produces.\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Reasoning hooks\n// ---------------------------------------------------------------------------\n\n/** Key in `invocationState` where the current reasoning step id is stashed. */\nconst INVOCATION_STEP_ID_KEY = \"__neo4jReasoningStepId\";\n/** Key in `invocationState` where the per-invocation tool-call → toolCallId map lives. */\nconst TOOL_CALL_MAP_KEY = \"__neo4jReasoningToolCalls\";\n\n/**\n * Wire reasoning capture onto a Strands `HookRegistry`.\n *\n * - `BeforeInvocationEvent` → `reasoning.recordStep` (opens a step; stashes\n * step id on `event.invocationState`).\n * - `AfterInvocationEvent` → re-records the step with a `result` field\n * (best-effort; we don't have a public `updateStep` API yet, so the\n * second write supplements rather than mutates).\n * - `BeforeToolCallEvent` → `reasoning.recordToolCall` with status\n * `pending`. Strands tool-call id → our tool-call id map stashed on\n * `invocationState`.\n * - `AfterToolCallEvent` → updates the recorded tool call's status.\n *\n * All capture is best-effort: every reasoning write is wrapped in try/catch\n * and silently swallowed on failure. Reasoning capture must never break the\n * agent run.\n */\nexport async function registerReasoningHooks(\n memory: MemoryClient,\n agent: LocalAgent,\n options: ReasoningHooksOptions,\n): Promise<void> {\n return registerReasoningHooksOnAgent(memory, agent, options);\n}\n\nasync function registerReasoningHooksOnAgent(\n memory: MemoryClient,\n agent: LocalAgent,\n options: ReasoningHooksOptions,\n): Promise<void> {\n const strands = await loadStrands();\n const conversationId = options.conversationId;\n\n agent.addHook(strands.BeforeInvocationEvent, async (event: BeforeInvocationEventType) => {\n try {\n const step = await memory.reasoning.recordStep({\n conversationId,\n reasoning: \"agent invocation started\",\n actionTaken: \"invoke_agent\",\n });\n (event.invocationState as Record<string, unknown>)[INVOCATION_STEP_ID_KEY] = step.id;\n (event.invocationState as Record<string, unknown>)[TOOL_CALL_MAP_KEY] = new Map<\n string,\n string\n >();\n } catch {\n /* best-effort */\n }\n });\n\n agent.addHook(strands.AfterInvocationEvent, async (event: AfterInvocationEventType) => {\n try {\n const stepId = (event.invocationState as Record<string, unknown>)[INVOCATION_STEP_ID_KEY];\n if (typeof stepId !== \"string\") return;\n // Record a follow-up step with the result, since the current\n // reasoning API doesn't expose updateStep. This is intentional —\n // the after-invocation marker is a separate point in the trace.\n await memory.reasoning.recordStep({\n conversationId,\n reasoning: `agent invocation completed (step ${stepId})`,\n actionTaken: \"invocation_complete\",\n result: \"ok\",\n });\n } catch {\n /* best-effort */\n }\n });\n\n agent.addHook(strands.BeforeToolCallEvent, async (event: BeforeToolCallEventType) => {\n try {\n const stepId = (event.invocationState as Record<string, unknown>)[INVOCATION_STEP_ID_KEY];\n if (typeof stepId !== \"string\") return;\n const toolCall = await memory.reasoning.recordToolCall(\n stepId,\n event.toolUse.name,\n event.toolUse.input as Record<string, unknown>,\n { status: \"pending\" },\n );\n const map = (event.invocationState as Record<string, unknown>)[TOOL_CALL_MAP_KEY];\n if (map instanceof Map) {\n map.set(event.toolUse.toolUseId, toolCall.id);\n }\n } catch {\n /* best-effort */\n }\n });\n\n agent.addHook(strands.AfterToolCallEvent, async (event: AfterToolCallEventType) => {\n try {\n const stepId = (event.invocationState as Record<string, unknown>)[INVOCATION_STEP_ID_KEY];\n if (typeof stepId !== \"string\") return;\n // We don't have a public updateToolCall API yet either — record a\n // follow-up tool-call entry with the resolved status. Pair-up via\n // the same toolUseId-keyed map for future updateToolCall support.\n await memory.reasoning.recordToolCall(\n stepId,\n event.toolUse.name,\n event.toolUse.input as Record<string, unknown>,\n {\n status: event.error ? \"failure\" : \"success\",\n error: event.error?.message,\n },\n );\n } catch {\n /* best-effort */\n }\n });\n}\n\n// ---------------------------------------------------------------------------\n// Convenience factory\n// ---------------------------------------------------------------------------\n\n/** Result of {@link connectMemoryToAgent} — spread directly into `new Agent({ ... })`. */\nexport interface ConnectMemoryToAgentResult {\n sessionManager: SessionManagerType;\n /**\n * Typed as `StrandsConversationManager` (the abstract base) so callers\n * can spread the result straight into `new Agent({ ... })` without\n * casts. At runtime this is a {@link Neo4jConversationManager}.\n */\n conversationManager: StrandsConversationManager;\n}\n\n/**\n * One-shot helper that wires the SessionStorage, the ConversationManager, and\n * (lazily) the reasoning hooks against a NAMS `MemoryClient`. Spread the\n * return value into `new Agent({ ... })`.\n *\n * Reasoning hooks attach themselves automatically when the conversation\n * manager's `initAgent` runs — no separate registration step required.\n */\nexport async function connectMemoryToAgent(\n memory: MemoryClient,\n options: StrandsIntegrationOptions,\n): Promise<ConnectMemoryToAgentResult> {\n const strands = await loadStrands();\n const sessionManager = new strands.SessionManager({\n sessionId: options.conversationId,\n storage: { snapshot: new Neo4jSessionStorage(memory) },\n } satisfies SessionManagerConfig);\n\n // Wrap Neo4jConversationManager so its initAgent ALSO registers the\n // reasoning hooks. Cleaner than asking the caller to do two things.\n const baseManager = new Neo4jConversationManager(memory, options);\n const originalInit = baseManager.initAgent.bind(baseManager);\n baseManager.initAgent = async (agent: LocalAgent) => {\n await originalInit(agent);\n await registerReasoningHooksOnAgent(memory, agent, {\n conversationId: options.conversationId,\n });\n };\n\n return {\n sessionManager,\n conversationManager: baseManager as unknown as StrandsConversationManager,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction defaultManifest(): SnapshotManifest {\n return {\n schemaVersion: \"1.0\",\n updatedAt: new Date().toISOString(),\n };\n}\n\nfunction pickStrandsMessages(snapshot: Snapshot): StrandsMessage[] {\n const data = snapshot.data as { messages?: unknown } | undefined;\n if (!data || !Array.isArray(data.messages)) return [];\n return data.messages as StrandsMessage[];\n}\n\nfunction stripMessagesFromSnapshot(snapshot: Snapshot): Snapshot {\n // Defensive shallow copy; messages live in the graph from here on.\n const nextData = { ...(snapshot.data ?? {}) };\n delete (nextData as Record<string, unknown>).messages;\n return { ...snapshot, data: nextData };\n}\n\nfunction mergeMessagesIntoSnapshot(\n blob: Snapshot,\n messages: StrandsMessage[],\n): Snapshot {\n // Cast through unknown — Snapshot.data is typed as Record<string, JSONValue>\n // but Strands itself stores messages there, so the runtime shape matches.\n return {\n ...blob,\n data: { ...(blob.data ?? {}), messages: messages as unknown as never },\n };\n}\n\nfunction strandsMessageToText(msg: StrandsMessage): string {\n // Strands messages carry ContentBlock[]. Flatten plain-text blocks into a\n // single string; non-text blocks (images, tool uses) are described by tag.\n const blocks = (msg as unknown as { content: unknown[] }).content ?? [];\n if (!Array.isArray(blocks)) return \"\";\n const parts: string[] = [];\n for (const b of blocks) {\n if (b && typeof b === \"object\") {\n const block = b as { text?: unknown; type?: string };\n if (typeof block.text === \"string\") {\n parts.push(block.text);\n } else if (block.type) {\n parts.push(`[${block.type}]`);\n }\n }\n }\n return parts.join(\"\\n\");\n}\n\nfunction toStrandsMessage(m: { role: string; content: string }): StrandsMessage {\n return {\n role: m.role as StrandsMessage[\"role\"],\n content: [{ text: m.content }] as unknown as StrandsMessage[\"content\"],\n } as StrandsMessage;\n}\n\nfunction contextInjectionMessage(text: string): StrandsMessage {\n return {\n role: \"system\" as StrandsMessage[\"role\"],\n content: [{ text }] as unknown as StrandsMessage[\"content\"],\n } as StrandsMessage;\n}\n\nfunction sameStateBlob(a: StrandsStateBlob, b: StrandsStateBlob): boolean {\n return (\n a.snapshotId === b.snapshotId &&\n a.isLatest === b.isLatest &&\n jsonLikeEqual(a.snapshot, b.snapshot)\n );\n}\n\nfunction findLastStateBlobForSnapshotId(\n blobs: StrandsStateBlob[],\n snapshotId: string,\n): StrandsStateBlob | undefined {\n for (let i = blobs.length - 1; i >= 0; i--) {\n if (blobs[i]?.snapshotId === snapshotId) return blobs[i];\n }\n return undefined;\n}\n\nfunction jsonLikeEqual(a: unknown, b: unknown): boolean {\n if (Object.is(a, b)) return true;\n if (typeof a !== typeof b) return false;\n if (Array.isArray(a) || Array.isArray(b)) {\n if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) return false;\n return a.every((value, index) => jsonLikeEqual(value, b[index]));\n }\n if (a && b && typeof a === \"object\" && typeof b === \"object\") {\n const aRecord = a as Record<string, unknown>;\n const bRecord = b as Record<string, unknown>;\n const aKeys = Object.keys(aRecord);\n const bKeys = Object.keys(bRecord);\n if (aKeys.length !== bKeys.length) return false;\n return aKeys.every((key) => key in bRecord && jsonLikeEqual(aRecord[key], bRecord[key]));\n }\n return false;\n}\n"]}
@@ -0,0 +1,53 @@
1
+ import { M as MemoryClient } from '../client-DSqbWQoa.js';
2
+ import '../index-qfRrdQNP.js';
3
+
4
+ /**
5
+ * MCP (Model Context Protocol) tool definitions for neo4j-agent-memory.
6
+ *
7
+ * Mirrors the 12 tools exposed by the hosted MCP server at
8
+ * `https://memory.neo4jlabs.com/mcp`. Use this to either:
9
+ *
10
+ * - Register the same tool surface against your own MCP server, or
11
+ * - Programmatically dispatch tool calls to a `MemoryClient`.
12
+ *
13
+ * The 12 standard tools — `memory_create_conversation`, `memory_add_messages`,
14
+ * `memory_get_context`, `memory_search_messages`, `memory_search_entities`,
15
+ * `memory_get_entity`, `memory_add_entity`, `memory_get_entity_history`,
16
+ * `memory_record_step`, `memory_record_tool_call`, `memory_get_trace`,
17
+ * `memory_explain_decision`.
18
+ *
19
+ * @example
20
+ * ```ts
21
+ * import { MemoryClient } from "@neo4j-labs/agent-memory";
22
+ * import { createMemoryTools, handleMemoryToolCall } from "@neo4j-labs/agent-memory/mcp";
23
+ *
24
+ * const client = new MemoryClient({
25
+ * endpoint: "https://memory.neo4jlabs.com/v1",
26
+ * apiKey: process.env.MEMORY_API_KEY!,
27
+ * });
28
+ *
29
+ * const tools = createMemoryTools(); // 12 standard tools
30
+ * await handleMemoryToolCall(client, "memory_get_context", { conversation_id });
31
+ * ```
32
+ */
33
+
34
+ interface McpToolDefinition {
35
+ name: string;
36
+ description: string;
37
+ inputSchema: {
38
+ type: "object";
39
+ properties: Record<string, unknown>;
40
+ required?: string[];
41
+ };
42
+ }
43
+ /** Build the 12-tool MCP surface that matches memory.neo4jlabs.com/mcp. */
44
+ declare function createMemoryTools(): McpToolDefinition[];
45
+ /**
46
+ * Dispatch one of the 12 standard MCP tool calls to a `MemoryClient`.
47
+ *
48
+ * Old `memory.<verb>` names from v0.1 are kept as deprecated aliases for one
49
+ * minor version; they emit a console warning and forward to the new tool.
50
+ */
51
+ declare function handleMemoryToolCall(client: MemoryClient, toolName: string, args: Record<string, unknown>): Promise<unknown>;
52
+
53
+ export { type McpToolDefinition, createMemoryTools, handleMemoryToolCall };
@@ -0,0 +1,256 @@
1
+ // src/mcp/index.ts
2
+ function createMemoryTools() {
3
+ return [
4
+ // ---- Short-Term -----------------------------------------------------
5
+ {
6
+ name: "memory_create_conversation",
7
+ description: "Create a new conversation session for a user.",
8
+ inputSchema: {
9
+ type: "object",
10
+ properties: {
11
+ user_id: { type: "string", description: "User identifier" },
12
+ metadata: { type: "object", additionalProperties: true }
13
+ },
14
+ required: ["user_id"]
15
+ }
16
+ },
17
+ {
18
+ name: "memory_add_messages",
19
+ description: "Append one or more messages to a conversation.",
20
+ inputSchema: {
21
+ type: "object",
22
+ properties: {
23
+ conversation_id: { type: "string" },
24
+ messages: {
25
+ type: "array",
26
+ items: {
27
+ type: "object",
28
+ properties: {
29
+ role: { type: "string", enum: ["user", "assistant", "system"] },
30
+ content: { type: "string" },
31
+ metadata: { type: "object", additionalProperties: true }
32
+ },
33
+ required: ["role", "content"]
34
+ }
35
+ }
36
+ },
37
+ required: ["conversation_id", "messages"]
38
+ }
39
+ },
40
+ {
41
+ name: "memory_get_context",
42
+ description: "Three-tier context (reflections + observations + recent messages) for a conversation.",
43
+ inputSchema: {
44
+ type: "object",
45
+ properties: {
46
+ conversation_id: { type: "string" }
47
+ },
48
+ required: ["conversation_id"]
49
+ }
50
+ },
51
+ {
52
+ name: "memory_search_messages",
53
+ description: "Search messages within a conversation by similarity or keywords.",
54
+ inputSchema: {
55
+ type: "object",
56
+ properties: {
57
+ conversation_id: { type: "string" },
58
+ query: { type: "string" },
59
+ limit: { type: "number" }
60
+ },
61
+ required: ["conversation_id", "query"]
62
+ }
63
+ },
64
+ // ---- Long-Term ------------------------------------------------------
65
+ {
66
+ name: "memory_search_entities",
67
+ description: "Search the knowledge graph for entities by name or concept.",
68
+ inputSchema: {
69
+ type: "object",
70
+ properties: {
71
+ query: { type: "string" },
72
+ type: { type: "string" },
73
+ limit: { type: "number" }
74
+ },
75
+ required: ["query"]
76
+ }
77
+ },
78
+ {
79
+ name: "memory_get_entity",
80
+ description: "Fetch one entity (with its relationships) by id.",
81
+ inputSchema: {
82
+ type: "object",
83
+ properties: { entity_id: { type: "string" } },
84
+ required: ["entity_id"]
85
+ }
86
+ },
87
+ {
88
+ name: "memory_add_entity",
89
+ description: "Manually create an entity.",
90
+ inputSchema: {
91
+ type: "object",
92
+ properties: {
93
+ name: { type: "string" },
94
+ type: { type: "string" },
95
+ description: { type: "string" }
96
+ },
97
+ required: ["name", "type"]
98
+ }
99
+ },
100
+ {
101
+ name: "memory_get_entity_history",
102
+ description: "All conversations that mentioned this entity.",
103
+ inputSchema: {
104
+ type: "object",
105
+ properties: { entity_id: { type: "string" } },
106
+ required: ["entity_id"]
107
+ }
108
+ },
109
+ // ---- Reasoning ------------------------------------------------------
110
+ {
111
+ name: "memory_record_step",
112
+ description: "Log a reasoning step under a conversation.",
113
+ inputSchema: {
114
+ type: "object",
115
+ properties: {
116
+ conversation_id: { type: "string" },
117
+ reasoning: { type: "string" },
118
+ action_taken: { type: "string" },
119
+ result: { type: "string" }
120
+ },
121
+ required: ["conversation_id", "reasoning", "action_taken"]
122
+ }
123
+ },
124
+ {
125
+ name: "memory_record_tool_call",
126
+ description: "Log a tool invocation tied to a reasoning step.",
127
+ inputSchema: {
128
+ type: "object",
129
+ properties: {
130
+ step_id: { type: "string" },
131
+ tool_name: { type: "string" },
132
+ input: { type: "string" },
133
+ output: { type: "string" },
134
+ status: { type: "string", enum: ["success", "error", "timeout"] },
135
+ duration_ms: { type: "number" }
136
+ },
137
+ required: ["tool_name", "status"]
138
+ }
139
+ },
140
+ {
141
+ name: "memory_get_trace",
142
+ description: "Full reasoning trace for a conversation (steps + tool calls).",
143
+ inputSchema: {
144
+ type: "object",
145
+ properties: { conversation_id: { type: "string" } },
146
+ required: ["conversation_id"]
147
+ }
148
+ },
149
+ {
150
+ name: "memory_explain_decision",
151
+ description: "Detailed explanation of one reasoning step \u2014 tool calls + entities it influenced.",
152
+ inputSchema: {
153
+ type: "object",
154
+ properties: { step_id: { type: "string" } },
155
+ required: ["step_id"]
156
+ }
157
+ }
158
+ ];
159
+ }
160
+ async function handleMemoryToolCall(client, toolName, args) {
161
+ const aliased = LEGACY_ALIASES[toolName];
162
+ if (aliased) {
163
+ if (typeof console !== "undefined") {
164
+ console.warn(
165
+ `[neo4j-agent-memory] MCP tool '${toolName}' is deprecated; use '${aliased}'.`
166
+ );
167
+ }
168
+ toolName = aliased;
169
+ }
170
+ switch (toolName) {
171
+ case "memory_create_conversation":
172
+ return client.shortTerm.createConversation({
173
+ userId: args["user_id"],
174
+ metadata: args["metadata"]
175
+ });
176
+ case "memory_add_messages": {
177
+ const conversationId = args["conversation_id"];
178
+ const msgs = args["messages"];
179
+ if (!msgs || msgs.length === 0) return [];
180
+ if (msgs.length === 1) {
181
+ const m = msgs[0];
182
+ return [
183
+ await client.shortTerm.addMessage(
184
+ conversationId,
185
+ m.role,
186
+ m.content,
187
+ { metadata: m.metadata }
188
+ )
189
+ ];
190
+ }
191
+ return client.shortTerm.bulkAddMessages(
192
+ conversationId,
193
+ msgs.map((m) => ({
194
+ role: m.role,
195
+ content: m.content,
196
+ metadata: m.metadata
197
+ }))
198
+ );
199
+ }
200
+ case "memory_get_context":
201
+ return client.shortTerm.getContext(args["conversation_id"]);
202
+ case "memory_search_messages":
203
+ return client.shortTerm.searchMessages(args["query"], {
204
+ sessionId: args["conversation_id"],
205
+ limit: args["limit"]
206
+ });
207
+ case "memory_search_entities":
208
+ return client.longTerm.searchEntities(args["query"], {
209
+ type: args["type"],
210
+ limit: args["limit"]
211
+ });
212
+ case "memory_get_entity":
213
+ return client.longTerm.getEntity(args["entity_id"]);
214
+ case "memory_add_entity":
215
+ return client.longTerm.addEntity(args["name"], args["type"], {
216
+ description: args["description"]
217
+ });
218
+ case "memory_get_entity_history":
219
+ return client.longTerm.getEntityHistory(args["entity_id"]);
220
+ case "memory_record_step":
221
+ return client.reasoning.recordStep({
222
+ conversationId: args["conversation_id"],
223
+ reasoning: args["reasoning"],
224
+ actionTaken: args["action_taken"],
225
+ result: args["result"]
226
+ });
227
+ case "memory_record_tool_call":
228
+ return client.reasoning.recordToolCall(
229
+ args["step_id"] ?? "",
230
+ args["tool_name"],
231
+ typeof args["input"] === "object" && args["input"] !== null ? args["input"] : { input: args["input"] },
232
+ {
233
+ result: args["output"],
234
+ status: args["status"] ?? "success",
235
+ durationMs: args["duration_ms"]
236
+ }
237
+ );
238
+ case "memory_get_trace":
239
+ return client.reasoning.getTraceByConversation(args["conversation_id"]);
240
+ case "memory_explain_decision":
241
+ return client.reasoning.explainStep(args["step_id"]);
242
+ default:
243
+ throw new Error(`Unknown memory tool: ${toolName}`);
244
+ }
245
+ }
246
+ var LEGACY_ALIASES = {
247
+ "memory.addMessage": "memory_add_messages",
248
+ "memory.getConversation": "memory_get_context",
249
+ "memory.searchMessages": "memory_search_messages",
250
+ "memory.addEntity": "memory_add_entity",
251
+ "memory.searchEntities": "memory_search_entities"
252
+ };
253
+
254
+ export { createMemoryTools, handleMemoryToolCall };
255
+ //# sourceMappingURL=index.js.map
256
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/mcp/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * MCP (Model Context Protocol) tool definitions for neo4j-agent-memory.\n *\n * Mirrors the 12 tools exposed by the hosted MCP server at\n * `https://memory.neo4jlabs.com/mcp`. Use this to either:\n *\n * - Register the same tool surface against your own MCP server, or\n * - Programmatically dispatch tool calls to a `MemoryClient`.\n *\n * The 12 standard tools — `memory_create_conversation`, `memory_add_messages`,\n * `memory_get_context`, `memory_search_messages`, `memory_search_entities`,\n * `memory_get_entity`, `memory_add_entity`, `memory_get_entity_history`,\n * `memory_record_step`, `memory_record_tool_call`, `memory_get_trace`,\n * `memory_explain_decision`.\n *\n * @example\n * ```ts\n * import { MemoryClient } from \"@neo4j-labs/agent-memory\";\n * import { createMemoryTools, handleMemoryToolCall } from \"@neo4j-labs/agent-memory/mcp\";\n *\n * const client = new MemoryClient({\n * endpoint: \"https://memory.neo4jlabs.com/v1\",\n * apiKey: process.env.MEMORY_API_KEY!,\n * });\n *\n * const tools = createMemoryTools(); // 12 standard tools\n * await handleMemoryToolCall(client, \"memory_get_context\", { conversation_id });\n * ```\n */\n\nimport type { MemoryClient } from \"../client.js\";\n\nexport interface McpToolDefinition {\n name: string;\n description: string;\n inputSchema: {\n type: \"object\";\n properties: Record<string, unknown>;\n required?: string[];\n };\n}\n\n/** Build the 12-tool MCP surface that matches memory.neo4jlabs.com/mcp. */\nexport function createMemoryTools(): McpToolDefinition[] {\n return [\n // ---- Short-Term -----------------------------------------------------\n {\n name: \"memory_create_conversation\",\n description: \"Create a new conversation session for a user.\",\n inputSchema: {\n type: \"object\",\n properties: {\n user_id: { type: \"string\", description: \"User identifier\" },\n metadata: { type: \"object\", additionalProperties: true },\n },\n required: [\"user_id\"],\n },\n },\n {\n name: \"memory_add_messages\",\n description: \"Append one or more messages to a conversation.\",\n inputSchema: {\n type: \"object\",\n properties: {\n conversation_id: { type: \"string\" },\n messages: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n role: { type: \"string\", enum: [\"user\", \"assistant\", \"system\"] },\n content: { type: \"string\" },\n metadata: { type: \"object\", additionalProperties: true },\n },\n required: [\"role\", \"content\"],\n },\n },\n },\n required: [\"conversation_id\", \"messages\"],\n },\n },\n {\n name: \"memory_get_context\",\n description:\n \"Three-tier context (reflections + observations + recent messages) for a conversation.\",\n inputSchema: {\n type: \"object\",\n properties: {\n conversation_id: { type: \"string\" },\n },\n required: [\"conversation_id\"],\n },\n },\n {\n name: \"memory_search_messages\",\n description: \"Search messages within a conversation by similarity or keywords.\",\n inputSchema: {\n type: \"object\",\n properties: {\n conversation_id: { type: \"string\" },\n query: { type: \"string\" },\n limit: { type: \"number\" },\n },\n required: [\"conversation_id\", \"query\"],\n },\n },\n // ---- Long-Term ------------------------------------------------------\n {\n name: \"memory_search_entities\",\n description: \"Search the knowledge graph for entities by name or concept.\",\n inputSchema: {\n type: \"object\",\n properties: {\n query: { type: \"string\" },\n type: { type: \"string\" },\n limit: { type: \"number\" },\n },\n required: [\"query\"],\n },\n },\n {\n name: \"memory_get_entity\",\n description: \"Fetch one entity (with its relationships) by id.\",\n inputSchema: {\n type: \"object\",\n properties: { entity_id: { type: \"string\" } },\n required: [\"entity_id\"],\n },\n },\n {\n name: \"memory_add_entity\",\n description: \"Manually create an entity.\",\n inputSchema: {\n type: \"object\",\n properties: {\n name: { type: \"string\" },\n type: { type: \"string\" },\n description: { type: \"string\" },\n },\n required: [\"name\", \"type\"],\n },\n },\n {\n name: \"memory_get_entity_history\",\n description: \"All conversations that mentioned this entity.\",\n inputSchema: {\n type: \"object\",\n properties: { entity_id: { type: \"string\" } },\n required: [\"entity_id\"],\n },\n },\n // ---- Reasoning ------------------------------------------------------\n {\n name: \"memory_record_step\",\n description: \"Log a reasoning step under a conversation.\",\n inputSchema: {\n type: \"object\",\n properties: {\n conversation_id: { type: \"string\" },\n reasoning: { type: \"string\" },\n action_taken: { type: \"string\" },\n result: { type: \"string\" },\n },\n required: [\"conversation_id\", \"reasoning\", \"action_taken\"],\n },\n },\n {\n name: \"memory_record_tool_call\",\n description: \"Log a tool invocation tied to a reasoning step.\",\n inputSchema: {\n type: \"object\",\n properties: {\n step_id: { type: \"string\" },\n tool_name: { type: \"string\" },\n input: { type: \"string\" },\n output: { type: \"string\" },\n status: { type: \"string\", enum: [\"success\", \"error\", \"timeout\"] },\n duration_ms: { type: \"number\" },\n },\n required: [\"tool_name\", \"status\"],\n },\n },\n {\n name: \"memory_get_trace\",\n description: \"Full reasoning trace for a conversation (steps + tool calls).\",\n inputSchema: {\n type: \"object\",\n properties: { conversation_id: { type: \"string\" } },\n required: [\"conversation_id\"],\n },\n },\n {\n name: \"memory_explain_decision\",\n description:\n \"Detailed explanation of one reasoning step — tool calls + entities it influenced.\",\n inputSchema: {\n type: \"object\",\n properties: { step_id: { type: \"string\" } },\n required: [\"step_id\"],\n },\n },\n ];\n}\n\n/**\n * Dispatch one of the 12 standard MCP tool calls to a `MemoryClient`.\n *\n * Old `memory.<verb>` names from v0.1 are kept as deprecated aliases for one\n * minor version; they emit a console warning and forward to the new tool.\n */\nexport async function handleMemoryToolCall(\n client: MemoryClient,\n toolName: string,\n args: Record<string, unknown>,\n): Promise<unknown> {\n const aliased = LEGACY_ALIASES[toolName];\n if (aliased) {\n if (typeof console !== \"undefined\") {\n console.warn(\n `[neo4j-agent-memory] MCP tool '${toolName}' is deprecated; use '${aliased}'.`,\n );\n }\n toolName = aliased;\n }\n\n switch (toolName) {\n case \"memory_create_conversation\":\n return client.shortTerm.createConversation({\n userId: args[\"user_id\"] as string,\n metadata: args[\"metadata\"] as Record<string, unknown> | undefined,\n });\n\n case \"memory_add_messages\": {\n const conversationId = args[\"conversation_id\"] as string;\n const msgs = args[\"messages\"] as\n | Array<{ role: string; content: string; metadata?: Record<string, unknown> }>\n | undefined;\n if (!msgs || msgs.length === 0) return [];\n if (msgs.length === 1) {\n const m = msgs[0]!;\n return [\n await client.shortTerm.addMessage(\n conversationId,\n m.role as \"user\" | \"assistant\" | \"system\",\n m.content,\n { metadata: m.metadata },\n ),\n ];\n }\n return client.shortTerm.bulkAddMessages(\n conversationId,\n msgs.map((m) => ({\n role: m.role as \"user\" | \"assistant\" | \"system\",\n content: m.content,\n metadata: m.metadata,\n })),\n );\n }\n\n case \"memory_get_context\":\n return client.shortTerm.getContext(args[\"conversation_id\"] as string);\n\n case \"memory_search_messages\":\n return client.shortTerm.searchMessages(args[\"query\"] as string, {\n sessionId: args[\"conversation_id\"] as string,\n limit: args[\"limit\"] as number | undefined,\n });\n\n case \"memory_search_entities\":\n return client.longTerm.searchEntities(args[\"query\"] as string, {\n type: args[\"type\"] as string | undefined,\n limit: args[\"limit\"] as number | undefined,\n });\n\n case \"memory_get_entity\":\n return client.longTerm.getEntity(args[\"entity_id\"] as string);\n\n case \"memory_add_entity\":\n return client.longTerm.addEntity(args[\"name\"] as string, args[\"type\"] as string, {\n description: args[\"description\"] as string | undefined,\n });\n\n case \"memory_get_entity_history\":\n return client.longTerm.getEntityHistory(args[\"entity_id\"] as string);\n\n case \"memory_record_step\":\n return client.reasoning.recordStep({\n conversationId: args[\"conversation_id\"] as string,\n reasoning: args[\"reasoning\"] as string,\n actionTaken: args[\"action_taken\"] as string,\n result: args[\"result\"] as string | undefined,\n });\n\n case \"memory_record_tool_call\":\n return client.reasoning.recordToolCall(\n (args[\"step_id\"] as string) ?? \"\",\n args[\"tool_name\"] as string,\n typeof args[\"input\"] === \"object\" && args[\"input\"] !== null\n ? (args[\"input\"] as Record<string, unknown>)\n : { input: args[\"input\"] },\n {\n result: args[\"output\"],\n status: (args[\"status\"] as \"success\" | \"error\" | \"timeout\") ?? \"success\",\n durationMs: args[\"duration_ms\"] as number | undefined,\n },\n );\n\n case \"memory_get_trace\":\n return client.reasoning.getTraceByConversation(args[\"conversation_id\"] as string);\n\n case \"memory_explain_decision\":\n return client.reasoning.explainStep(args[\"step_id\"] as string);\n\n default:\n throw new Error(`Unknown memory tool: ${toolName}`);\n }\n}\n\n/**\n * v0.1 → v0.2 deprecated tool aliases. Will be removed in v0.3.\n */\nconst LEGACY_ALIASES: Record<string, string> = {\n \"memory.addMessage\": \"memory_add_messages\",\n \"memory.getConversation\": \"memory_get_context\",\n \"memory.searchMessages\": \"memory_search_messages\",\n \"memory.addEntity\": \"memory_add_entity\",\n \"memory.searchEntities\": \"memory_search_entities\",\n};\n"]}
@@ -0,0 +1,86 @@
1
+ import { M as MemoryClient } from '../client-DSqbWQoa.js';
2
+ import '../index-qfRrdQNP.js';
3
+
4
+ /**
5
+ * Vercel AI SDK middleware for automatic memory integration.
6
+ *
7
+ * The middleware automatically:
8
+ * - Injects three-tier conversational context (reflections + observations +
9
+ * recent messages) ahead of every model call when a `conversationId` is
10
+ * supplied — falls back to flat history for bridge transports.
11
+ * - Persists the user's input message before generation.
12
+ * - Persists the assistant's response (and tool calls) after generation.
13
+ * - Lazily creates a conversation on first call when the caller didn't
14
+ * pre-create one (only available with RestTransport).
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * import { generateText } from "ai";
19
+ * import { MemoryClient } from "@neo4j-labs/agent-memory";
20
+ * import { agentMemoryMiddleware } from "@neo4j-labs/agent-memory/middleware/vercel-ai";
21
+ *
22
+ * const client = new MemoryClient({
23
+ * endpoint: "https://memory.neo4jlabs.com/v1",
24
+ * apiKey: process.env.MEMORY_API_KEY!,
25
+ * });
26
+ *
27
+ * const middleware = agentMemoryMiddleware(client, {
28
+ * conversationId: "conv-uuid", // or sessionId for bridge transport
29
+ * userId: "alice@example.com", // used if a conversation is created
30
+ * includeContext: true,
31
+ * });
32
+ *
33
+ * const result = await generateText({
34
+ * model: yourModel,
35
+ * experimental_middleware: middleware,
36
+ * messages: [{ role: "user", content: "Hello!" }],
37
+ * });
38
+ * ```
39
+ *
40
+ * Compatible with the Vercel AI SDK v4+ `LanguageModelV1Middleware` shape.
41
+ */
42
+
43
+ interface AgentMemoryMiddlewareOptions {
44
+ /**
45
+ * Conversation id (REST transport) or session id (bridge transport).
46
+ * Can be a string or a function that returns one.
47
+ */
48
+ conversationId?: string | (() => string);
49
+ /** @deprecated Use `conversationId`. Kept for backwards compatibility. */
50
+ sessionId?: string | (() => string);
51
+ /**
52
+ * User id used when lazily creating a conversation. Only consulted if
53
+ * `conversationId` is not supplied and the transport is REST.
54
+ */
55
+ userId?: string;
56
+ /**
57
+ * Include three-tier context (reflections + observations + recent messages).
58
+ * If false, falls back to flat history. Default: true on REST, false on
59
+ * bridge (where context endpoints aren't implemented).
60
+ */
61
+ includeContext?: boolean;
62
+ /** Maximum messages to include from flat history (bridge fallback). */
63
+ historyLimit?: number;
64
+ /** Persist user input before generation. Default: true. */
65
+ persistInput?: boolean;
66
+ /** Persist assistant response after generation. Default: true. */
67
+ persistResponses?: boolean;
68
+ }
69
+ interface AgentMemoryLanguageModelMiddleware {
70
+ transformParams?: (options: {
71
+ params: Record<string, unknown>;
72
+ }) => Promise<Record<string, unknown>>;
73
+ wrapGenerate?: (options: {
74
+ doGenerate: () => Promise<{
75
+ text?: string;
76
+ [key: string]: unknown;
77
+ }>;
78
+ }) => Promise<{
79
+ text?: string;
80
+ [key: string]: unknown;
81
+ }>;
82
+ }
83
+ /** Memory-augmented LanguageModelV1 middleware. */
84
+ declare function agentMemoryMiddleware(client: MemoryClient, options?: AgentMemoryMiddlewareOptions): AgentMemoryLanguageModelMiddleware;
85
+
86
+ export { type AgentMemoryLanguageModelMiddleware, type AgentMemoryMiddlewareOptions, agentMemoryMiddleware };
@@ -0,0 +1,107 @@
1
+ import { NotSupportedError } from '../chunk-ASQMU7YC.js';
2
+
3
+ // src/middleware/vercel-ai.ts
4
+ function resolve(value) {
5
+ if (typeof value === "function") return value();
6
+ return value;
7
+ }
8
+ function agentMemoryMiddleware(client, options) {
9
+ const persistResponses = options?.persistResponses ?? true;
10
+ const persistInput = options?.persistInput ?? true;
11
+ const includeContext = options?.includeContext ?? true;
12
+ let resolvedId = resolve(options?.conversationId) ?? resolve(options?.sessionId);
13
+ async function ensureConversationId() {
14
+ if (resolvedId) return resolvedId;
15
+ try {
16
+ const conv = await client.shortTerm.createConversation({
17
+ userId: options?.userId ?? "anonymous"
18
+ });
19
+ resolvedId = conv.id;
20
+ return resolvedId;
21
+ } catch (err) {
22
+ if (err instanceof NotSupportedError) {
23
+ resolvedId = `session-${cryptoRandom()}`;
24
+ return resolvedId;
25
+ }
26
+ throw err;
27
+ }
28
+ }
29
+ return {
30
+ transformParams: async ({ params }) => {
31
+ const id = await ensureConversationId();
32
+ let historyMessages = [];
33
+ if (includeContext) {
34
+ try {
35
+ const ctx = await client.shortTerm.getContext(id);
36
+ for (const r of ctx.reflections) {
37
+ historyMessages.push({ role: "system", content: `[reflection] ${r.content}` });
38
+ }
39
+ for (const o of ctx.observations) {
40
+ historyMessages.push({ role: "system", content: `[observation] ${o.content}` });
41
+ }
42
+ for (const m of ctx.recentMessages) {
43
+ historyMessages.push({ role: m.role, content: m.content });
44
+ }
45
+ } catch (err) {
46
+ historyMessages = [];
47
+ }
48
+ }
49
+ if (historyMessages.length === 0) {
50
+ try {
51
+ const conv = await client.shortTerm.getConversation(id, {
52
+ limit: options?.historyLimit
53
+ });
54
+ historyMessages = conv.messages.map((msg) => ({
55
+ role: msg.role,
56
+ content: msg.content
57
+ }));
58
+ } catch {
59
+ }
60
+ }
61
+ if (persistInput) {
62
+ const incoming = params["prompt"] ?? [];
63
+ const lastUser = [...incoming].reverse().find((m) => m.role === "user");
64
+ if (lastUser) {
65
+ try {
66
+ await client.shortTerm.addMessage(id, lastUser.role, lastUser.content);
67
+ } catch {
68
+ }
69
+ }
70
+ }
71
+ if (historyMessages.length === 0) return params;
72
+ const existing = params["prompt"] ?? [];
73
+ return {
74
+ ...params,
75
+ prompt: [...historyMessages, ...existing]
76
+ };
77
+ },
78
+ wrapGenerate: async ({ doGenerate }) => {
79
+ const result = await doGenerate();
80
+ if (persistResponses && result.text) {
81
+ const id = await ensureConversationId();
82
+ try {
83
+ await client.shortTerm.addMessage(id, "assistant", result.text);
84
+ } catch {
85
+ }
86
+ }
87
+ return result;
88
+ }
89
+ };
90
+ }
91
+ function cryptoRandom() {
92
+ if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
93
+ return crypto.randomUUID();
94
+ }
95
+ if (typeof crypto !== "undefined" && typeof crypto.getRandomValues === "function") {
96
+ const buf = new Uint8Array(16);
97
+ crypto.getRandomValues(buf);
98
+ return Array.from(buf, (b) => b.toString(16).padStart(2, "0")).join("");
99
+ }
100
+ throw new Error(
101
+ "Secure randomness is unavailable in this runtime; supply an explicit conversationId."
102
+ );
103
+ }
104
+
105
+ export { agentMemoryMiddleware };
106
+ //# sourceMappingURL=vercel-ai.js.map
107
+ //# sourceMappingURL=vercel-ai.js.map