Skip to content

feat(agent-gui): track engagement analytics#1146

Merged
chovy-ai merged 2 commits into
mainfrom
agent/agent-gui-engagement-analytics-v2
Jul 15, 2026
Merged

feat(agent-gui): track engagement analytics#1146
chovy-ai merged 2 commits into
mainfrom
agent/agent-gui-engagement-analytics-v2

Conversation

@chovy-ai

@chovy-ai chovy-ai commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Rework the conflicted engagement tracking from feat(agent): track Agent GUI engagement #1081 against the current Agent GUI/workbench architecture.
  • Define session/target-scoped panel visits with true exposure eligibility: active and host-visible, focused document, at least 50% intersection, and a continuous 1-second dwell.
  • Report the first composer focus and accepted content entry per exposed visit while excluding controlled hydration, prefill, and programmatic mention-trigger insertion.
  • Keep reusable Agent GUI code on a semantic event contract; Desktop owns analytics event names, workspace/standalone surface labels, reporter construction, and transport.
  • Restrict payloads to identifiers, enums, and booleans; prompt text, attachment data, file names, paths, and mention URIs never cross the analytics boundary.

The previous implementation tied a visit to panel eligibility without including the active conversation context, so switching sessions while visible could reuse a panel visit across conversations. Visits now end when eligibility or the session/target context changes.

Verification

  • pnpm check:changed — passed 13 lanes after rebasing onto current main
  • pnpm check:full — passed all 18 tasks
  • Agent GUI focused tests — 159 passed
  • Desktop reporter and privacy mapping tests — 23 passed
  • Agent GUI, Desktop, and Workbench Surface typechecks — passed
  • Agent GUI degradation, renderer boundary, runtime boundary, TypeScript lint, and git diff --check — passed

Fallback Three Questions

  • Source: the timer represents the analytics definition of a true exposure: the panel must remain continuously eligible for one second.
  • Why can it not be fixed at that source? No existing host event carries continuous DOM intersection, document focus/visibility, and dwell duration together; the reusable panel is the first layer with all required signals.
  • Removal condition: remove the timer if the analytics contract drops the dwell requirement or the host provides an authoritative exposure lifecycle/timestamp that includes the same eligibility semantics.

Checklist

  • I kept the change focused on one concern.
  • I updated documentation when behavior, setup, or contributor workflow changed.
  • I updated all README/CONTRIBUTING language variants when changing their English source (not applicable; none changed).
  • I ran the lowest meaningful local checks for the changed surface.
  • My commits are signed off with DCO when required: git commit -s.

Summary by cubic

Adds privacy-safe engagement analytics to the Agent GUI. Tracks true panel exposure, first composer focus, and first user-entered content per session/target-scoped visit; Desktop maps these semantic events to product analytics for workspace and standalone Agent surfaces.

  • New Features
    • True exposure: eligible only when active, host-visible (isVisible), document focused, ≥50% intersection, with a continuous 1s dwell; visits reset on eligibility or session/target change. If IntersectionObserver is unavailable, we don’t approximate exposure.
    • Events: @tutti-os/agent-gui emits semantic events via hostActions.onEngagementEvent; @tutti-os/desktop reports agent.chat_panel_exposed, agent.chat_input_focused, agent.chat_input_content_entered with surface = workspace or standalone_agent.
    • Composer engagement: captures focus method (keyboard | pointer | programmatic) and first content (text | large_text | image) with hadPrefill; excludes controlled hydration, prefill, and programmatic mention trigger.
    • Privacy: payloads include only identifiers/enums/booleans; no prompt text, file names, paths, mention URIs, or attachment data.
    • API additions:
      • @tutti-os/agent-gui: AgentGUINode adds isVisible and optional onEngagementEvent; AgentComposer adds optional engagement; rich text editor adds onFocus and onUserContentChange.
      • @tutti-os/desktop: createAgentGUIEngagementEventSink(surface) provides the sink; wired for workspace and standalone Agent; hosts pass isVisible derived from workbench presentationMode and minimized state and skip reporting in preview.
      • @tutti-os/workbench-surface: host context exposes presentationMode to derive panel visibility.
    • Tests and docs: engagement unit tests, reporter completeness and privacy tests, and architecture docs updated to define visit scope, exposure semantics, and privacy guarantees.

