Class: ClaudeMemory::Ingest::Ingester

Inherits:
Object
  • Object
show all
Defined in:
lib/claude_memory/ingest/ingester.rb

Overview

Delta-based transcript ingestion with cursor tracking. Reads new content from transcripts, extracts metadata and tool calls, sanitizes private tags, and persists to the content_items table with FTS indexing.

Instance Method Summary collapse

Constructor Details

#initialize(store, fts: nil, env: ENV, metadata_extractor: nil, tool_extractor: nil, tool_filter: nil, observation_compressor: nil) ⇒ Ingester

Returns a new instance of Ingester.

Parameters:

  • store (Store::SQLiteStore)

    database store for persistence

  • fts (Index::LexicalFTS, nil) (defaults to: nil)

    full-text search index (default: new from store)

  • env (Hash) (defaults to: ENV)

    environment variables

  • metadata_extractor (MetadataExtractor, nil) (defaults to: nil)

    extracts git branch, cwd, etc.

  • tool_extractor (ToolExtractor, nil) (defaults to: nil)

    extracts tool calls from transcript text

  • tool_filter (ToolFilter, nil) (defaults to: nil)

    filters irrelevant tool calls

  • observation_compressor (ObservationCompressor, nil) (defaults to: nil)

    compresses tool observations



18
19
20
21
22
23
24
25
26
# File 'lib/claude_memory/ingest/ingester.rb', line 18

def initialize(store, fts: nil, env: ENV, metadata_extractor: nil, tool_extractor: nil, tool_filter: nil, observation_compressor: nil)
  @store = store
  @fts = fts || Index::LexicalFTS.new(store)
  @config = Configuration.new(env)
  @metadata_extractor =  || MetadataExtractor.new
  @tool_extractor = tool_extractor || ToolExtractor.new
  @tool_filter = tool_filter || ToolFilter.new
  @observation_compressor = observation_compressor || ObservationCompressor.new
end

Instance Method Details

#ingest(source:, session_id:, transcript_path:, project_path: nil) ⇒ Hash

Ingest new content from a transcript file

Parameters:

  • source (String)

    content source identifier (e.g., “hook”, “cli”)

  • session_id (String)

    Claude session ID

  • transcript_path (String)

    path to the transcript file

  • project_path (String, nil) (defaults to: nil)

    project root (defaults to detected path)

Returns:

  • (Hash)

    result with :status (:ingested, :skipped, or :no_change), :content_id, :bytes_read, and optional :reason



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/claude_memory/ingest/ingester.rb', line 35

def ingest(source:, session_id:, transcript_path:, project_path: nil)
  unless should_ingest?(transcript_path)
    ClaudeMemory.logger.debug("ingest", message: "Skipped unchanged file", transcript_path: transcript_path)
    return {status: :skipped, bytes_read: 0, reason: "unchanged"}
  end

  prepared = prepare_delta(session_id, transcript_path, project_path)
  return {status: :no_change, bytes_read: 0} if prepared.nil?
  return {status: :skipped, bytes_read: 0, reason: "session_excluded"} if prepared == :excluded

  content_id = persist_content(source, session_id, transcript_path, prepared)

  log_ingestion(content_id, prepared, session_id)
  {status: :ingested, content_id: content_id, bytes_read: prepared[:delta].bytesize, project_path: prepared[:project_path]}
end