Skip to content

Forecast: prefer usage artifact for token AIC, retain legacy agent fallback#37427

Merged
pelikhan merged 2 commits into
mainfrom
copilot/update-forecast-download-usage-artifact
Jun 6, 2026
Merged

Forecast: prefer usage artifact for token AIC, retain legacy agent fallback#37427
pelikhan merged 2 commits into
mainfrom
copilot/update-forecast-download-usage-artifact

Conversation

Copilot AI commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

Forecast currently depends on token data that often required downloading the heavier agent artifact when cache was cold. This change makes forecast fetch token usage from the lightweight usage artifact first, while preserving legacy compatibility paths.

  • What changed

    • Usage-first artifact retrieval
      • Updated forecast run AIC resolution to attempt artifact downloads in this order:
        1. usage
        2. agent
        3. agent-artifacts (legacy)
      • Returns the first non-zero AIC parsed from downloaded token usage data.
    • Token usage file discovery
      • Extended token usage lookup to recognize usage-artifact layout:
        • usage/agent/token_usage.jsonl
      • Added support for both filename variants in scan fallback:
        • token-usage.jsonl
        • token_usage.jsonl
    • Behavioral coverage
      • Added tests for:
        • usage-first success path
        • fallback from usage to agent
        • usage artifact file discovery precedence
  • Example (new fallback order in forecast AIC load path)

usageFirstFilters := [][]string{
    {"usage"},
    {constants.AgentArtifactName},
    {"agent-artifacts"},
}

Copilot AI changed the title Use usage artifact first for forecast token retrieval Forecast: prefer usage artifact for token AIC, retain legacy agent fallback Jun 6, 2026
Copilot AI requested a review from pelikhan June 6, 2026 22:19
@pelikhan pelikhan marked this pull request as ready for review June 6, 2026 22:20
Copilot AI review requested due to automatic review settings June 6, 2026 22:20
@pelikhan pelikhan merged commit 21d3191 into main Jun 6, 2026
@pelikhan pelikhan deleted the copilot/update-forecast-download-usage-artifact branch June 6, 2026 22:20

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

This PR updates the forecast AIC loading path to prefer a lightweight usage artifact for token usage data, while keeping fallbacks to the heavier agent artifacts for backward compatibility.

Changes:

  • Extended token-usage file discovery to recognize usage/agent/token_usage.jsonl and accept both token-usage.jsonl and token_usage.jsonl naming variants.
  • Updated forecast cached-run AIC resolution to attempt artifact downloads in the order: usageagentagent-artifacts, returning the first non-zero AIC found.
  • Added unit tests covering the usage-first path and a fallback scenario.
Show a summary per file
File Description
pkg/cli/token_usage.go Adds usage-artifact-aware token usage file discovery and supports underscore filename variant.
pkg/cli/token_usage_test.go Adds a test for finding token usage in the usage artifact layout.
pkg/cli/forecast.go Implements usage-first artifact download order for AIC resolution when cache is missing/insufficient.
pkg/cli/forecast_test.go Adds tests validating usage-first behavior and fallback sequencing.

Copilot's findings

Tip

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

  • Files reviewed: 4/4 changed files
  • Comments generated: 5

Comment thread pkg/cli/token_usage.go
Comment on lines 279 to +286
// findTokenUsageFile searches for token-usage.jsonl in the run directory
func findTokenUsageFile(runDir string) string {
usageArtifactCandidate := filepath.Join(runDir, "usage", "agent", "token_usage.jsonl")
if _, err := os.Stat(usageArtifactCandidate); err == nil {
tokenUsageLog.Printf("Found token usage file in usage artifact: %s", usageArtifactCandidate)
return usageArtifactCandidate
}

Comment thread pkg/cli/forecast.go
Comment on lines +759 to +773
usageFirstFilters := [][]string{
{"usage"},
{constants.AgentArtifactName},
{"agent-artifacts"},
}

for _, filter := range usageFirstFilters {
if err := forecastDownloadRunArtifacts(context.Background(), runID, dir, verbose, "", "", "", filter); err != nil && !errors.Is(err, ErrNoArtifacts) {
continue
}
tokenUsage, err := forecastAnalyzeTokenUsage(dir, verbose)
if err != nil || tokenUsage == nil || tokenUsage.TotalAIC <= 0 {
continue
}
return tokenUsage.TotalAIC
Comment thread pkg/cli/forecast.go
Comment on lines +766 to +768
if err := forecastDownloadRunArtifacts(context.Background(), runID, dir, verbose, "", "", "", filter); err != nil && !errors.Is(err, ErrNoArtifacts) {
continue
}
Comment thread pkg/cli/forecast_test.go
require.Equal(t, []string{"usage"}, downloaded)
}

func TestLoadCachedRunAIC_FallsBackToLegacyAgentArtifacts(t *testing.T) {
Comment thread pkg/cli/forecast.go
Comment on lines +759 to +763
usageFirstFilters := [][]string{
{"usage"},
{constants.AgentArtifactName},
{"agent-artifacts"},
}
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.

3 participants