Skip to content

[unified_analytics] Fix Cursor agent check, default agent & add isBot - #2687

Merged
kevmoo merged 2 commits into
mainfrom
telemetry-bot-agent
Oct 16, 2026
Merged

kevmoo merged 2 commits into
mainfrom
telemetry-bot-agent

Conversation

@kevmoo

@kevmoo kevmoo commented Oct 16, 2026

Copy link
Copy Markdown
Member

Tighten Cursor AI agent detection, default agent in production Analytics factories, and add a shared Analytics.isBot helper for CI/bot environment detection.

  • Tighten AiAgent.cursor detection (lib/src/enums.dart): Check CURSOR_AGENT (non-empty and not '0'/'false') and CURSOR_EXTENSION_HOST_ROLE == 'agent-exec' instead of TERM_PROGRAM == 'cursor' or any CURSOR_* prefix (which false-matched CURSOR_TRACE_ID in human-opened Cursor IDE terminals).
  • Default agent in Analytics and Analytics.development (lib/src/analytics.dart): Default agent to AiAgent.detectAgentName(Platform.environment) when omitted so all Dash tools automatically report ai_agent without per-caller plumbing. Analytics.fake leaves agent as passed (null by default) so unit tests remain hermetic when run inside an AI agent.
  • Add Analytics.isBot(Map<String, String> environment) (lib/src/analytics.dart): Unifies the CI/bot environment variable checks from flutter_tools (BotDetector) and dartdev (isBot), respecting explicit non-bot overrides (BOT=false, BOT=0, FLUTTER_HOST, FLUTTER_ANALYTICS_LOG_FILE) and rejecting falsy CI=false/CI=0/empty values. Scoped as a static method on Analytics to avoid colliding with pkg/dartdev's top-level isBot. (is_bot user property registration is deferred to Step 2 of [unified_analytics] Add shared isBot helper and is_bot user property #2672 pending PDD review.)

Fixes #2670
Fixes #2671
Part of #2672

… tighten Cursor agent detection

- Default `agent` in `Analytics` and `Analytics.development` to `AiAgent.detectAgentName(Platform.environment)` when omitted, while keeping `Analytics.fake` hermetic.
- Tighten `AiAgent.cursor` detection in `AiAgent.detectAgentName` to check `CURSOR_AGENT` and `CURSOR_EXTENSION_HOST_ROLE=agent-exec` instead of `TERM_PROGRAM=cursor` or arbitrary `CURSOR_*` environment variables (such as `CURSOR_TRACE_ID` in human-opened Cursor IDE terminals).
- Add `Analytics.isBot(Map<String, String> environment)` unifying CI and bot environment checks across `flutter_tools` and `dartdev`.

Fixes #2670
Fixes #2671
@github-actions

github-actions Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

PR Health

Coverage ✔️
File Coverage
pkgs/unified_analytics/lib/src/analytics.dart 💚 78 % ⬆️ 2 %
pkgs/unified_analytics/lib/src/enums.dart 💚 100 %

This check for test coverage is informational (issues shown here will not fail the PR).

This check can be disabled by tagging the PR with skip-coverage-check.

License Headers ✔️
// Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

Files
no missing headers

All source files should start with a license header.

Unrelated files missing license headers
Files
pkgs/html/test/differential_test.dart
pkgs/html/test/dom_parsing_test.dart
pkgs/html/test/mxss_test.dart
pkgs/html/test/noah_ark_clause_limit_test.dart

This check can be disabled by tagging the PR with skip-license-check.

Breaking changes ✔️
Package Change Current Version New Version Needed Version Looking good?
unified_analytics Non-Breaking 8.0.18 8.1.0-wip 8.1.0-wip ✔️

This check can be disabled by tagging the PR with skip-breaking-check.

Unused Dependencies ✔️
Package Status
unified_analytics ✔️ All dependencies utilized correctly.

For details on how to fix these, see dependency_validator.

This check can be disabled by tagging the PR with skip-unused-dependencies-check.

API leaks ⚠️

The following packages contain symbols visible in the public API, but not exported by the library. Export these symbols or remove them from your publicly visible API.

Package Leaked API symbol Leaking sources
unified_analytics Condition survey_handler.dart::Survey::conditionList
survey_handler.dart::Survey::new::conditionList
unified_analytics PersistedSurvey survey_handler.dart::SurveyHandler::fetchPersistedSurveys
unified_analytics GAClient analytics.dart::Analytics::fake::gaClient
analytics.dart::AnalyticsImpl::new::gaClient
unified_analytics UserProperty analytics.dart::FakeAnalytics::userProperty

This check can be disabled by tagging the PR with skip-leaking-check.

Changelog Entry ✔️
Package Changed Files

Changes to files need to be accounted for in their respective changelogs.

This check can be disabled by tagging the PR with skip-changelog-check (for example, for non-user-visible changes when the package version is already at -wip).

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request defaults the agent parameter in Analytics to the detected agent name, refines the detection of the Cursor agent, and introduces Analytics.isBot to identify CI and bot environments. Feedback suggests improving the DartDoc for isBot to align with style guidelines, and handling the TRAVIS and CONTINUOUS_INTEGRATION environment variables case-insensitively along with corresponding test updates.

Default `agent` to `AiAgent.detectAgentName(environment)` in `Analytics.fake` (where `environment` defaults to `const {}`) so unit tests remain hermetic by default while supporting environment-driven `ai_agent` testing.
@kevmoo
kevmoo marked this pull request as ready for review October 16, 2026 05:16
@kevmoo
kevmoo requested a review from a team as a code owner October 16, 2026 05:17
@kevmoo
kevmoo requested a review from keertip October 16, 2026 05:19
@kevmoo
kevmoo merged commit c1471db into main Oct 16, 2026
21 checks passed
@kevmoo
kevmoo deleted the telemetry-bot-agent branch October 16, 2026 16:35
opensource-fork-sync Bot pushed a commit to cla7aye15I4nd/opensource-flutter__flutter that referenced this pull request Oct 16, 2026
…tter#194530)

Remove `AzureDetector` (`http://169.254.169.254/metadata/instance`) and
persistent `is-bot` caching (`PersistentToolState.isRunningOnBot` /
`setIsRunningOnBot`) from `BotDetector`, relying strictly on
deterministic CI environment variables.

- **Remove IMDS probe and disk cache (`bot_detector.dart`,
`persistent_tool_state.dart`)**: Eliminates the link-local HTTP probe on
tool startup, prevents cloud developer workstations on Azure/GCE/AWS
from being permanently misclassified as bots in `.flutter_tool_state`,
and removes unused `httpClientFactory` and `persistentToolState`
parameters from `BotDetector`.
- **Tighten `BOT` and `CI` environment checks (`bot_detector.dart`)**:
Treat `BOT=false` and `BOT=0` as explicit non-bot overrides, require
`CI` to be non-empty and not `'false'` or `'0'`, accept `BOT=true` or
`BOT=1`, and check `AZURE_HTTP_USER_AGENT` alongside `TF_BUILD`
(matching `dartdev`).
- **Async getter retention**: `Future<bool> get isRunningOnBot` is
intentionally kept async (`Future<bool>`) in this PR to avoid churn
across the 12 production `await` sites and `FakeBotDetector` in tests;
once `package:unified_analytics` rolls with `Analytics.isBot(Map<String,
String> environment)` (tracked in
dart-lang/tools#2672 /
dart-lang/tools#2687), a follow-up PR for
flutter#194405 can delegate directly
or simplify callers if desired.

Part of flutter#194405
copybara-service Bot pushed a commit to dart-lang/sdk that referenced this pull request Oct 17, 2026
Roll `tools_rev` to c1471db9c0fead64394eab4834d0fb640403b42a and replace
`dartdev`'s duplicate `_isRunningOnBot` implementation with
`Analytics.isBot` from `package:unified_analytics`, which ignores falsy
`CI` and `BOT` environment values (`false`, `0`, empty).

Rolling `package:unified_analytics` also defaults `Analytics.agent` to
`AiAgent.detectAgentName(Platform.environment)` for SDK tools such as
`analysis_server` and `dtd` when `agent` is omitted, and tightens
`AiAgent.cursor` detection.

tools (https://github.com/dart-lang/tools/compare/350bde5..c1471db):
  c1471db9  Fri Oct 16 09:35:21 2026 -0700  Kevin Moore  [unified_analytics] Fix Cursor agent check, default agent & add isBot (dart-lang/tools#2687)
  2d0d09a1  Fri Oct 16 15:37:59 2026 +0000  Phil Quitslund  [unified_analytics] Prepare for 8.1.0 release (dart-lang/tools#2684)
  7ea42bf6  Thu Oct 15 11:13:58 2026 -0700  Kallen Tu  Add Event.migrateEvent for the dart migrate tool. (dart-lang/tools#2682)
  4eaf46ba  Wed Oct 14 18:18:45 2026 +0000  Kevin Moore  [markdown] Fix LinkParser edge cases and BlockParser retreat loop (dart-lang/tools#2631)
  03f7124a  Wed Oct 14 11:15:00 2026 -0700  Kevin Moore  [markdown] Add tool/update_spec_tests.dart and sync GFM 0.29.0.gfm.13 spec stats (dart-lang/tools#2666)
  e0c90075  Tue Oct 13 16:16:23 2026 -0700  Morgan :)  [code_builder] publish 4.13.0 (dart-lang/tools#2663)

Fixes #64594
Fixes #64591
TEST=pkg/dartdev/test/analytics_test.dart

Change-Id: I71026772917d60df2ef144cc5527be9002f087f6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/565421
Commit-Queue: Kevin Moore <[email protected]>
Reviewed-by: Keerti Parthasarathy <[email protected]>
suryaKommana2662 pushed a commit to suryaKommana2662/flutter that referenced this pull request Oct 29, 2026
…tter#194530)

Remove `AzureDetector` (`http://169.254.169.254/metadata/instance`) and
persistent `is-bot` caching (`PersistentToolState.isRunningOnBot` /
`setIsRunningOnBot`) from `BotDetector`, relying strictly on
deterministic CI environment variables.

- **Remove IMDS probe and disk cache (`bot_detector.dart`,
`persistent_tool_state.dart`)**: Eliminates the link-local HTTP probe on
tool startup, prevents cloud developer workstations on Azure/GCE/AWS
from being permanently misclassified as bots in `.flutter_tool_state`,
and removes unused `httpClientFactory` and `persistentToolState`
parameters from `BotDetector`.
- **Tighten `BOT` and `CI` environment checks (`bot_detector.dart`)**:
Treat `BOT=false` and `BOT=0` as explicit non-bot overrides, require
`CI` to be non-empty and not `'false'` or `'0'`, accept `BOT=true` or
`BOT=1`, and check `AZURE_HTTP_USER_AGENT` alongside `TF_BUILD`
(matching `dartdev`).
- **Async getter retention**: `Future<bool> get isRunningOnBot` is
intentionally kept async (`Future<bool>`) in this PR to avoid churn
across the 12 production `await` sites and `FakeBotDetector` in tests;
once `package:unified_analytics` rolls with `Analytics.isBot(Map<String,
String> environment)` (tracked in
dart-lang/tools#2672 /
dart-lang/tools#2687), a follow-up PR for
flutter#194405 can delegate directly
or simplify callers if desired.

Part of flutter#194405
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[unified_analytics] Default agent to AiAgent.detectAgentName [unified_analytics] Avoid tagging Cursor IDE terminals as AI agents

2 participants