Skip to content

Support Mistral Vibe sessions#301

Open
ozymandiashh wants to merge 1 commit into
getagentseal:mainfrom
ozymandiashh:feat/mistral-vibe-provider
Open

Support Mistral Vibe sessions#301
ozymandiashh wants to merge 1 commit into
getagentseal:mainfrom
ozymandiashh:feat/mistral-vibe-provider

Conversation

@ozymandiashh
Copy link
Copy Markdown
Contributor

@ozymandiashh ozymandiashh commented May 11, 2026

Summary

This adds first-class CodeBurn support for Mistral Vibe sessions.

Mistral Vibe stores usage differently from providers like Claude Code, Codex, Pi, or Qwen. Instead of writing token usage on each assistant turn, Vibe writes a session-level cumulative total in meta.json, while the actual prompt/tool-call transcript lives in messages.jsonl. Because of that, this provider intentionally emits one CodeBurn usage record per Vibe session rather than pretending there is per-turn usage that the source data does not contain.

Closes #283.

What Changed

  • Added an eager mistral-vibe provider.
  • Auto-discovers Vibe sessions from:
    • $VIBE_HOME/logs/session/ when VIBE_HOME is set
    • ~/.vibe/logs/session/ by default
  • Parses Vibe 2.x session folders containing:
    • meta.json
    • messages.jsonl
  • Tracks nested subagent sessions under a parent session's agents/ folder.
  • Uses Vibe's own model prices first, then active model config prices, then CodeBurn/LiteLLM fallback pricing.
  • Normalizes Vibe tool calls into CodeBurn's standard dashboard names, for example:
    • bash -> Bash
    • read_file -> Read
    • write_file -> Write
    • search_replace -> Edit
    • grep -> Grep
    • task -> Agent
    • web_search -> WebSearch
  • Adds focused provider tests, README/provider docs, provider matrix entry, changelog note, and icon.

How Vibe Sessions Are Parsed

A current Vibe session looks like this on disk:

~/.vibe/logs/session/
  session_20260511_100000_abcd1234/
    meta.json
    messages.jsonl
    agents/
      session_20260511_100012_efgh5678/
        meta.json
        messages.jsonl

CodeBurn reads meta.json for usage and session metadata:

{
  "session_id": "session-abc123",
  "start_time": "2026-05-11T10:00:00+00:00",
  "end_time": "2026-05-11T10:05:00+00:00",
  "environment": {
    "working_directory": "/Users/test/my-project"
  },
  "stats": {
    "session_prompt_tokens": 2000,
    "session_completion_tokens": 3000,
    "input_price_per_million": 1.5,
    "output_price_per_million": 7.5
  },
  "config": {
    "active_model": "mistral-medium-3.5"
  }
}

That becomes one CodeBurn provider call roughly equivalent to:

{
  "provider": "mistral-vibe",
  "model": "mistral-medium-3.5",
  "inputTokens": 2000,
  "outputTokens": 3000,
  "costUSD": 0.0255,
  "timestamp": "2026-05-11T10:05:00+00:00",
  "sessionId": "session-abc123"
}

CodeBurn then reads messages.jsonl for the first user prompt and assistant tool calls:

{"role":"user","content":"track Mistral Vibe usage"}
{"role":"assistant","tool_calls":[{"function":{"name":"bash","arguments":"{\"command\":\"npm test && git status\"}"}}]}

From that transcript, CodeBurn extracts:

{
  "userMessage": "track Mistral Vibe usage",
  "tools": ["Bash"],
  "bashCommands": ["npm", "git"]
}

Why One Record Per Session

Other providers often attach token usage to each assistant response, so CodeBurn can emit one usage record per assistant turn. Vibe currently does not expose usage that way. It stores cumulative session totals in meta.json.stats, for example:

  • session_prompt_tokens
  • session_completion_tokens
  • input_price_per_million
  • output_price_per_million

Splitting those totals across messages would be guesswork and could make date bucketing, model cost, and tool attribution misleading. This PR keeps the accounting faithful to the source data: one Vibe session folder becomes one CodeBurn usage record.

Edge Cases Covered

  • Missing Vibe directory returns no sessions instead of erroring.
  • VIBE_HOME override is respected.
  • ~ and ~/... are expanded for VIBE_HOME to match Vibe's own behavior.
  • Invalid JSONL lines are skipped without dropping the whole session.
  • Sessions with zero prompt and completion tokens are ignored.
  • Missing end_time falls back to start_time.
  • Duplicate scans dedupe by mistral-vibe:<session_id>.
  • Subagent sessions under agents/ are discovered and counted separately.
  • Cost fallback chain is tested:
    • Vibe stats prices
    • Vibe active model config prices
    • LiteLLM pricing fallback

Files Changed

  • src/providers/mistral-vibe.ts - provider discovery/parsing/cost/tool extraction
  • tests/providers/mistral-vibe.test.ts - focused fixtures and regression coverage
  • src/providers/index.ts - provider registry
  • tests/provider-registry.test.ts - registry expectation
  • docs/providers/mistral-vibe.md - provider-specific implementation notes
  • docs/providers/README.md - provider docs index
  • README.md - supported provider table, notes, env var docs
  • CHANGELOG.md - unreleased entry
  • assets/providers/mistral-vibe.svg - provider icon

Validation

  • npm run build
  • npx vitest run (48 files / 672 tests)
  • git diff --check
  • Argus local reviewer: PASS
  • Claude Opus 4.7 effort max: PASS
  • Gemini 3.1 Pro Preview: PASS
  • GitHub checks: PASS
    • check
    • assess
    • semgrep

Note

npx tsc --noEmit still fails on an existing unrelated error in src/models-report.ts(151,13):

Type string is not assignable to type TaskCategory

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.

Feature: Support for Mistral Vibe

1 participant