ITool implementation that stores a new memory trace in the agent's SQLite brain database.

Usage:

const tool = new MemoryAddTool(brain);
const result = await tool.execute(
{ content: 'User prefers dark mode.', tags: ['preference', 'ui'] },
context,
);
// result.output.traceId → 'mt_3f2b8c1e-5d4a-4e6f-9b7c-2a1d0e8f6c5b'

Implements

  • ITool<MemoryAddInput, MemoryAddOutput>

Constructors

  • Parameters

    • brain: Brain

      The agent's shared SQLite brain database connection.

    • Optional writeBack: MemoryToolWriteBack

      The facade that made the tool (Memory.createTools()), through which a write a learning layer does not keep is taken back. Without it the tool deletes the row itself.

    Returns MemoryAddTool

Methods

  • The refusal a write meets whatever a human would answer, read before the tool orchestrator's approval gate (ITool.refusalBeforeApproval), so no one is asked to approve a write that cannot act: a freeze, and, with the turn's scope ids on the call, an organization trace, a thread trace with nothing to file it under, and a session that records no writes. execute refuses the same call itself, in the same order; a type or scope outside the input schema's lists is left to it.

    Parameters

    • args: Record<string, any>

      The call's arguments, before the input schema is checked.

    • context: ToolExecutionContext

      The call's context.

    Returns undefined | ToolExecutionResult<MemoryAddOutput>

    The refusal, or undefined when the call may run.

  • Insert a new memory trace row into memory_traces.

    Defaults applied when optional fields are absent:

    • type → 'episodic'
    • scope → 'user'
    • tags → []

    The trace is created with strength = 1.0 (maximum encoding strength) and deleted = 0 (active). No embedding is computed here — the background EmbeddingEncoder will embed it asynchronously.

    A type or scope outside the input schema's lists is refused with an error result and nothing is stored. A caller that runs the tool without checking its arguments against the schema gets the same answer.

    Where a learning layer put the turn's scope ids on the call, the trace goes under the turn's own user, persona or thread scope id, names the turn's second user (turnUserId), and the write runs through the learner session's recorder; an organization trace is refused (organization_scope). Only a freeze stops a write, with a layer or without one (frozen).

    Parameters

    • args: MemoryAddInput

      Memory add input (content, optional type/scope/tags).

    • context: ToolExecutionContext

      Tool execution context used to resolve the scope ID.

    Returns Promise<ToolExecutionResult<MemoryAddOutput>>

    { traceId } on success, or an error result.

Properties

id: "memory-add-v1" = 'memory-add-v1'

Globally unique tool identifier.

name: "memory_add" = 'memory_add'

LLM-facing tool name (snake_case, as the LLM will call it).

displayName: "Add Memory" = 'Add Memory'

Human-readable display name for UIs and logs.

description: "Store a new memory trace. The agent calls this to remember important facts, decisions, or observations." = 'Store a new memory trace. The agent calls this to remember important facts, decisions, or observations.'

Description shown to the LLM when deciding which tool to invoke. Must be comprehensive enough for the model to understand when to call this.

category: "memory" = 'memory'

Logical category for discovery and grouping.

hasSideEffects: true = true

This tool writes to the database. Callers may request confirmation before execution when hasSideEffects = true.

inputSchema: JSONSchemaObject = ...

JSON schema for input validation and LLM tool-call construction. All optional fields default gracefully inside execute().