Class: ClaudeMemory::OTel::PromptScope
- Inherits:
-
Object
- Object
- ClaudeMemory::OTel::PromptScope
- Defined in:
- lib/claude_memory/otel/prompt_scope.rb
Overview
Back-tags activity_events with the OTel prompt.id after telemetry events arrive. Hook events (hook_ingest, hook_context, …) fire ~immediately as the user’s turn closes, but Claude Code batches OTel exports on the OTEL_METRIC_EXPORT_INTERVAL (default 60s), so by the time we see a prompt.id on the receiver, the activity_events for that turn already exist with prompt_id = NULL.
Tagging strategy per (prompt_id, session_id) group:
1. session_id-match path — for activity_events carrying the same
session_id, update those that fall in the prompt's time window.
Hook events (hook_ingest, hook_context, hook_sweep, hook_publish,
roi_nudge) reliably carry session_id from the Claude Code hook
payload.
2. time-window path — for activity_events with NULL session_id
(recall, store_extraction — MCP-originated; Claude Code doesn't
thread session_id into plugin MCP calls per reference_mcp_session
_id_gap), tag by occurred_at falling in the prompt window only.
Operates on both project_store and global_store when available. Cross-project tagging (projects other than the dashboard’s loaded one) is out of scope — dashboard is per-project and other project DBs aren’t in the manager.
Constant Summary collapse
- MAX_WINDOW_SECONDS =
Bound the prompt window so a long-running turn doesn’t sweep up later activity events that belong to the NEXT prompt. The OTel spec only emits prompt.id between user_prompt and the next user_prompt, so the natural max is implicit; we add a safety ceiling.
600- POST_WINDOW_BUFFER_SECONDS =
Buffer added after the latest OTel event because hook_ingest fires AFTER the Stop event, which can be a few seconds after the last api_request.
30
Instance Method Summary collapse
-
#initialize(manager) ⇒ PromptScope
constructor
A new instance of PromptScope.
-
#tag(events) ⇒ Hash
count, groups: count.
Constructor Details
#initialize(manager) ⇒ PromptScope
Returns a new instance of PromptScope.
39 40 41 |
# File 'lib/claude_memory/otel/prompt_scope.rb', line 39 def initialize(manager) @manager = manager end |
Instance Method Details
#tag(events) ⇒ Hash
Returns count, groups: count.
47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/claude_memory/otel/prompt_scope.rb', line 47 def tag(events) return {tagged: 0, groups: 0} if events.nil? || events.empty? groups = group_by_prompt(events) return {tagged: 0, groups: 0} if groups.empty? tagged = 0 groups.each do |key, range| prompt_id, session_id = key [@manager.project_store, @manager.global_store].compact.each do |store| tagged += tag_in_store(store, prompt_id, session_id, range) end end {tagged: tagged, groups: groups.size} rescue Sequel::DatabaseError => e ClaudeMemory.logger.debug("prompt_scope tag failed: #{e.}") {tagged: 0, groups: 0, error: e.} end |