Skip to content

feat(retrieval,agent-memory): add PostHog product telemetry (TS + PY)#281

Open
KIvanow wants to merge 2 commits into
masterfrom
feat/retrieval-agent-memory-posthog-analytics
Open

feat(retrieval,agent-memory): add PostHog product telemetry (TS + PY)#281
KIvanow wants to merge 2 commits into
masterfrom
feat/retrieval-agent-memory-posthog-analytics

Conversation

@KIvanow

@KIvanow KIvanow commented Jun 25, 2026

Copy link
Copy Markdown
Member

Mirror the agent-cache/semantic-cache analytics pattern across the retrieval and agent-memory packages in both TypeScript and Python: optional posthog dependency with a noop fallback, build-time baked-key placeholders, BETTERDB_TELEMETRY opt-out, and a Valkey-persisted instance-id UUID. Captures *_init and index_created events.

Wires POSTHOG_API_KEY/POSTHOG_HOST build env into the four release workflows so the keys bake into published artifacts.

Summary

Changes

Checklist

  • Unit / integration tests added
  • Docs added / updated
  • Roborev review passed — run roborev review --branch or /roborev-review-branch in Claude Code (internal)
  • Competitive analysis done / discussed (internal)
  • Blog post about it discussed (internal)

Note

Medium Risk
Published npm/PyPI artifacts may embed a PostHog project key at build time, and telemetry runs by default unless opted out—privacy and key-exposure considerations for downstream users.

Overview
Adds optional PostHog product analytics to @betterdb/agent-memory, @betterdb/retrieval, and their Python wheels, following the same pattern as agent-cache: noop fallback, BETTERDB_TELEMETRY opt-out, and a stable instance UUID stored in Valkey at {name}:__instance_id.

MemoryStore / Retriever start analytics on the first index call (ensureIndex / create_index), emit *_init with config metadata and index_created only when this worker actually creates the index (retrieval skips the event on concurrent “already exists”). Analytics errors never affect core behavior; close() flushes via shutdown.

Release builds can bake POSTHOG_API_KEY and POSTHOG_HOST into artifacts: Hatch hatch_build.py for Python and inject-telemetry-defaults.mjs after tsc for npm. The four agent-memory/retrieval release workflows pass those secrets at build time. posthog / posthog-node are added as dependencies, with unit tests for the analytics factories.

Reviewed by Cursor Bugbot for commit fc1ecb6. Bugbot is set up for automated code reviews on this repo. Configure here.

Mirror the agent-cache/semantic-cache analytics pattern across the
retrieval and agent-memory packages in both TypeScript and Python:
optional posthog dependency with a noop fallback, build-time baked-key
placeholders, BETTERDB_TELEMETRY opt-out, and a Valkey-persisted
instance-id UUID. Captures *_init and index_created events.

Wires POSTHOG_API_KEY/POSTHOG_HOST build env into the four release
workflows so the keys bake into published artifacts.
throw err;
}
}
this.analytics.capture('index_created', { dims });

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spurious index_created event

Low Severity

When createIndex swallows an already exists error from concurrent FT.CREATE, it still emits index_created even though this worker did not create the index. The Python retriever returns before capturing in that case, so telemetry can over-count index creation on multi-worker boot.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 34a568f. Configure here.

Comment thread packages/agent-memory/src/MemoryStore.ts
Defer analytics startup to a fire-once awaited ensureAnalyticsStarted()
called at the top of createIndex/ensureIndex, mirroring the Python ports.
This guarantees the real PostHog client is initialized before any event
is captured, so index_created is no longer emitted on the noop instance.

Also skip the index_created event on the concurrent "already exists"
path in retrieval, so multi-worker boot does not over-count creation.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit fc1ecb6. Configure here.

if (this.discovery) {
await this.discovery.stop({ deleteHeartbeat: true });
}
await this.analytics.shutdown();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Close ignores in-flight analytics

Low Severity

close shuts down whatever analytics reference is current but does not coordinate with a concurrent ensureAnalyticsStarted still creating PostHog. After close, that in-flight init can still assign a live client that never gets shut down, unlike AgentCache’s shutdownCalled guard in the mirrored pattern.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit fc1ecb6. Configure here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant