Skip to content

model-usage: implement Antigravity provider - #6472

Open
neheb wants to merge 1 commit into
basecamp:quattrofrom
neheb:ant
Open

model-usage: implement Antigravity provider#6472
neheb wants to merge 1 commit into
basecamp:quattrofrom
neheb:ant

Conversation

@neheb

@neheb neheb commented Aug 1, 2026

Copy link
Copy Markdown

Work all done by Antigravity.

Prompt was:

Implement shell/plugins/model-usage/providers/Antigravity.qml

Copilot AI review requested due to automatic review settings August 1, 2026 01:19

Copilot AI 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.

Pull request overview

Adds Antigravity usage and quota reporting to the model-usage panel.

Changes:

  • Adds an Antigravity provider and scanner.
  • Integrates Antigravity into the panel, defaults, and installation.
  • Adds local-history scanner tests and branding.

Tip

If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or run gh pr ready --undo.
Click "Ready for review" or run gh pr ready to reengage.

Reviewed changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
shell/plugins/model-usage/providers/Antigravity.qml Defines the provider interface and refresh lifecycle.
shell/plugins/model-usage/scripts/antigravity_usage_scanner.py Collects local activity and IDE quota data.
shell/plugins/model-usage/Main.qml Registers Antigravity with model usage.
shell/plugins/model-usage/Panel.qml Adds branding and empty-state text.
shell/plugins/model-usage/manifest.json Adds default provider settings.
shell/plugins/model-usage/assets/antigravity.svg Provides the provider icon.
install/user/mise.sh Installs the agy CLI.
test/shell.d/model-usage-antigravity-scanner-test.sh Tests local history aggregation.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

result = subprocess.run(["lsof", "-nP", "-iTCP", "-sTCP:LISTEN", "-p", pid],
capture_output=True, text=True, timeout=10)
for line in result.stdout.splitlines()[1:]:
for match in re.finditer(r":(\d+)$", line):

Antigravity {
id: antigravityProvider
enabled: root.providerEnabled("antigravity")
return response.status, response.read()


def parse_limits(payload):
Copilot AI review requested due to automatic review settings August 1, 2026 01:31

Copilot AI 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.

Pull request overview

Copilot reviewed 7 out of 8 changed files in this pull request and generated 2 comments.

Suppressed comments (3)

shell/plugins/model-usage/Main.qml:14

  • Antigravity is disabled for the shipped bare widget entry. BarModel.entrySettings() supplies {} here, while providerEnabled() defaults only Claude and Codex to enabled when no provider setting exists, so the scanner never runs despite the new manifest default. Default this provider to enabled unless it is explicitly disabled.
    enabled: root.providerEnabled("antigravity")

shell/plugins/model-usage/scripts/antigravity_usage_scanner.py:31

  • Invalid timestamps are converted to today's date, so a malformed history entry is counted as a prompt/session today instead of being ignored. Return a failure sentinel from local_day_from_ms() and skip that entry before updating counters.
  except Exception:
    return datetime.now().strftime("%Y-%m-%d")

shell/plugins/model-usage/scripts/antigravity_usage_scanner.py:83

  • These values are prompt counts, but the existing panel contract renders recentDays.messageCount under “TOKENS BY DAY” and formats each value as tokens. Antigravity users will therefore see prompts misreported as token usage. Either extend the provider/UI contract with the metric unit and render prompts, or leave this token series empty.
    # Populate recentDays with local daily prompt counts. While the UI refers
    # to this as "TOKENS BY DAY", displaying prompt counts allows drawing
    # the weekly activity bar chart for Antigravity instead of hiding it.
    "recentDays": [recent_days_map[date] for date in recent_dates],

try:
result = subprocess.run(["ss", "-tlnp"], capture_output=True, text=True, timeout=10)
for line in result.stdout.splitlines():
if f"pid={pid}" not in line:
Comment on lines +135 to +136
result = subprocess.run(["lsof", "-nP", "-iTCP", "-sTCP:LISTEN", "-p", pid],
capture_output=True, text=True, timeout=10)
Work all done by Antigravity.

Prompt was:

Implement shell/plugins/model-usage/providers/Antigravity.qml

Signed-off-by: Rosen Penev <rosenp@gmail.com>
Copilot AI review requested due to automatic review settings August 1, 2026 01:41

Copilot AI 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.

Pull request overview

Copilot reviewed 7 out of 8 changed files in this pull request and generated no new comments.

Suppressed comments (6)

shell/plugins/model-usage/scripts/antigravity_usage_scanner.py:139

  • The fallback has the same discovery failure: normal lsof -iTCP -sTCP:LISTEN output ends with (LISTEN), so :(\d+)$ cannot match it. If ss yields no ports, this leaves only --extension_server_port to probe and can make limits appear unavailable even while the language server is running.
        for match in re.finditer(r":(\d+)$", line):
          ports.append(match.group(1))

shell/plugins/model-usage/Main.qml:71

  • The new provider participates in the aggregate refresh state but is omitted from lastRefreshedAtMs immediately below. With only Antigravity enabled, a successful scan leaves the module-level timestamp at zero, so consumers of the model-usage plugin never observe its refresh time. Include the Antigravity timestamp in the aggregate.
  property bool refreshing: antigravityProvider.refreshing || claudeProvider.refreshing || codexProvider.refreshing || syncRunning

shell/plugins/model-usage/scripts/antigravity_usage_scanner.py:129

  • This regex only accepts a port at the end of the line, but ss -tlnp appends users:(...,pid=...,fd=...) after the peer address. Therefore every line that passes the PID check fails this match, and the language server's listening ports are never discovered through ss. Parse the local-address column instead.

This issue also appears on line 138 of the same file.

      for match in re.finditer(r":(\d+)(?:\s+\(LISTEN\))?\s*$", line):
        ports.append(match.group(1))

shell/plugins/model-usage/scripts/antigravity_usage_scanner.py:83

  • These values are prompt counts, but recentDays.messageCount is the existing token-total field: Panel.qml:491 labels it “TOKENS BY DAY” and line 697 formats each value as tokens. This makes, for example, three prompts display as three tokens and also sums incompatible units during sync. Leave recentDays empty until the UI supports a provider-specific “prompts by day” metric.
    # Populate recentDays with local daily prompt counts. While the UI refers
    # to this as "TOKENS BY DAY", displaying prompt counts allows drawing
    # the weekly activity bar chart for Antigravity instead of hiding it.
    "recentDays": [recent_days_map[date] for date in recent_dates],

shell/plugins/model-usage/scripts/antigravity_usage_scanner.py:31

  • A malformed but present timestamp is silently converted to today's date. Such an entry is then counted as one of today's prompts/sessions and as an active day rather than being skipped, producing incorrect usage totals. Return an invalid marker here and have scan_local_stats continue past that entry before updating counters.
  except Exception:
    return datetime.now().strftime("%Y-%m-%d")

test/shell.d/model-usage-antigravity-scanner-test.sh:16

  • Using the current instant and then adding one or two seconds makes this test fail when it starts just before local midnight: the later fixtures belong to tomorrow, while the assertions still expect three prompts today. Anchor both fixtures at noon so the additions cannot cross a date boundary.
today_ms=$(python3 -c "import time; print(int(time.time() * 1000))")
yesterday_ms=$((today_ms - 86400000))

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.

2 participants