Rohit Malhotraandopenhands e2615344df feat: add first-use telemetry tracking with consent (#138)
* feat: add first-use telemetry tracking with consent

- Add telemetry service with consent management (src/services/telemetry.ts)
- Add useTelemetry React hook for easy integration (src/hooks/use-telemetry.ts)
- Add TelemetryConsentBanner component with i18n support
- Add local development server for testing (scripts/telemetry-dev-server.mjs)
- Add comprehensive tests for telemetry service and hook
- Export telemetry utilities from library index
- Respect DO_NOT_TRACK environment variable for privacy
- Uses localhost:8080 endpoint for development

Co-authored-by: openhands <openhands@all-hands.dev>

* fix: address PR review feedback

- Make TELEMETRY_ENDPOINT configurable via VITE_TELEMETRY_ENDPOINT env var
- Make POSTHOG_API_KEY configurable via VITE_POSTHOG_API_KEY env var
- Add validation to skip telemetry if API key not configured (except localhost)
- Fix DO_NOT_TRACK to work in browser environments using VITE_DO_NOT_TRACK
- Also respect browser's navigator.doNotTrack standard
- Update consent banner hint text to reference correct env var
- Add documentation comments for all configuration options

Co-authored-by: openhands <openhands@all-hands.dev>

* feat: hardcode PostHog credentials for centralized telemetry

- Use OpenHands PostHog project API key for all library users
- Use PostHog US Cloud endpoint (https://us.i.posthog.com/capture)
- Remove environment variable configuration for endpoint/API key
- Telemetry now automatically sends to centralized project when consent granted
- Users can still opt out via UI, VITE_DO_NOT_TRACK, or browser DNT setting

Co-authored-by: openhands <openhands@all-hands.dev>

* feat: use separate PostHog API keys for dev and production

- Dev environment: phc_kBtz5nKmxVRRQ7HtPwr2QX9eMC5j65zE86QKocVNwb4U
- Production: phc_BgzfxKdgsYMLFTmJqt424ZoyVHvKFfrwttLimzdYTKFK
- Automatically selects key based on import.meta.env.DEV

Co-authored-by: openhands <openhands@all-hands.dev>

* chore: use single production PostHog API key everywhere

Simplify by using the same API key for all environments.

Co-authored-by: openhands <openhands@all-hands.dev>

* chore: rename telemetry events

- library_first_use → canvas_install
- library_session_start → canvas_new_session

Co-authored-by: openhands <openhands@all-hands.dev>

* feat: migrate telemetry to PostHog SDK

Replace raw HTTP requests with PostHog SDK for:
- Automatic event batching
- Built-in retry logic with exponential backoff
- Offline support (queues events, sends when back online)
- Automatic session tracking
- Better device/browser info enrichment

Benefits:
- More reliable event delivery
- Reduced network requests
- Cleaner code with less manual state management
- Future-proof for feature flags, session replay, etc.

Co-authored-by: openhands <openhands@all-hands.dev>

* refactor: remove redundant hasTrackedFirstUse state in hook

The trackFirstUse() function already has built-in deduplication via
localStorage, so the local React state was unnecessary. Simplified
the hook and added a comment explaining the deduplication mechanism.

Co-authored-by: openhands <openhands@all-hands.dev>

* chore: remove obsolete telemetry dev server

The local dev server was used when telemetry used raw HTTP requests
to a configurable endpoint. Now that we use the PostHog SDK with
the real PostHog endpoint, this is no longer needed.

Co-authored-by: openhands <openhands@all-hands.dev>

* fix: remove trailing comma in package.json

Co-authored-by: openhands <openhands@all-hands.dev>

* fix: address PR review feedback

- Make POSTHOG_API_KEY configurable via VITE_POSTHOG_API_KEY env var
- Make POSTHOG_HOST configurable via VITE_POSTHOG_HOST env var
- Add session deduplication using sessionStorage to prevent duplicate
  canvas_new_session events from multiple hook instances
- Clear sessionStorage in clearTelemetryData()

Co-authored-by: openhands <openhands@all-hands.dev>

* fix: use dynamic imports for PostHog SSR compatibility

- Convert top-level posthog-js import to dynamic import for SSR safety
- Add getPostHog() lazy loader that only imports in browser context
- Make setTelemetryConsent, clearTelemetryData, getPostHogInstance async
- Update documentation to clarify default telemetry destination
- Update tests for async function signatures

This ensures the library works correctly in SSR frameworks (Next.js, Remix,
etc.) that might import this module server-side.

Co-authored-by: openhands <openhands@all-hands.dev>

* feat: add telemetry consent banner to app layout

The consent banner now appears on all pages until the user explicitly
accepts or declines telemetry. This ensures users are always prompted
for consent on their first visit regardless of which page they land on.

Co-authored-by: openhands <openhands@all-hands.dev>

* refactor: update telemetry consent banner to modal style

- Changed from bottom banner to centered modal overlay (matching OpenHands)
- Uses ModalBackdrop, ModalBody, BaseModalTitle, BaseModalDescription
- Single checkbox with 'Confirm preferences' button pattern
- Full-screen overlay blocks interaction until user makes a choice
- Added i18n keys: TELEMETRY$SEND_ANONYMOUS_DATA, TELEMETRY$CONFIRM_PREFERENCES

Co-authored-by: openhands <openhands@all-hands.dev>

* fix: ensure PostHog is initialized before tracking events

- Made grantConsent/denyConsent in useTelemetry hook async to ensure
  PostHog initialization completes before state update triggers tracking
- Updated tests for async consent functions
- This fixes a race condition where trackFirstUse() could be called before
  PostHog's opt_in_capturing() had been executed

Co-authored-by: openhands <openhands@all-hands.dev>

---------

Co-authored-by: openhands <openhands@all-hands.dev>
2026-05-07 13:18:01 -04:00
2026-05-07 12:50:05 -04:00
2026-04-24 17:33:22 -04:00

agent-canvas

Warning

This project is in an early incubator phase. It may be vibecoded, untested, or out of date. OpenHands takes no responsibility for the code or its support. Learn more.

Quickstart

This repository is a near-direct port of the OpenHands frontend adapted to talk directly to software-agent-sdk / agent_server without the usual OpenHands app backend.

Prerequisites

  • Node.js 22.12.x or later
  • npm
  • uv (for running the agent server via uvx)

1. Clone and install the frontend

git clone https://github.com/OpenHands/agent-canvas.git
cd agent-canvas
npm install

2. Install uv

If you do not already have uv installed, install it first (OpenHands SDK recommends uv 0.8.13+):

curl -LsSf https://astral.sh/uv/install.sh | sh

Need Windows or another install method? See the official uv installation guide: https://docs.astral.sh/uv/getting-started/installation/

If ~/.local/bin is not already on your PATH, add it:

export PATH="$HOME/.local/bin:$PATH"
command -v uvx

The npm run dev command uses uvx to automatically download and run the agent server, so no separate installation step is needed.

3. Optional: create a .env file

If you need to change the backend URL, frontend port, session API key, or working directory, copy the sample file:

cp .env.sample .env

Then edit the values you need.

4. Start the app

npm run dev

This starts the full stack:

  • Agent server (via uvx)
  • Automation backend (via uvx)
  • Vite dev server
  • Ingress proxy (routes traffic to all backends)

Access the UI at http://localhost:8000

Environment Variables

Variable Description Default
PORT Ingress port 8000
OH_AUTOMATION_GIT_REF Git ref for automation backend main
OH_AGENT_SERVER_GIT_REF Git ref for agent-server main

5. First-run sanity check

After the page opens:

  • / should load without errors
  • /settings should load
  • configure a working LLM model + API key under Settings > LLM before running the first live task
  • you should be able to open or create a conversation
  • /api/automation/docs should show the automation API docs

Alternative: Minimal Mode (without Automation)

To run without the automation service:

npm run dev:minimal

This runs only agent-server + Vite (no automation backend or ingress). Access at http://localhost:3001/

More documentation

For contributor and developer workflows, including frontend-only mode, mock mode, environment variables, and build/test commands, see DEVELOPMENT.md.

S
Languages
TypeScript 93.7%
JavaScript 4.7%
Python 0.9%
Shell 0.3%
CSS 0.2%
Other 0.1%