Written for commit a8c7380. Summary will update on new commits.

Review in cubic

@chovy-ai
chovy-ai force-pushed the agent/agent-gui-engagement-analytics-v2 branch from 6f9ad04 to f417a56 Compare July 15, 2026 05:15
@chovy-ai
chovy-ai marked this pull request as ready for review July 15, 2026 05:18

@cubic-dev-ai cubic-dev-ai 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.

3 issues found across 46 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="apps/desktop/src/renderer/src/features/workspace-agent/ui/DesktopAgentGUIWorkbenchBody.tsx">

<violation number="1" location="apps/desktop/src/renderer/src/features/workspace-agent/ui/DesktopAgentGUIWorkbenchBody.tsx:741">
P1: Minimizing the node or entering/leaving mission control may not start/end exposure because the memo comparator ignores both new inputs to `frame.isVisible`. Include `context.presentationMode` and `context.node.isMinimized` in `areDesktopAgentGUIWorkbenchBodyContextsEqual`.</violation>
</file>

<file name="apps/desktop/src/renderer/src/features/analytics/reporters/agent-chat-input-content-entered/types.ts">

<violation number="1" location="apps/desktop/src/renderer/src/features/analytics/reporters/agent-chat-input-content-entered/types.ts:3">
P2: The new content-entered reporter does not enforce its privacy allowlist: the inherited string index signature accepts arbitrary extra analytics fields, and `BaseAnalyticsReporter` serializes all of them. Consider projecting only the declared event fields before transport or changing the base generic constraint so this params type rejects undeclared keys.</violation>
</file>

<file name="apps/desktop/src/renderer/src/features/analytics/reporters/agent-chat-input-focused/types.ts">

<violation number="1" location="apps/desktop/src/renderer/src/features/analytics/reporters/agent-chat-input-focused/types.ts:3">
P2: The new focused-event contract permits arbitrary string-keyed payload fields, so a direct caller can type-check sensitive fields such as prompt text and `BaseAnalyticsReporter` will transmit them. A closed params shape (with the base reporter constraint adjusted to validate known property values without adding an index signature) would enforce this event's privacy boundary.</violation>
</file>

Tip: instead of fixing issues one by one fix them all with cubic

Re-trigger cubic

isMaximized: context.displayMode === "fullscreen",
isActive: context.isFocused,
isVisible:
context.presentationMode !== "mission-control" &&

@cubic-dev-ai cubic-dev-ai Bot Jul 15, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1: Minimizing the node or entering/leaving mission control may not start/end exposure because the memo comparator ignores both new inputs to frame.isVisible. Include context.presentationMode and context.node.isMinimized in areDesktopAgentGUIWorkbenchBodyContextsEqual.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At apps/desktop/src/renderer/src/features/workspace-agent/ui/DesktopAgentGUIWorkbenchBody.tsx, line 741:

<comment>Minimizing the node or entering/leaving mission control may not start/end exposure because the memo comparator ignores both new inputs to `frame.isVisible`. Include `context.presentationMode` and `context.node.isMinimized` in `areDesktopAgentGUIWorkbenchBodyContextsEqual`.</comment>

<file context>
@@ -736,6 +737,9 @@ function DesktopAgentGUIWorkbenchBodyImpl({
           isMaximized: context.displayMode === "fullscreen",
           isActive: context.isFocused,
+          isVisible:
+            context.presentationMode !== "mission-control" &&
+            context.node.isMinimized !== true,
           embedded: true,
</file context>
Fix with cubic

Comment thread packages/agent/gui/agent-gui/agentGuiNode/agentRichText/AgentRichTextEditor.tsx Outdated
chovy-ai added 2 commits July 15, 2026 13:42
Signed-off-by: Chovy <253849174+chovy-ai@users.noreply.github.com>
Signed-off-by: Chovy <253849174+chovy-ai@users.noreply.github.com>
@chovy-ai
chovy-ai force-pushed the agent/agent-gui-engagement-analytics-v2 branch 2 times, most recently from 27b39b0 to a8c7380 Compare July 15, 2026 05:46
@chovy-ai
chovy-ai merged commit 7cea41b into main Jul 15, 2026
11 checks passed
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