AppGitHub
Context API

ctx.memory

ctx.memory provides access to the strategy memory system, including ingestion, retrieval, and asset reads.

Shape

interface MemoryAPI {
  query(options?: MemoryQueryOptions): Promise<MemoryRecord[]>
  search(query: string, options?: MemorySearchOptions): Promise<MemoryHit[]>
  ingest(
    input: MemoryIngestInput,
    options?: MemoryIngestOptions
  ): Promise<MemoryIngestResult | MemoryIngestResult[]>
  readAsset(asset: Attachment | string, options?: ReadAssetOptions): Promise<string>
  removeMemory(memoryId: string): Promise<{ deleted: boolean }>
}

Overview

ctx.memory provides access to AfferLab's strategy memory system.

It allows strategies to ingest content, query stored memory records, run retrieval, and read back asset content when building prompts.

The runtime handles storage, chunking, indexing, and retrieval internally, so strategies control what to store and how to use it, while the runtime manages storage and retrieval.

Typical use cases include:

  • retrieval augmented generation (RAG)
  • long-term knowledge storage
  • document understanding
  • memory-backed prompt construction
  • conversation summarization

Methods

ingest(input, options?)

Ingests content into memory.

The runtime may parse the input, create an asset, split content into chunks, and optionally index it for semantic retrieval, depending on the input type and options.

input: MemoryIngestInput

Supported inputs include:

  • raw text
  • an asset reference such as { assetId }
  • an inline document payload such as { text, filename, mime }
  • an array of the inputs above

options: MemoryIngestOptions

interface MemoryIngestOptions {

  /**
   * Controls how much processing to wait for before resolving.
   *
   * - 'load' → resolve after content is stored
   * - 'full' → resolve after full processing (including chunking and indexing)
   *
   * Default: 'full'
   */
  wait?: 'load' | 'full'

  /**
   * Defines how the content should be processed.
   *
   * - 'raw'   → store only, no chunking or indexing
   * - 'chunk' → split into chunks, no indexing
   * - 'rag'   → chunk + indexing (for retrieval)
   *
   * Default: 'rag'
   */
  mode?: 'raw' | 'chunk' | 'rag'

  /**
   * Tags used for filtering and categorization.
   */
  tags?: string[]

  /**
   * Arbitrary structured metadata.
   */
  meta?: Record<string, unknown>

}

Return: Promise<MemoryIngestResult | MemoryIngestResult[]> Example:

await ctx.memory.ingest('Project roadmap for 2025', {
  tags: ['roadmap']
})

query(options?)

Returns memory records for the current conversation.

This is used to list or filter stored memory before selecting content to include in the context.

options: MemoryQueryOptions

interface MemoryQueryOptions {

  /**
   * Filters records that contain all specified tags.
   */
  tags?: string[]

  /**
   * Field used for sorting.
   *
   * Default: 'updatedAt'
   */
  orderBy?: 'updatedAt' | 'createdAt'

  /**
   * Sort direction.
   *
   * Default: 'desc'
   */
  order?: 'desc' | 'asc'

  /**
   * Maximum number of records to return.
   *
   * Default: 20
   */
  limit?: number

  /**
   * Number of records to skip.
   *
   * Default: 0
   */
  offset?: number
}

Return: Promise<MemoryRecord[]>

Example:

const items = await ctx.memory.query({
  tags: ['pinned'],
  limit: 20
})

search(query, options?)

Runs retrieval against indexed memory content.

Unlike query, this method performs semantic search and returns ranked results based on relevance.

query: string

The text query used for retrieval.

options: MemorySearchOptions

interface MemorySearchOptions {

  /**
   * Maximum number of results to return.
   *
   * Default: 5
   */
  topK?: number

  /**
   * Filters results by tags.
   */
  tags?: string[]

}

Return: Promise<MemoryHit[]>

Example:

const hits = await ctx.memory.search('project roadmap', {
  topK: 5,
  tags: ['roadmap']
})

readAsset(asset, options?)

Reads the text content of an asset.

This is typically used after query() or search() to retrieve full or partial content for context injection.

asset: Attachment | string

An attachment object or asset id.

options: ReadAssetOptions

interface ReadAssetOptions {

  /**
   * Maximum number of characters to return.
   *
   * Default: undefined
   */
  maxChars?: number
}

Return: Promise<string>

Example:

const content = await ctx.memory.readAsset('asset_123', {
  maxChars: 20000
})

removeMemory(memoryId)

Deletes a specific memory record.

memoryId: string

Return: Promise<{ deleted: boolean }>

Example:

await ctx.memory.removeMemory('memory_123')

Usage

Example: load memory items and inject their contents into the prompt.

export async function onContextBuild(ctx) {
  const items = await ctx.memory.query({
    tags: ['pinned'],
    limit: 10
  })

  const blocks: string[] = []

  for (const item of items) {
    if (!item.assetId) continue
    const content = await ctx.memory.readAsset(item.assetId, { maxChars: 5000 })
    if (content) {
      blocks.push(content)
    }
  }

  if (blocks.length) {
    ctx.slots.add('memory', blocks.join('\n\n'), {
      priority: 2,
      position: 1
    })
  }

  ctx.slots.add('input', ctx.input, {
    priority: 1,
    position: 2
  })

  return ctx.slots.render()
}

Example: ingest a generated summary.

await ctx.memory.ingest(summaryText, {
  tags: ['summary']
})

Notes

ctx.memory is strategy-facing. Strategies do not manage chunking, embedding, or storage internals.

  • query() → structured filtering (list)
  • search() → semantic retrieval (RAG)
  • readAsset() → load full content

Memory should not be relied on as a single source of truth.

On this page