Skip to main content
The @atomicmemory/openai-agents adapter wires AtomicMemory into agent runs built with the OpenAI Agents SDK for TypeScript. It does not replace the SDK’s own Session implementations — AtomicMemory is long-term semantic memory, while Session remains useful for short-term conversation state within a run. The two coexist. The adapter exposes four primitives you can compose to fit your specific run pattern, from a single one-call wrapper to individual retrieve and ingest operations.

Installation

pnpm add @atomicmemory/openai-agents @atomicmemory/sdk

Four primitives at a glance

runWithMemory()

One-call wrapper: search → prepend context → run agent → ingest turn. Best for simple flows.

augmentInputWithMemory()

Search AtomicMemory and prepend a system() message with retrieved context to the agent input.

ingestAgentTurn()

Persist the completed turn after run(). System messages excluded by default.

createMemoryTools()

Create memory_search and memory_ingest as agent function tools the model can call during a run.

One-call wrapper — runWithMemory

runWithMemory is the simplest integration. It retrieves relevant memories, prepends context to the agent input, runs your agent, and persists the completed turn — all in a single await:
import { MemoryClient } from '@atomicmemory/sdk';
import { Agent, run } from '@openai/agents';
import { runWithMemory } from '@atomicmemory/openai-agents';

const memory = new MemoryClient({
  providers: {
    atomicmemory: {
      apiUrl: process.env.ATOMICMEMORY_API_URL!,
      apiKey: process.env.ATOMICMEMORY_API_KEY,
    },
  },
  defaultProvider: 'atomicmemory',
});
await memory.initialize();

const agent = new Agent({
  name: 'Assistant',
  instructions: 'You are a helpful assistant.',
});

const { result, retrieved } = await runWithMemory({
  client: memory,
  scope: { user: 'user-123', namespace: 'support' },
  input: 'What did we decide about billing retries?',
  run: (input) => run(agent, input),
});

console.log(result.finalOutput, retrieved.length);

Agent-callable memory tools — createMemoryTools

When you want the model to decide when to search or store memory during a run, attach the tool pair to your agent. The tools are standard OpenAI Agents SDK function tools:
import { Agent } from '@openai/agents';
import { createMemoryTools } from '@atomicmemory/openai-agents';

const agent = new Agent({
  name: 'Assistant',
  instructions:
    'Use memory tools when prior context or durable learning matters.',
  tools: createMemoryTools(memory, {
    scope: { user: 'user-123', namespace: 'support' },
    metadata: { source: 'openai-agents-tool' },
  }),
});
Retrieved memories are injected as reference context only. The adapter’s default prompt explicitly instructs the model not to follow instructions embedded in retrieved memories.

Manual retrieve and ingest — augmentInputWithMemory and ingestAgentTurn

When you need more control, use the two primitives separately. augmentInputWithMemory prepends a system() message when matches exist; ingestAgentTurn persists the completed turn:
import { augmentInputWithMemory, ingestAgentTurn } from '@atomicmemory/openai-agents';

const scope = { user: 'user-123' };

const { input: augmented, retrieved } = await augmentInputWithMemory(memory, {
  scope,
  input: 'What should I remember?',
});

const result = await run(agent, augmented);

await ingestAgentTurn(memory, {
  scope,
  input: augmented,
  result,
  metadata: { source: 'openai-agents', event: 'run_completed' },
});

Persisting streamed results

For streamed runs, wait for the stream to complete and pass the output text explicitly:
const stream = await run(agent, input, { stream: true });
await stream.completed;

await ingestAgentTurn(memory, {
  scope,
  input,
  output: String(stream.finalOutput ?? ''),
});
ingestAgentTurn requires text output. For structured outputs, it serializes finalOutput as JSON automatically unless you pass an explicit output string.

System-message handling on ingest

System messages are excluded from ingest by default — they typically contain hidden instructions and policies that should not become durable memory. The adapter appends the assistant output as the final assistant message in the stored turn.

Scope

Scope fields follow the SDK’s Scope type: user, agent, namespace, and thread. At least one field must be provided — the SDK rejects scopeless requests.
AtomicMemory and the OpenAI Agents SDK Session serve different purposes and work well together. Use Session for within-run conversation state (short-term context) and AtomicMemory for facts, preferences, and decisions that should persist across runs (long-term semantic memory).