diff --git a/HISTORY.md b/HISTORY.md index 3b6404106..08be2c255 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,20 +1,108 @@ # Release history ### main branch +- Offer to OAuth against OpenRouter if no model and keys are provided. +- Prioritize `gemini/gemini-2.5-pro-exp-03-25` if `GEMINI_API_KEY` is set, and `vertex_ai/gemini-2.5-pro-exp-03-25` if `VERTEXAI_PROJECT` is set, when no model is specified. +- Select OpenRouter default model based on free/paid tier status if `OPENROUTER_API_KEY` is set and no model is specified. +- Warn at startup if `--stream` and `--cache-prompts` are used together, as cost estimates may be inaccurate. +- Boost repomap ranking for files whose path components match identifiers mentioned in the chat. +- Change web scraping timeout from an error to a warning, allowing scraping to continue with potentially incomplete content. +- Left-align markdown headings in the terminal output, by Peter Schilling. +- Aider wrote 90% of the code in this release. -- Display thinking/reasoning content from LLMs which return it. -- Enhanced handling of reasoning tags to better clean up model responses. +### Aider v0.79.2 + +- Added 'gemini' alias for gemini-2.5-pro model. +- Updated Gemini 2.5 Pro max output tokens to 64k. +- Added support for Lisp-style semicolon comments in file watcher, by Matteo Landi. +- Added OpenRouter API error detection and retries. +- Added openrouter/deepseek-chat-v3-0324 model. +- Aider wrote 93% of the code in this release. + +### Aider v0.79.1 + +- Improved model listing to include all models in fuzzy matching, including those provided by aider (not litellm). + +### Aider v0.79.0 + +- Added support for Gemini 2.5 Pro models. +- Added support for DeepSeek V3 0324 model. +- Added a new `/context` command that automatically identifies which files need to be edited for a given request. +- Added `/edit` as an alias for the `/editor` command. +- Added "overeager" mode for Claude 3.7 Sonnet models to try and keep it working within the requested scope. +- Aider wrote 65% of the code in this release. + +### Aider v0.78.0 + +- Added support for thinking tokens for OpenRouter Sonnet 3.7. +- Added commands to switch between model types: `/editor-model` for Editor Model, and `/weak-model` for Weak Model, by csala. +- Added model setting validation to ignore `--reasoning-effort` and `--thinking-tokens` if the model doesn't support them. +- Added `--check-model-accepts-settings` flag (default: true) to force unsupported model settings. +- Annotated which models support reasoning_effort and thinking_tokens settings in the model settings data. +- Improved code block rendering in markdown output with better padding using NoInsetMarkdown. +- Added `--git-commit-verify` flag (default: False) to control whether git commit hooks are bypassed. +- Fixed autocompletion for `/ask`, `/code`, and `/architect` commands, by shladnik. +- Added vi-like behavior when pressing enter in multiline-mode while in vi normal/navigation-mode, by Marco Mayer. +- Added AWS_PROFILE support for Bedrock models, allowing use of AWS profiles instead of explicit credentials, by lentil32. +- Enhanced `--aiderignore` argument to resolve both absolute and relative paths, by mopemope. +- Improved platform information handling to gracefully handle retrieval errors. +- Aider wrote 92% of the code in this release. + +### Aider v0.77.1 + +- Bumped dependencies to pickup litellm fix for Ollama. +- Added support for `openrouter/google/gemma-3-27b-it` model. +- Updated exclude patterns for help documentation. + +### Aider v0.77.0 + +- Big upgrade in [programming languages supported](https://aider.chat/docs/languages.html) by adopting [tree-sitter-language-pack](https://github.com/Goldziher/tree-sitter-language-pack/). + - 130 new languages with linter support. + - 20 new languages with repo-map support. +- Added `/think-tokens` command to set thinking token budget with support for human-readable formats (8k, 10.5k, 0.5M). +- Added `/reasoning-effort` command to control model reasoning level. +- The `/think-tokens` and `/reasoning-effort` commands display current settings when called without arguments. +- Display of thinking token budget and reasoning effort in model information. +- Changed `--thinking-tokens` argument to accept string values with human-readable formats. +- Added `--auto-accept-architect` flag (default: true) to automatically accept changes from architect coder format without confirmation. +- Added support for `cohere_chat/command-a-03-2025` and `gemini/gemma-3-27b-it` +- The bare `/drop` command now preserves original read-only files provided via args.read. +- Fixed a bug where default model would be set by deprecated `--shortcut` switches even when already specified in the command line. +- Improved AutoCompleter to require 3 characters for autocompletion to reduce noise. +- Aider wrote 72% of the code in this release. + +### Aider v0.76.2 + +- Fixed handling of JSONDecodeError when loading model cache file. +- Fixed handling of GitCommandError when retrieving git user configuration. +- Aider wrote 75% of the code in this release. + +### Aider v0.76.1 + +- Added ignore_permission_denied option to file watcher to prevent errors when accessing restricted files, by Yutaka Matsubara. +- Aider wrote 0% of the code in this release. + +### Aider v0.76.0 + +- Improved support for thinking/reasoningmodels: + - Added `--thinking-tokens` CLI option to control token budget for models that support thinking. + - Display thinking/reasoning content from LLMs which return it. + - Enhanced handling of reasoning tags to better clean up model responses. + - Added deprecation warning for `remove_reasoning` setting, now replaced by `reasoning_tag`. +- Aider will notify you when it's completed the last request and needs your input: + - Added [notifications when LLM responses are ready](https://aider.chat/docs/usage/notifications.html) with `--notifications` flag. + - Specify desktop notification command with `--notifications-command`. +- Added support for QWQ 32B. +- Switch to `tree-sitter-language-pack` for tree sitter support. - Improved error handling for EOF (Ctrl+D) in user input prompts. - Added helper function to ensure hex color values have a # prefix. - Fixed handling of Git errors when reading staged files. - Improved SSL verification control for model information requests. -- Added support for QWQ 32B. -- Added [notifications when LLM responses are ready](https://aider.chat/docs/usage/notifications.html) with `--notifications` flag. -- Specify desktop notification command with `--notifications-command`. - Improved empty LLM response handling with clearer warning messages. - Fixed Git identity retrieval to respect global configuration, by Akira Komamura. - Offer to install dependencies for Bedrock and Vertex AI models. -- Aider wrote 82% of the code in this release. +- Deprecated model shortcut args (like --4o, --opus) in favor of the --model flag. +- Aider wrote 85% of the code in this release. ### Aider v0.75.3 diff --git a/README.md b/README.md index ced62cb95..f5b1dc5f0 100644 --- a/README.md +++ b/README.md @@ -1,150 +1,170 @@ +

+ Aider Logo +

- +

+AI Pair Programming in Your Terminal +

-# Aider is AI pair programming in your terminal -Aider lets you pair program with LLMs, -to edit code in your local git repository. -Start a new project or work with an existing code base. -Aider works best with Claude 3.7 Sonnet, DeepSeek R1 & Chat V3, OpenAI o1, o3-mini & GPT-4o. Aider can [connect to almost any LLM, including local models](https://aider.chat/docs/llms.html). +

+Aider lets you pair program with LLMs to start a new project or build on your existing codebase. +

-

aider screencast

- - -

- - - - - - -

- -## Getting started + GitHub Stars + PyPI Downloads + Tokens per week + OpenRouter Ranking + Singularity + +

-If you already have python 3.8-3.13 installed, you can get started quickly like this: +## Features + +### [Cloud and local LLMs](https://aider.chat/docs/llms.html) + + +Aider works best with Claude 3.7 Sonnet, DeepSeek R1 & Chat V3, OpenAI o1, o3-mini & GPT-4o, but can connect to almost any LLM, including local models. + +
+ +### [Maps your codebase](https://aider.chat/docs/repomap.html) + + +Aider makes a map of your entire codebase, which helps it work well in larger projects. + +
+ +### [100+ code languages](https://aider.chat/docs/languages.html) + + +Aider works with most popular programming languages: python, javascript, rust, ruby, go, cpp, php, html, css, and dozens more. + +
+ +### [Git integration](https://aider.chat/docs/git.html) + + +Aider automatically commits changes with sensible commit messages. Use familiar git tools to easily diff, manage and undo AI changes. + +
+ +### [Use in your IDE](https://aider.chat/docs/usage/watch.html) + + +Use aider from within your favorite IDE or editor. Ask for changes by adding comments to your code and aider will get to work. + +
+ +### [Images & web pages](https://aider.chat/docs/usage/images-urls.html) + + +Add images and web pages to the chat to provide visual context, screenshots, reference docs, etc. + +
+ +### [Voice-to-code](https://aider.chat/docs/usage/voice.html) + + +Speak with aider about your code! Request new features, test cases or bug fixes using your voice and let aider implement the changes. + +
+ +### [Linting & testing](https://aider.chat/docs/usage/lint-test.html) + + +Automatically lint and test your code every time aider makes changes. Aider can fix problems detected by your linters and test suites. + +
+ +### [Copy/paste to web chat](https://aider.chat/docs/usage/copypaste.html) + + +Work with any LLM via its web chat interface. Aider streamlines copy/pasting code context and edits back and forth with a browser. + +## Getting Started ```bash python -m pip install aider-install aider-install -# Change directory into your code base +# Change directory into your codebase cd /to/your/project -# Work with DeepSeek via DeepSeek's API -aider --model deepseek --api-key deepseek=your-key-goes-here +# DeepSeek +aider --model deepseek --api-key deepseek= -# Work with Claude 3.7 Sonnet via Anthropic's API -aider --model sonnet --api-key anthropic=your-key-goes-here +# Claude 3.7 Sonnet +aider --model sonnet --api-key anthropic= -# Work with GPT-4o via OpenAI's API -aider --model gpt-4o --api-key openai=your-key-goes-here - -# Work with Sonnet via OpenRouter's API -aider --model openrouter/anthropic/claude-3.7-sonnet --api-key openrouter=your-key-goes-here - -# Work with DeepSeek via OpenRouter's API -aider --model openrouter/deepseek/deepseek-chat --api-key openrouter=your-key-goes-here - -# Work with Github Copilot -aider --model github_copilot/claude-3.7-sonnet-thought +# o3-mini +aider --model o3-mini --api-key openai= ``` - -> [!TIP] -> If you have not authenticated with Github Copilot before, the first time you run Aider with the `github_copilot` model, you will be prompted to authenticate with Github Copilot using device code authentication. Follow the instructions in the terminal to authenticate. +See the [installation instructions](https://aider.chat/docs/install.html) and [usage documentation](https://aider.chat/docs/usage.html) for more details. -See the -[installation instructions](https://aider.chat/docs/install.html) -and -[usage documentation](https://aider.chat/docs/usage.html) -for more details. +## More Information -## Features - -- Run aider with the files you want to edit: `aider ...` -- Ask for changes: - - Add new features or test cases. - - Describe a bug. - - Paste in an error message or GitHub issue URL. - - Refactor code. - - Update docs. -- Aider will edit your files to complete your request. -- Aider [automatically git commits](https://aider.chat/docs/git.html) changes with a sensible commit message. -- [Use aider inside your favorite editor or IDE](https://aider.chat/docs/usage/watch.html). -- Aider works with [most popular languages](https://aider.chat/docs/languages.html): python, javascript, typescript, php, html, css, and more... -- Aider can edit multiple files at once for complex requests. -- Aider uses a [map of your entire git repo](https://aider.chat/docs/repomap.html), which helps it work well in larger codebases. -- Edit files in your editor or IDE while chatting with aider, -and it will always use the latest version. -Pair program with AI. -- [Add images to the chat](https://aider.chat/docs/usage/images-urls.html) (GPT-4o, Claude 3.5 Sonnet, etc). -- [Add URLs to the chat](https://aider.chat/docs/usage/images-urls.html) and aider will read their content. -- [Code with your voice](https://aider.chat/docs/usage/voice.html). -- Aider works best with Claude 3.7 Sonnet, DeepSeek V3, o1 & GPT-4o and can [connect to almost any LLM](https://aider.chat/docs/llms.html). - - -## Top tier performance - -[Aider has one of the top scores on SWE Bench](https://aider.chat/2024/06/02/main-swe-bench.html). -SWE Bench is a challenging software engineering benchmark where aider -solved *real* GitHub issues from popular open source -projects like django, scikitlearn, matplotlib, etc. - -## More info - -- [Documentation](https://aider.chat/) -- [Installation](https://aider.chat/docs/install.html) -- [Usage](https://aider.chat/docs/usage.html) -- [Tutorial videos](https://aider.chat/docs/usage/tutorials.html) +### Documentation +- [Installation Guide](https://aider.chat/docs/install.html) +- [Usage Guide](https://aider.chat/docs/usage.html) +- [Tutorial Videos](https://aider.chat/docs/usage/tutorials.html) - [Connecting to LLMs](https://aider.chat/docs/llms.html) -- [Configuration](https://aider.chat/docs/config.html) +- [Configuration Options](https://aider.chat/docs/config.html) - [Troubleshooting](https://aider.chat/docs/troubleshooting.html) +- [FAQ](https://aider.chat/docs/faq.html) + +### Community & Resources - [LLM Leaderboards](https://aider.chat/docs/leaderboards/) -- [GitHub](https://github.com/Aider-AI/aider) -- [Discord](https://discord.gg/Tv2uQnR88V) +- [GitHub Repository](https://github.com/Aider-AI/aider) +- [Discord Community](https://discord.gg/Tv2uQnR88V) - [Blog](https://aider.chat/blog/) +## Kind Words From Users -## Kind words from users - -- *The best free open source AI coding assistant.* -- [IndyDevDan](https://youtu.be/YALpX8oOn78) -- *The best AI coding assistant so far.* -- [Matthew Berman](https://www.youtube.com/watch?v=df8afeb1FY8) -- *Aider ... has easily quadrupled my coding productivity.* -- [SOLAR_FIELDS](https://news.ycombinator.com/item?id=36212100) -- *It's a cool workflow... Aider's ergonomics are perfect for me.* -- [qup](https://news.ycombinator.com/item?id=38185326) -- *It's really like having your senior developer live right in your Git repo - truly amazing!* -- [rappster](https://github.com/Aider-AI/aider/issues/124) -- *What an amazing tool. It's incredible.* -- [valyagolev](https://github.com/Aider-AI/aider/issues/6#issue-1722897858) -- *Aider is such an astounding thing!* -- [cgrothaus](https://github.com/Aider-AI/aider/issues/82#issuecomment-1631876700) -- *It was WAY faster than I would be getting off the ground and making the first few working versions.* -- [Daniel Feldman](https://twitter.com/d_feldman/status/1662295077387923456) -- *THANK YOU for Aider! It really feels like a glimpse into the future of coding.* -- [derwiki](https://news.ycombinator.com/item?id=38205643) -- *It's just amazing. It is freeing me to do things I felt were out my comfort zone before.* -- [Dougie](https://discord.com/channels/1131200896827654144/1174002618058678323/1174084556257775656) -- *This project is stellar.* -- [funkytaco](https://github.com/Aider-AI/aider/issues/112#issuecomment-1637429008) -- *Amazing project, definitely the best AI coding assistant I've used.* -- [joshuavial](https://github.com/Aider-AI/aider/issues/84) -- *I absolutely love using Aider ... It makes software development feel so much lighter as an experience.* -- [principalideal0](https://discord.com/channels/1131200896827654144/1133421607499595858/1229689636012691468) -- *I have been recovering from multiple shoulder surgeries ... and have used aider extensively. It has allowed me to continue productivity.* -- [codeninja](https://www.reddit.com/r/OpenAI/s/nmNwkHy1zG) -- *I am an aider addict. I'm getting so much more work done, but in less time.* -- [dandandan](https://discord.com/channels/1131200896827654144/1131200896827654149/1135913253483069470) -- *After wasting $100 on tokens trying to find something better, I'm back to Aider. It blows everything else out of the water hands down, there's no competition whatsoever.* -- [SystemSculpt](https://discord.com/channels/1131200896827654144/1131200896827654149/1178736602797846548) -- *Aider is amazing, coupled with Sonnet 3.5 it’s quite mind blowing.* -- [Josh Dingus](https://discord.com/channels/1131200896827654144/1133060684540813372/1262374225298198548) -- *Hands down, this is the best AI coding assistant tool so far.* -- [IndyDevDan](https://www.youtube.com/watch?v=MPYFPvxfGZs) -- *[Aider] changed my daily coding workflows. It's mind-blowing how a single Python application can change your life.* -- [maledorak](https://discord.com/channels/1131200896827654144/1131200896827654149/1258453375620747264) -- *Best agent for actual dev work in existing codebases.* -- [Nick Dobos](https://twitter.com/NickADobos/status/1690408967963652097?s=20) +- *"The best free open source AI coding assistant."* — [IndyDevDan](https://youtu.be/YALpX8oOn78) +- *"The best AI coding assistant so far."* — [Matthew Berman](https://www.youtube.com/watch?v=df8afeb1FY8) +- *"Aider ... has easily quadrupled my coding productivity."* — [SOLAR_FIELDS](https://news.ycombinator.com/item?id=36212100) +- *"It's a cool workflow... Aider's ergonomics are perfect for me."* — [qup](https://news.ycombinator.com/item?id=38185326) +- *"It's really like having your senior developer live right in your Git repo - truly amazing!"* — [rappster](https://github.com/Aider-AI/aider/issues/124) +- *"What an amazing tool. It's incredible."* — [valyagolev](https://github.com/Aider-AI/aider/issues/6#issue-1722897858) +- *"Aider is such an astounding thing!"* — [cgrothaus](https://github.com/Aider-AI/aider/issues/82#issuecomment-1631876700) +- *"It was WAY faster than I would be getting off the ground and making the first few working versions."* — [Daniel Feldman](https://twitter.com/d_feldman/status/1662295077387923456) +- *"THANK YOU for Aider! It really feels like a glimpse into the future of coding."* — [derwiki](https://news.ycombinator.com/item?id=38205643) +- *"It's just amazing. It is freeing me to do things I felt were out my comfort zone before."* — [Dougie](https://discord.com/channels/1131200896827654144/1174002618058678323/1174084556257775656) +- *"This project is stellar."* — [funkytaco](https://github.com/Aider-AI/aider/issues/112#issuecomment-1637429008) +- *"Amazing project, definitely the best AI coding assistant I've used."* — [joshuavial](https://github.com/Aider-AI/aider/issues/84) +- *"I absolutely love using Aider ... It makes software development feel so much lighter as an experience."* — [principalideal0](https://discord.com/channels/1131200896827654144/1133421607499595858/1229689636012691468) +- *"I have been recovering from multiple shoulder surgeries ... and have used aider extensively. It has allowed me to continue productivity."* — [codeninja](https://www.reddit.com/r/OpenAI/s/nmNwkHy1zG) +- *"I am an aider addict. I'm getting so much more work done, but in less time."* — [dandandan](https://discord.com/channels/1131200896827654144/1131200896827654149/1135913253483069470) +- *"After wasting $100 on tokens trying to find something better, I'm back to Aider. It blows everything else out of the water hands down, there's no competition whatsoever."* — [SystemSculpt](https://discord.com/channels/1131200896827654144/1131200896827654149/1178736602797846548) +- *"Aider is amazing, coupled with Sonnet 3.5 it's quite mind blowing."* — [Josh Dingus](https://discord.com/channels/1131200896827654144/1133060684540813372/1262374225298198548) +- *"Hands down, this is the best AI coding assistant tool so far."* — [IndyDevDan](https://www.youtube.com/watch?v=MPYFPvxfGZs) +- *"[Aider] changed my daily coding workflows. It's mind-blowing how a single Python application can change your life."* — [maledorak](https://discord.com/channels/1131200896827654144/1131200896827654149/1258453375620747264) +- *"Best agent for actual dev work in existing codebases."* — [Nick Dobos](https://twitter.com/NickADobos/status/1690408967963652097?s=20) +- *"One of my favorite pieces of software. Blazing trails on new paradigms!"* — [Chris Wall](https://x.com/chris65536/status/1905053299251798432) +- *"Aider has been revolutionary for me and my work."* — [Starry Hope](https://x.com/starryhopeblog/status/1904985812137132056) +- *"Try aider! One of the best ways to vibe code."* — [Chris Wall](https://x.com/Chris65536/status/1905053418961391929) +- *"Aider is hands down the best. And it's free and opensource."* — [AriyaSavakaLurker](https://www.reddit.com/r/ChatGPTCoding/comments/1ik16y6/whats_your_take_on_aider/mbip39n/) +- *"Aider is also my best friend."* — [jzn21](https://www.reddit.com/r/ChatGPTCoding/comments/1heuvuo/aider_vs_cline_vs_windsurf_vs_cursor/m27dcnb/) +- *"Try Aider, it's worth it."* — [jorgejhms](https://www.reddit.com/r/ChatGPTCoding/comments/1heuvuo/aider_vs_cline_vs_windsurf_vs_cursor/m27cp99/) +- *"I like aider :)"* — [Chenwei Cui](https://x.com/ccui42/status/1904965344999145698) +- *"Aider is the precision tool of LLM code gen. It is minimal, thoughtful and capable of surgical changes to your codebase all while keeping the developer in control."* — [Reilly Sweetland](https://x.com/rsweetland/status/1904963807237259586) diff --git a/aider/__init__.py b/aider/__init__.py index 05050dcde..12299f17b 100644 --- a/aider/__init__.py +++ b/aider/__init__.py @@ -1,6 +1,6 @@ from packaging import version -__version__ = "0.75.3.dev" +__version__ = "0.79.3.dev" safe_version = __version__ try: diff --git a/aider/args.py b/aider/args.py index 591183f7c..6df19778b 100644 --- a/aider/args.py +++ b/aider/args.py @@ -3,6 +3,7 @@ import argparse import os import sys +from pathlib import Path import configargparse @@ -12,10 +13,20 @@ from aider.args_formatter import ( MarkdownHelpFormatter, YamlHelpFormatter, ) +from aider.deprecated import add_deprecated_model_args from .dump import dump # noqa: F401 +def resolve_aiderignore_path(path_str, git_root=None): + path = Path(path_str) + if path.is_absolute(): + return str(path) + elif git_root: + return str(Path(git_root) / path) + return str(path) + + def default_env_file(git_root): return os.path.join(git_root, ".env") if git_root else ".env" @@ -38,98 +49,6 @@ def get_parser(default_config_files, git_root): default=None, help="Specify the model to use for the main chat", ) - opus_model = "claude-3-opus-20240229" - group.add_argument( - "--opus", - action="store_const", - dest="model", - const=opus_model, - help=f"Use {opus_model} model for the main chat", - ) - sonnet_model = "anthropic/claude-3-7-sonnet-20250219" - group.add_argument( - "--sonnet", - action="store_const", - dest="model", - const=sonnet_model, - help=f"Use {sonnet_model} model for the main chat", - ) - haiku_model = "claude-3-5-haiku-20241022" - group.add_argument( - "--haiku", - action="store_const", - dest="model", - const=haiku_model, - help=f"Use {haiku_model} model for the main chat", - ) - gpt_4_model = "gpt-4-0613" - group.add_argument( - "--4", - "-4", - action="store_const", - dest="model", - const=gpt_4_model, - help=f"Use {gpt_4_model} model for the main chat", - ) - gpt_4o_model = "gpt-4o" - group.add_argument( - "--4o", - action="store_const", - dest="model", - const=gpt_4o_model, - help=f"Use {gpt_4o_model} model for the main chat", - ) - gpt_4o_mini_model = "gpt-4o-mini" - group.add_argument( - "--mini", - action="store_const", - dest="model", - const=gpt_4o_mini_model, - help=f"Use {gpt_4o_mini_model} model for the main chat", - ) - gpt_4_turbo_model = "gpt-4-1106-preview" - group.add_argument( - "--4-turbo", - action="store_const", - dest="model", - const=gpt_4_turbo_model, - help=f"Use {gpt_4_turbo_model} model for the main chat", - ) - gpt_3_model_name = "gpt-3.5-turbo" - group.add_argument( - "--35turbo", - "--35-turbo", - "--3", - "-3", - action="store_const", - dest="model", - const=gpt_3_model_name, - help=f"Use {gpt_3_model_name} model for the main chat", - ) - deepseek_model = "deepseek/deepseek-chat" - group.add_argument( - "--deepseek", - action="store_const", - dest="model", - const=deepseek_model, - help=f"Use {deepseek_model} model for the main chat", - ) - o1_mini_model = "o1-mini" - group.add_argument( - "--o1-mini", - action="store_const", - dest="model", - const=o1_mini_model, - help=f"Use {o1_mini_model} model for the main chat", - ) - o1_preview_model = "o1-preview" - group.add_argument( - "--o1-preview", - action="store_const", - dest="model", - const=o1_preview_model, - help=f"Use {o1_preview_model} model for the main chat", - ) ########## group = parser.add_argument_group("API Keys and settings") @@ -208,6 +127,11 @@ def get_parser(default_config_files, git_root): type=str, help="Set the reasoning_effort API parameter (default: not set)", ) + group.add_argument( + "--thinking-tokens", + type=str, + help="Set the thinking token budget for models that support it (default: not set)", + ) group.add_argument( "--verify-ssl", action=argparse.BooleanOptionalAction, @@ -234,6 +158,12 @@ def get_parser(default_config_files, git_root): const="architect", help="Use architect edit format for the main chat", ) + group.add_argument( + "--auto-accept-architect", + action=argparse.BooleanOptionalAction, + default=True, + help="Enable/disable automatic acceptance of architect changes (default: True)", + ) group.add_argument( "--weak-model", metavar="WEAK_MODEL", @@ -261,6 +191,14 @@ def get_parser(default_config_files, git_root): default=True, help="Only work with models that have meta-data available (default: True)", ) + group.add_argument( + "--check-model-accepts-settings", + action=argparse.BooleanOptionalAction, + default=True, + help=( + "Check if model accepts settings like reasoning_effort/thinking_tokens (default: True)" + ), + ) group.add_argument( "--max-chat-history-tokens", type=int, @@ -460,9 +398,11 @@ def get_parser(default_config_files, git_root): default_aiderignore_file = ( os.path.join(git_root, ".aiderignore") if git_root else ".aiderignore" ) + group.add_argument( "--aiderignore", metavar="AIDERIGNORE", + type=lambda path_str: resolve_aiderignore_path(path_str, git_root), default=default_aiderignore_file, help="Specify the aider ignore file (default: .aiderignore in git root)", ) @@ -508,6 +448,12 @@ def get_parser(default_config_files, git_root): default=False, help="Prefix all commit messages with 'aider: ' (default: False)", ) + group.add_argument( + "--git-commit-verify", + action=argparse.BooleanOptionalAction, + default=False, + help="Enable/disable git pre-commit hooks with --no-verify (default: False)", + ) group.add_argument( "--commit", action="store_true", @@ -842,6 +788,11 @@ def get_parser(default_config_files, git_root): help="Specify which editor to use for the /editor command", ) + ########## + group = parser.add_argument_group("Deprecated model settings") + # Add deprecated model shortcut arguments + add_deprecated_model_args(parser, group) + return parser diff --git a/aider/coders/__init__.py b/aider/coders/__init__.py index e9d334bc9..cb7172ca5 100644 --- a/aider/coders/__init__.py +++ b/aider/coders/__init__.py @@ -1,6 +1,7 @@ from .architect_coder import ArchitectCoder from .ask_coder import AskCoder from .base_coder import Coder +from .context_coder import ContextCoder from .editblock_coder import EditBlockCoder from .editblock_fenced_coder import EditBlockFencedCoder from .editor_editblock_coder import EditorEditBlockCoder @@ -23,4 +24,5 @@ __all__ = [ ArchitectCoder, EditorEditBlockCoder, EditorWholeFileCoder, + ContextCoder, ] diff --git a/aider/coders/architect_coder.py b/aider/coders/architect_coder.py index a561e3e0d..f3e2a38b1 100644 --- a/aider/coders/architect_coder.py +++ b/aider/coders/architect_coder.py @@ -6,6 +6,7 @@ from .base_coder import Coder class ArchitectCoder(AskCoder): edit_format = "architect" gpt_prompts = ArchitectPrompts() + auto_accept_architect = False def reply_completed(self): content = self.partial_response_content @@ -13,7 +14,7 @@ class ArchitectCoder(AskCoder): if not content or not content.strip(): return - if not self.io.confirm_ask("Edit the files?"): + if not self.auto_accept_architect and not self.io.confirm_ask("Edit the files?"): return kwargs = dict() diff --git a/aider/coders/base_coder.py b/aider/coders/base_coder.py index d07ea4998..7c4e9688b 100755 --- a/aider/coders/base_coder.py +++ b/aider/coders/base_coder.py @@ -207,10 +207,22 @@ class Coder: prefix = "Model" output = f"{prefix}: {main_model.name} with {self.edit_format} edit format" + + # Check for thinking token budget + thinking_tokens = main_model.get_thinking_tokens(main_model) + if thinking_tokens: + output += f", {thinking_tokens} think tokens" + + # Check for reasoning effort + reasoning_effort = main_model.get_reasoning_effort(main_model) + if reasoning_effort: + output += f", reasoning {reasoning_effort}" + if self.add_cache_headers or main_model.caches_by_default: output += ", prompt cache" if main_model.info.get("supports_assistant_prefill"): output += ", infinite output" + lines.append(output) if self.edit_format == "architect": @@ -310,6 +322,7 @@ class Coder: ignore_mentions=None, file_watcher=None, auto_copy_context=False, + auto_accept_architect=True, ): # Fill in a dummy Analytics if needed, but it is never .enable()'d self.analytics = analytics if analytics is not None else Analytics() @@ -322,6 +335,7 @@ class Coder: self.abs_root_path_cache = {} self.auto_copy_context = auto_copy_context + self.auto_accept_architect = auto_accept_architect self.ignore_mentions = ignore_mentions if not self.ignore_mentions: @@ -383,7 +397,7 @@ class Coder: self.main_model = main_model # Set the reasoning tag name based on model settings or default self.reasoning_tag_name = ( - self.main_model.remove_reasoning if self.main_model.remove_reasoning else REASONING_TAG + self.main_model.reasoning_tag if self.main_model.reasoning_tag else REASONING_TAG ) self.stream = stream and main_model.streaming @@ -1016,7 +1030,13 @@ class Coder: return None def get_platform_info(self): - platform_text = f"- Platform: {platform.platform()}\n" + platform_text = "" + try: + platform_text = f"- Platform: {platform.platform()}\n" + except KeyError: + # Skip platform info if it can't be retrieved + platform_text = "- Platform information unavailable\n" + shell_var = "COMSPEC" if os.name == "nt" else "SHELL" shell_val = os.getenv(shell_var) platform_text += f"- Shell: {shell_var}={shell_val}\n" @@ -1057,7 +1077,13 @@ class Coder: return platform_text def fmt_system_prompt(self, prompt): - lazy_prompt = self.gpt_prompts.lazy_prompt if self.main_model.lazy else "" + if self.main_model.lazy: + lazy_prompt = self.gpt_prompts.lazy_prompt + elif self.main_model.overeager: + lazy_prompt = self.gpt_prompts.overeager_prompt + else: + lazy_prompt = "" + platform_text = self.get_platform_info() if self.suggest_shell_commands: @@ -1430,7 +1456,8 @@ class Coder: return try: - self.reply_completed() + if self.reply_completed(): + return except KeyboardInterrupt: interrupted = True @@ -1573,22 +1600,26 @@ class Coder: ) ] - def get_file_mentions(self, content): + def get_file_mentions(self, content, ignore_current=False): words = set(word for word in content.split()) # drop sentence punctuation from the end words = set(word.rstrip(",.!;:?") for word in words) # strip away all kinds of quotes - quotes = "".join(['"', "'", "`"]) + quotes = "\"'`*_" words = set(word.strip(quotes) for word in words) - addable_rel_fnames = self.get_addable_relative_files() + if ignore_current: + addable_rel_fnames = self.get_all_relative_files() + existing_basenames = {} + else: + addable_rel_fnames = self.get_addable_relative_files() - # Get basenames of files already in chat or read-only - existing_basenames = {os.path.basename(f) for f in self.get_inchat_relative_files()} | { - os.path.basename(self.get_rel_fname(f)) for f in self.abs_read_only_fnames - } + # Get basenames of files already in chat or read-only + existing_basenames = {os.path.basename(f) for f in self.get_inchat_relative_files()} | { + os.path.basename(self.get_rel_fname(f)) for f in self.abs_read_only_fnames + } mentioned_rel_fnames = set() fname_to_rel_fnames = {} @@ -1712,7 +1743,10 @@ class Coder: try: reasoning_content = completion.choices[0].message.reasoning_content except AttributeError: - reasoning_content = None + try: + reasoning_content = completion.choices[0].message.reasoning + except AttributeError: + reasoning_content = None try: self.partial_response_content = completion.choices[0].message.content or "" @@ -1775,22 +1809,27 @@ class Coder: pass text = "" + try: reasoning_content = chunk.choices[0].delta.reasoning_content - if reasoning_content: - if not self.got_reasoning_content: - text += f"<{REASONING_TAG}>\n\n" - text += reasoning_content - self.got_reasoning_content = True - received_content = True except AttributeError: - pass + try: + reasoning_content = chunk.choices[0].delta.reasoning + except AttributeError: + reasoning_content = None + + if reasoning_content: + if not self.got_reasoning_content: + text += f"<{REASONING_TAG}>\n\n" + text += reasoning_content + self.got_reasoning_content = True + received_content = True try: content = chunk.choices[0].delta.content if content: if self.got_reasoning_content and not self.ended_reasoning_content: - text += f"\n\n\n\n" + text += f"\n\n\n\n" self.ended_reasoning_content = True text += content @@ -1922,11 +1961,6 @@ class Coder: f" ${format_cost(self.total_cost)} session." ) - if self.add_cache_headers and self.stream: - warning = " Use --no-stream for accurate caching costs." - self.usage_report = tokens_report + "\n" + cost_report + warning - return - if cache_hit_tokens and cache_write_tokens: sep = "\n" else: diff --git a/aider/coders/base_prompts.py b/aider/coders/base_prompts.py index c431c7520..af1d3af3c 100644 --- a/aider/coders/base_prompts.py +++ b/aider/coders/base_prompts.py @@ -14,6 +14,9 @@ You NEVER leave comments describing code without implementing it! You always COMPLETELY IMPLEMENT the needed code! """ + overeager_prompt = """Pay careful attention to the scope of the user's request. +Do what they ask, but no more.""" + example_messages = [] files_content_prefix = """I have *added these files to the chat* so you can go ahead and edit them. diff --git a/aider/coders/context_coder.py b/aider/coders/context_coder.py new file mode 100644 index 000000000..73fe64af0 --- /dev/null +++ b/aider/coders/context_coder.py @@ -0,0 +1,53 @@ +from .base_coder import Coder +from .context_prompts import ContextPrompts + + +class ContextCoder(Coder): + """Identify which files need to be edited for a given request.""" + + edit_format = "context" + gpt_prompts = ContextPrompts() + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + if not self.repo_map: + return + + self.repo_map.refresh = "always" + self.repo_map.max_map_tokens *= self.repo_map.map_mul_no_files + self.repo_map.map_mul_no_files = 1.0 + + def reply_completed(self): + content = self.partial_response_content + if not content or not content.strip(): + return True + + # dump(repr(content)) + current_rel_fnames = set(self.get_inchat_relative_files()) + mentioned_rel_fnames = set(self.get_file_mentions(content, ignore_current=True)) + + # dump(current_rel_fnames) + # dump(mentioned_rel_fnames) + # dump(current_rel_fnames == mentioned_rel_fnames) + + if mentioned_rel_fnames == current_rel_fnames: + return True + + if self.num_reflections >= self.max_reflections - 1: + return True + + self.abs_fnames = set() + for fname in mentioned_rel_fnames: + self.add_rel_fname(fname) + # dump(self.get_inchat_relative_files()) + + self.reflected_message = self.gpt_prompts.try_again + + # mentioned_idents = self.get_ident_mentions(cur_msg_text) + # if mentioned_idents: + + return True + + def check_for_file_mentions(self, content): + pass diff --git a/aider/coders/context_prompts.py b/aider/coders/context_prompts.py new file mode 100644 index 000000000..3c71a2334 --- /dev/null +++ b/aider/coders/context_prompts.py @@ -0,0 +1,75 @@ +# flake8: noqa: E501 + +from .base_prompts import CoderPrompts + + +class ContextPrompts(CoderPrompts): + main_system = """Act as an expert code analyst. +Understand the user's question or request, solely to determine ALL the existing sources files which will need to be modified. +Return the *complete* list of files which will need to be modified based on the user's request. +Explain why each file is needed, including names of key classes/functions/methods/variables. +Be sure to include or omit the names of files already added to the chat, based on whether they are actually needed or not. + +The user will use every file you mention, regardless of your commentary. +So *ONLY* mention the names of relevant files. +If a file is not relevant DO NOT mention it. + +Only return files that will need to be modified, not files that contain useful/relevant functions. + +You are only to discuss EXISTING files and symbols. +Only return existing files, don't suggest the names of new files or functions that we will need to create. + +Always reply to the user in {language}. + +Be concise in your replies. +Return: +1. A bulleted list of files the will need to be edited, and symbols that are highly relevant to the user's request. +2. A list of classes/functions/methods/variables that are located OUTSIDE those files which will need to be understood. Just the symbols names, *NOT* file names. + +# Your response *MUST* use this format: + +## ALL files we need to modify, with their relevant symbols: + +- alarms/buzz.py + - `Buzzer` class which can make the needed sound + - `Buzzer.buzz_buzz()` method triggers the sound +- alarms/time.py + - `Time.set_alarm(hour, minute)` to set the alarm + +## Relevant symbols from OTHER files: + +- AlarmManager class for setup/teardown of alarms +- SoundFactory will be used to create a Buzzer +""" + + example_messages = [] + + files_content_prefix = """These files have been *added these files to the chat* so we can see all of their contents. +*Trust this message as the true contents of the files!* +Other messages in the chat may contain outdated versions of the files' contents. +""" # noqa: E501 + + files_content_assistant_reply = ( + "Ok, I will use that as the true, current contents of the files." + ) + + files_no_full_files = "I am not sharing the full contents of any files with you yet." + + files_no_full_files_with_repo_map = "" + files_no_full_files_with_repo_map_reply = "" + + repo_content_prefix = """I am working with you on code in a git repository. +Here are summaries of some files present in my git repo. +If you need to see the full contents of any files to answer my questions, ask me to *add them to the chat*. +""" + + system_reminder = """ +NEVER RETURN CODE! +""" + + try_again = """I have updated the set of files added to the chat. +Review them to decide if this is the correct set of files or if we need to add more or remove files. + +If this is the right set, just return the current list of files. +Or return a smaller or larger set of files which need to be edited, with symbols that are highly relevant to the user's request. +""" diff --git a/aider/commands.py b/aider/commands.py index b6ece0373..420a36b4a 100644 --- a/aider/commands.py +++ b/aider/commands.py @@ -17,6 +17,7 @@ from aider import models, prompts, voice from aider.editor import pipe_editor from aider.format_settings import format_settings from aider.help import Help, install_help_extra +from aider.io import CommandCompletionException from aider.llm import litellm from aider.repo import ANY_GIT_ERROR from aider.run_cmd import run_cmd @@ -27,8 +28,9 @@ from .dump import dump # noqa: F401 class SwitchCoder(Exception): - def __init__(self, **kwargs): + def __init__(self, placeholder=None, **kwargs): self.kwargs = kwargs + self.placeholder = placeholder class Commands: @@ -59,6 +61,7 @@ class Commands: parser=None, verbose=False, editor=None, + original_read_only_fnames=None, ): self.io = io self.coder = coder @@ -77,11 +80,42 @@ class Commands: self.help = None self.editor = editor + # Store the original read-only filenames provided via args.read + self.original_read_only_fnames = set(original_read_only_fnames or []) + def cmd_model(self, args): - "Switch to a new LLM" + "Switch the Main Model to a new LLM" model_name = args.strip() - model = models.Model(model_name, weak_model=self.coder.main_model.weak_model.name) + model = models.Model( + model_name, + editor_model=self.coder.main_model.editor_model.name, + weak_model=self.coder.main_model.weak_model.name, + ) + models.sanity_check_models(self.io, model) + raise SwitchCoder(main_model=model) + + def cmd_editor_model(self, args): + "Switch the Editor Model to a new LLM" + + model_name = args.strip() + model = models.Model( + self.coder.main_model.name, + editor_model=model_name, + weak_model=self.coder.main_model.weak_model.name, + ) + models.sanity_check_models(self.io, model) + raise SwitchCoder(main_model=model) + + def cmd_weak_model(self, args): + "Switch the Weak Model to a new LLM" + + model_name = args.strip() + model = models.Model( + self.coder.main_model.name, + editor_model=self.coder.main_model.editor_model.name, + weak_model=model_name, + ) models.sanity_check_models(self.io, model) raise SwitchCoder(main_model=model) @@ -114,6 +148,10 @@ class Commands: " them." ), ), + ( + "context", + "Automatically identify which files will need to be edited.", + ), ] ) @@ -355,7 +393,21 @@ class Commands: def _drop_all_files(self): self.coder.abs_fnames = set() - self.coder.abs_read_only_fnames = set() + + # When dropping all files, keep those that were originally provided via args.read + if self.original_read_only_fnames: + # Keep only the original read-only files + to_keep = set() + for abs_fname in self.coder.abs_read_only_fnames: + rel_fname = self.coder.get_rel_fname(abs_fname) + if ( + abs_fname in self.original_read_only_fnames + or rel_fname in self.original_read_only_fnames + ): + to_keep.add(abs_fname) + self.coder.abs_read_only_fnames = to_keep + else: + self.coder.abs_read_only_fnames = set() def _clear_chat_history(self): self.coder.done_messages = [] @@ -822,7 +874,12 @@ class Commands: "Remove files from the chat session to free up context space" if not args.strip(): - self.io.tool_output("Dropping all files from the chat session.") + if self.original_read_only_fnames: + self.io.tool_output( + "Dropping all files from the chat session except originally read-only files." + ) + else: + self.io.tool_output("Dropping all files from the chat session.") self._drop_all_files() return @@ -1065,6 +1122,18 @@ class Commands: show_announcements=False, ) + def completions_ask(self): + raise CommandCompletionException() + + def completions_code(self): + raise CommandCompletionException() + + def completions_architect(self): + raise CommandCompletionException() + + def completions_context(self): + raise CommandCompletionException() + def cmd_ask(self, args): """Ask questions about the code base without editing any files. If no prompt provided, switches to ask mode.""" # noqa return self._generic_chat_command(args, "ask") @@ -1077,7 +1146,11 @@ class Commands: """Enter architect/editor mode using 2 different models. If no prompt provided, switches to architect/editor mode.""" # noqa return self._generic_chat_command(args, "architect") - def _generic_chat_command(self, args, edit_format): + def cmd_context(self, args): + """Enter context mode to see surrounding code context. If no prompt provided, switches to context mode.""" # noqa + return self._generic_chat_command(args, "context", placeholder=args.strip() or None) + + def _generic_chat_command(self, args, edit_format, placeholder=None): if not args.strip(): # Switch to the corresponding chat mode if no args provided return self.cmd_chat_mode(edit_format) @@ -1094,11 +1167,13 @@ class Commands: user_msg = args coder.run(user_msg) + # Use the provided placeholder if any raise SwitchCoder( edit_format=self.coder.edit_format, summarize_from_coder=False, from_coder=coder, show_announcements=False, + placeholder=placeholder, ) def get_help_md(self): @@ -1411,6 +1486,62 @@ class Commands: if user_input.strip(): self.io.set_placeholder(user_input.rstrip()) + def cmd_edit(self, args=""): + "Alias for /editor: Open an editor to write a prompt" + return self.cmd_editor(args) + + def cmd_think_tokens(self, args): + "Set the thinking token budget (supports formats like 8096, 8k, 10.5k, 0.5M)" + model = self.coder.main_model + + if not args.strip(): + # Display current value if no args are provided + formatted_budget = model.get_thinking_tokens(model) + if formatted_budget is None: + self.io.tool_output("Thinking tokens are not currently set.") + else: + budget = model.extra_params["thinking"].get("budget_tokens") + self.io.tool_output( + f"Current thinking token budget: {budget:,} tokens ({formatted_budget})." + ) + return + + value = args.strip() + model.set_thinking_tokens(value) + + formatted_budget = model.get_thinking_tokens(model) + budget = model.extra_params["thinking"].get("budget_tokens") + + self.io.tool_output(f"Set thinking token budget to {budget:,} tokens ({formatted_budget}).") + self.io.tool_output() + + # Output announcements + announcements = "\n".join(self.coder.get_announcements()) + self.io.tool_output(announcements) + + def cmd_reasoning_effort(self, args): + "Set the reasoning effort level (values: number or low/medium/high depending on model)" + model = self.coder.main_model + + if not args.strip(): + # Display current value if no args are provided + reasoning_value = model.get_reasoning_effort(model) + if reasoning_value is None: + self.io.tool_output("Reasoning effort is not currently set.") + else: + self.io.tool_output(f"Current reasoning effort: {reasoning_value}") + return + + value = args.strip() + model.set_reasoning_effort(value) + reasoning_value = model.get_reasoning_effort(model) + self.io.tool_output(f"Set reasoning effort to {reasoning_value}") + self.io.tool_output() + + # Output announcements + announcements = "\n".join(self.coder.get_announcements()) + self.io.tool_output(announcements) + def cmd_copy_context(self, args=None): """Copy the current chat context as markdown, suitable to paste into a web UI""" diff --git a/aider/deprecated.py b/aider/deprecated.py new file mode 100644 index 000000000..e40924f5c --- /dev/null +++ b/aider/deprecated.py @@ -0,0 +1,126 @@ +def add_deprecated_model_args(parser, group): + """Add deprecated model shortcut arguments to the argparse parser.""" + opus_model = "claude-3-opus-20240229" + group.add_argument( + "--opus", + action="store_true", + help=f"Use {opus_model} model for the main chat (deprecated, use --model)", + default=False, + ) + sonnet_model = "anthropic/claude-3-7-sonnet-20250219" + group.add_argument( + "--sonnet", + action="store_true", + help=f"Use {sonnet_model} model for the main chat (deprecated, use --model)", + default=False, + ) + haiku_model = "claude-3-5-haiku-20241022" + group.add_argument( + "--haiku", + action="store_true", + help=f"Use {haiku_model} model for the main chat (deprecated, use --model)", + default=False, + ) + gpt_4_model = "gpt-4-0613" + group.add_argument( + "--4", + "-4", + action="store_true", + help=f"Use {gpt_4_model} model for the main chat (deprecated, use --model)", + default=False, + ) + gpt_4o_model = "gpt-4o" + group.add_argument( + "--4o", + action="store_true", + help=f"Use {gpt_4o_model} model for the main chat (deprecated, use --model)", + default=False, + ) + gpt_4o_mini_model = "gpt-4o-mini" + group.add_argument( + "--mini", + action="store_true", + help=f"Use {gpt_4o_mini_model} model for the main chat (deprecated, use --model)", + default=False, + ) + gpt_4_turbo_model = "gpt-4-1106-preview" + group.add_argument( + "--4-turbo", + action="store_true", + help=f"Use {gpt_4_turbo_model} model for the main chat (deprecated, use --model)", + default=False, + ) + gpt_3_model_name = "gpt-3.5-turbo" + group.add_argument( + "--35turbo", + "--35-turbo", + "--3", + "-3", + action="store_true", + help=f"Use {gpt_3_model_name} model for the main chat (deprecated, use --model)", + default=False, + ) + deepseek_model = "deepseek/deepseek-chat" + group.add_argument( + "--deepseek", + action="store_true", + help=f"Use {deepseek_model} model for the main chat (deprecated, use --model)", + default=False, + ) + o1_mini_model = "o1-mini" + group.add_argument( + "--o1-mini", + action="store_true", + help=f"Use {o1_mini_model} model for the main chat (deprecated, use --model)", + default=False, + ) + o1_preview_model = "o1-preview" + group.add_argument( + "--o1-preview", + action="store_true", + help=f"Use {o1_preview_model} model for the main chat (deprecated, use --model)", + default=False, + ) + + +def handle_deprecated_model_args(args, io): + """Handle deprecated model shortcut arguments and provide appropriate warnings.""" + # Define model mapping + model_map = { + "opus": "claude-3-opus-20240229", + "sonnet": "anthropic/claude-3-7-sonnet-20250219", + "haiku": "claude-3-5-haiku-20241022", + "4": "gpt-4-0613", + "4o": "gpt-4o", + "mini": "gpt-4o-mini", + "4_turbo": "gpt-4-1106-preview", + "35turbo": "gpt-3.5-turbo", + "deepseek": "deepseek/deepseek-chat", + "o1_mini": "o1-mini", + "o1_preview": "o1-preview", + } + + # Check if any deprecated args are used + for arg_name, model_name in model_map.items(): + arg_name_clean = arg_name.replace("-", "_") + if hasattr(args, arg_name_clean) and getattr(args, arg_name_clean): + # Find preferred name to display in warning + from aider.models import MODEL_ALIASES + + display_name = model_name + # Check if there's a shorter alias for this model + for alias, full_name in MODEL_ALIASES.items(): + if full_name == model_name: + display_name = alias + break + + # Show the warning + io.tool_warning( + f"The --{arg_name.replace('_', '-')} flag is deprecated and will be removed in a" + f" future version. Please use --model {display_name} instead." + ) + + # Set the model + if not args.model: + args.model = model_name + break diff --git a/aider/exceptions.py b/aider/exceptions.py index 2fc810430..3c2ff0c30 100644 --- a/aider/exceptions.py +++ b/aider/exceptions.py @@ -83,4 +83,8 @@ class LiteLLMExceptions: ) if "boto3" in str(ex): return ExInfo("APIConnectionError", False, "You need to: pip install boto3") + if "OpenrouterException" in str(ex) and "'choices'" in str(ex): + return ExInfo( + "APIConnectionError", True, "The OpenRouter API provider is down or overloaded." + ) return self.exceptions.get(ex.__class__, ExInfo(None, None, None)) diff --git a/aider/help_pats.py b/aider/help_pats.py index 5d2b14865..546517d66 100644 --- a/aider/help_pats.py +++ b/aider/help_pats.py @@ -10,4 +10,10 @@ exclude_website_pats = [ "docs/unified-diffs.md", "docs/leaderboards/index.md", "assets/**", + ".jekyll-metadata", + "Gemfile.lock", + "Gemfile", + "_config.yml", + "**/OLD/**", + "OLD/**", ] diff --git a/aider/io.py b/aider/io.py index d328b6bb3..053f739db 100644 --- a/aider/io.py +++ b/aider/io.py @@ -18,6 +18,7 @@ from prompt_toolkit.enums import EditingMode from prompt_toolkit.filters import Condition, is_searching from prompt_toolkit.history import FileHistory from prompt_toolkit.key_binding import KeyBindings +from prompt_toolkit.key_binding.vi_state import InputMode from prompt_toolkit.keys import Keys from prompt_toolkit.lexers import PygmentsLexer from prompt_toolkit.output.vt100 import is_dumb_terminal @@ -34,6 +35,7 @@ from rich.text import Text from aider.mdstream import MarkdownStream from .dump import dump # noqa: F401 +from .editor import pipe_editor from .utils import is_image_file # Constants @@ -68,6 +70,13 @@ def restore_multiline(func): return wrapper +class CommandCompletionException(Exception): + """Raised when a command should use the normal autocompleter instead of + command-specific completion.""" + + pass + + @dataclass class ConfirmGroup: preference: str = None @@ -186,14 +195,23 @@ class AutoCompleter(Completer): return if text[0] == "/": - yield from self.get_command_completions(document, complete_event, text, words) - return + try: + yield from self.get_command_completions(document, complete_event, text, words) + return + except CommandCompletionException: + # Fall through to normal completion + pass candidates = self.words candidates.update(set(self.fname_to_rel_fnames)) candidates = [word if type(word) is tuple else (word, word) for word in candidates] last_word = words[-1] + + # Only provide completions if the user has typed at least 3 characters + if len(last_word) < 3: + return + completions = [] for word_match, word_insert in candidates: if word_match.lower().startswith(last_word.lower()): @@ -487,11 +505,16 @@ class InputOutput: get_rel_fname(fname, root) for fname in (abs_read_only_fnames or []) ] show = self.format_files_for_input(rel_fnames, rel_read_only_fnames) + + prompt_prefix = "" if edit_format: - show += edit_format + prompt_prefix += edit_format if self.multiline_mode: - show += (" " if edit_format else "") + "multi" - show += "> " + prompt_prefix += (" " if edit_format else "") + "multi" + prompt_prefix += "> " + + show += prompt_prefix + self.prompt_prefix = prompt_prefix inp = "" multiline_input = False @@ -534,12 +557,31 @@ class InputOutput: def _(event): "Navigate forward through history" event.current_buffer.history_forward() + + @kb.add("c-x", "c-e") + def _(event): + "Edit current input in external editor (like Bash)" + buffer = event.current_buffer + current_text = buffer.text + + # Open the editor with the current text + edited_text = pipe_editor(input_data=current_text) + + # Replace the buffer with the edited text, strip any trailing newlines + buffer.text = edited_text.rstrip('\n') + + # Move cursor to the end of the text + buffer.cursor_position = len(buffer.text) @kb.add("enter", eager=True, filter=~is_searching) def _(event): "Handle Enter key press" - if self.multiline_mode: - # In multiline mode, Enter adds a newline + if self.multiline_mode and not ( + self.editingmode == EditingMode.VI + and event.app.vi_state.input_mode == InputMode.NAVIGATION + ): + # In multiline mode and if not in vi-mode or vi navigation/normal mode, + # Enter adds a newline event.current_buffer.insert_text("\n") else: # In normal mode, Enter submits @@ -557,7 +599,7 @@ class InputOutput: while True: if multiline_input: - show = ". " + show = self.prompt_prefix try: if self.prompt_session: @@ -573,7 +615,7 @@ class InputOutput: self.clipboard_watcher.start() def get_continuation(width, line_number, is_soft_wrap): - return ". " + return self.prompt_prefix line = self.prompt_session.prompt( show, diff --git a/aider/main.py b/aider/main.py index e11db45f3..652425905 100644 --- a/aider/main.py +++ b/aider/main.py @@ -24,11 +24,13 @@ from aider.coders import Coder from aider.coders.base_coder import UnknownEditFormat from aider.commands import Commands, SwitchCoder from aider.copypaste import ClipboardWatcher +from aider.deprecated import handle_deprecated_model_args from aider.format_settings import format_settings, scrub_sensitive_info from aider.history import ChatSummary from aider.io import InputOutput from aider.llm import litellm # noqa: F401; properly init litellm on launch from aider.models import ModelSettings +from aider.onboarding import select_default_model from aider.repo import ANY_GIT_ERROR, GitRepo from aider.report import report_uncaught_exceptions from aider.versioncheck import check_version, install_from_main_branch, install_upgrade @@ -125,8 +127,15 @@ def setup_git(git_root, io): if not repo: return - user_name = repo.git.config("--default", "", "--get", "user.name") or None - user_email = repo.git.config("--default", "", "--get", "user.email") or None + try: + user_name = repo.git.config("--get", "user.name") or None + except git.exc.GitCommandError: + user_name = None + + try: + user_email = repo.git.config("--get", "user.email") or None + except git.exc.GitCommandError: + user_email = None if user_name and user_email: return repo.working_tree_dir @@ -349,11 +358,21 @@ def register_models(git_root, model_settings_fname, io, verbose=False): def load_dotenv_files(git_root, dotenv_fname, encoding="utf-8"): + # Standard .env file search path dotenv_files = generate_search_path_list( ".env", git_root, dotenv_fname, ) + + # Explicitly add the OAuth keys file to the beginning of the list + oauth_keys_file = Path.home() / ".aider" / "oauth-keys.env" + if oauth_keys_file.exists(): + # Insert at the beginning so it's loaded first (and potentially overridden) + dotenv_files.insert(0, str(oauth_keys_file.resolve())) + # Remove duplicates if it somehow got included by generate_search_path_list + dotenv_files = list(dict.fromkeys(dotenv_files)) + loaded = [] for fname in dotenv_files: try: @@ -560,6 +579,9 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F io = get_io(False) io.tool_warning("Terminal does not support pretty output (UnicodeDecodeError)") + if args.stream and args.cache_prompts: + io.tool_warning("Cost estimates may be inaccurate when using streaming and caching.") + # Process any environment variables set via --set-env if args.set_env: for env_setting in args.set_env: @@ -588,6 +610,9 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F if args.openai_api_key: os.environ["OPENAI_API_KEY"] = args.openai_api_key + + # Handle deprecated model shortcut args + handle_deprecated_model_args(args, io) if args.openai_api_base: os.environ["OPENAI_API_BASE"] = args.openai_api_base if args.openai_api_version: @@ -703,11 +728,6 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F if args.check_update: check_version(io, verbose=args.verbose) - if args.list_models: - models.print_matching_models(io, args.list_models) - analytics.event("exit", reason="Listed models") - return 0 - if args.git: git_root = setup_git(git_root, io) if args.gitignore: @@ -727,6 +747,11 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F register_models(git_root, args.model_settings_file, io, verbose=args.verbose) register_litellm_models(git_root, args.model_metadata_file, io, verbose=args.verbose) + if args.list_models: + models.print_matching_models(io, args.list_models) + analytics.event("exit", reason="Listed models") + return 0 + # Process any command line aliases if args.alias: for alias_def in args.alias: @@ -740,42 +765,60 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F alias, model = parts models.MODEL_ALIASES[alias.strip()] = model.strip() - if not args.model: - # Select model based on available API keys - model_key_pairs = [ - ("ANTHROPIC_API_KEY", "sonnet"), - ("DEEPSEEK_API_KEY", "deepseek"), - ("OPENROUTER_API_KEY", "openrouter/anthropic/claude-3.7-sonnet"), - ("OPENAI_API_KEY", "gpt-4o"), - ("GEMINI_API_KEY", "flash"), - ] - - for env_key, model_name in model_key_pairs: - if os.environ.get(env_key): - args.model = model_name - io.tool_warning( - f"Found {env_key} so using {model_name} since no --model was specified." - ) - break - if not args.model: - io.tool_error("You need to specify a --model and an --api-key to use.") - io.offer_url(urls.models_and_keys, "Open documentation url for more info?") - return 1 + selected_model_name = select_default_model(args, io, analytics) + if not selected_model_name: + # Error message and analytics event are handled within select_default_model + return 1 + args.model = selected_model_name # Update args with the selected model main_model = models.Model( args.model, weak_model=args.weak_model, editor_model=args.editor_model, editor_edit_format=args.editor_edit_format, + verbose=args.verbose, ) - # add --reasoning-effort cli param + # Check if deprecated remove_reasoning is set + if main_model.remove_reasoning is not None: + io.tool_warning( + "Model setting 'remove_reasoning' is deprecated, please use 'reasoning_tag' instead." + ) + + # Set reasoning effort and thinking tokens if specified if args.reasoning_effort is not None: - if not getattr(main_model, "extra_params", None): - main_model.extra_params = {} - if "extra_body" not in main_model.extra_params: - main_model.extra_params["extra_body"] = {} - main_model.extra_params["extra_body"]["reasoning_effort"] = args.reasoning_effort + # Apply if check is disabled or model explicitly supports it + if not args.check_model_accepts_settings or ( + main_model.accepts_settings and "reasoning_effort" in main_model.accepts_settings + ): + main_model.set_reasoning_effort(args.reasoning_effort) + + if args.thinking_tokens is not None: + # Apply if check is disabled or model explicitly supports it + if not args.check_model_accepts_settings or ( + main_model.accepts_settings and "thinking_tokens" in main_model.accepts_settings + ): + main_model.set_thinking_tokens(args.thinking_tokens) + + # Show warnings about unsupported settings that are being ignored + if args.check_model_accepts_settings: + settings_to_check = [ + {"arg": args.reasoning_effort, "name": "reasoning_effort"}, + {"arg": args.thinking_tokens, "name": "thinking_tokens"}, + ] + + for setting in settings_to_check: + if setting["arg"] is not None and ( + not main_model.accepts_settings + or setting["name"] not in main_model.accepts_settings + ): + io.tool_warning( + f"Warning: {main_model.name} does not support '{setting['name']}', ignoring." + ) + io.tool_output( + f"Use --no-check-model-accepts-settings to force the '{setting['name']}'" + " setting." + ) if args.copy_paste and args.edit_format is None: if main_model.edit_format in ("diff", "whole"): @@ -824,6 +867,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F attribute_commit_message_committer=args.attribute_commit_message_committer, commit_prompt=args.commit_prompt, subtree_only=args.subtree_only, + git_commit_verify=args.git_commit_verify, ) except FileNotFoundError: pass @@ -849,6 +893,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F parser=parser, verbose=args.verbose, editor=args.editor, + original_read_only_fnames=read_only_fnames, ) summarizer = ChatSummary( @@ -871,6 +916,9 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F else: map_tokens = args.map_tokens + # Track auto-commits configuration + analytics.event("auto_commits", enabled=bool(args.auto_commits)) + try: coder = Coder.create( main_model=main_model, @@ -903,6 +951,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F chat_language=args.chat_language, detect_urls=args.detect_urls, auto_copy_context=args.copy_paste, + auto_accept_architect=args.auto_accept_architect, ) except UnknownEditFormat as err: io.tool_error(str(err)) @@ -1061,6 +1110,10 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F except SwitchCoder as switch: coder.ok_to_warm_cache = False + # Set the placeholder if provided + if hasattr(switch, "placeholder") and switch.placeholder is not None: + io.placeholder = switch.placeholder + kwargs = dict(io=io, from_coder=coder) kwargs.update(switch.kwargs) if "show_announcements" in kwargs: diff --git a/aider/mdstream.py b/aider/mdstream.py index e7e19df87..24c14f0d4 100755 --- a/aider/mdstream.py +++ b/aider/mdstream.py @@ -3,9 +3,12 @@ import io import time +from rich import box from rich.console import Console from rich.live import Live -from rich.markdown import Markdown +from rich.markdown import CodeBlock, Heading, Markdown +from rich.panel import Panel +from rich.syntax import Syntax from rich.text import Text from aider.dump import dump # noqa: F401 @@ -46,6 +49,46 @@ The end. """ # noqa: E501 +class NoInsetCodeBlock(CodeBlock): + """A code block with syntax highlighting and no padding.""" + + def __rich_console__(self, console, options): + code = str(self.text).rstrip() + syntax = Syntax(code, self.lexer_name, theme=self.theme, word_wrap=True, padding=(1, 0)) + yield syntax + + +class LeftHeading(Heading): + """A heading class that renders left-justified.""" + + def __rich_console__(self, console, options): + text = self.text + text.justify = "left" # Override justification + if self.tag == "h1": + # Draw a border around h1s, but keep text left-aligned + yield Panel( + text, + box=box.HEAVY, + style="markdown.h1.border", + ) + else: + # Styled text for h2 and beyond + if self.tag == "h2": + yield Text("") # Keep the blank line before h2 + yield text + + +class NoInsetMarkdown(Markdown): + """Markdown with code blocks that have no padding and left-justified headings.""" + + elements = { + **Markdown.elements, + "fence": NoInsetCodeBlock, + "code_block": NoInsetCodeBlock, + "heading_open": LeftHeading, + } + + class MarkdownStream: """Streaming markdown renderer that progressively displays content with a live updating window. @@ -88,7 +131,7 @@ class MarkdownStream: # Render the markdown to a string buffer string_io = io.StringIO() console = Console(file=string_io, force_terminal=True) - markdown = Markdown(text, **self.mdargs) + markdown = NoInsetMarkdown(text, **self.mdargs) console.print(markdown) output = string_io.getvalue() @@ -186,6 +229,7 @@ if __name__ == "__main__": _text = _text * 10 pm = MarkdownStream() + print("Using NoInsetMarkdown for code blocks with padding=0") for i in range(6, len(_text), 5): pm.update(_text[:i]) time.sleep(0.01) diff --git a/aider/models.py b/aider/models.py index 92d248f25..f9f69a566 100644 --- a/aider/models.py +++ b/aider/models.py @@ -90,6 +90,8 @@ MODEL_ALIASES = { "deepseek": "deepseek/deepseek-chat", "r1": "deepseek/deepseek-reasoner", "flash": "gemini/gemini-2.0-flash-exp", + "gemini-2.5-pro": "gemini/gemini-2.5-pro-exp-03-25", + "gemini": "gemini/gemini-2.5-pro-exp-03-25", } # Model metadata loaded from resources and user's files. @@ -103,6 +105,7 @@ class ModelSettings: use_repo_map: bool = False send_undo_reply: bool = False lazy: bool = False + overeager: bool = False reminder: str = "user" examples_as_sys_msg: bool = False extra_params: Optional[dict] = None @@ -113,8 +116,10 @@ class ModelSettings: streaming: bool = True editor_model_name: Optional[str] = None editor_edit_format: Optional[str] = None - remove_reasoning: Optional[str] = None + reasoning_tag: Optional[str] = None + remove_reasoning: Optional[str] = None # Deprecated alias for reasoning_tag system_prompt_prefix: Optional[str] = None + accepts_settings: Optional[list] = None # Load model settings from package resource @@ -152,7 +157,11 @@ class ModelInfoManager: if self.cache_file.exists(): cache_age = time.time() - self.cache_file.stat().st_mtime if cache_age < self.CACHE_TTL: - self.content = json.loads(self.cache_file.read_text()) + try: + self.content = json.loads(self.cache_file.read_text()) + except json.JSONDecodeError: + # If the cache file is corrupted, treat it as missing + self.content = None except OSError: pass @@ -225,11 +234,14 @@ model_info_manager = ModelInfoManager() class Model(ModelSettings): - def __init__(self, model, weak_model=None, editor_model=None, editor_edit_format=None): + def __init__( + self, model, weak_model=None, editor_model=None, editor_edit_format=None, verbose=False + ): # Map any alias to its canonical name model = MODEL_ALIASES.get(model, model) self.name = model + self.verbose = verbose self.max_chat_history_tokens = 1024 self.weak_model = None @@ -272,6 +284,11 @@ class Model(ModelSettings): val = getattr(source, field.name) setattr(self, field.name, val) + # Handle backward compatibility: if remove_reasoning is set but reasoning_tag isn't, + # use remove_reasoning's value for reasoning_tag + if self.reasoning_tag is None and self.remove_reasoning is not None: + self.reasoning_tag = self.remove_reasoning + def configure_model_settings(self, model): # Look for exact model match exact_match = False @@ -282,6 +299,10 @@ class Model(ModelSettings): exact_match = True break # Continue to apply overrides + # Initialize accepts_settings if it's None + if self.accepts_settings is None: + self.accepts_settings = [] + model = model.lower() # If no exact match, try generic settings @@ -309,6 +330,8 @@ class Model(ModelSettings): self.use_repo_map = True self.use_temperature = False self.system_prompt_prefix = "Formatting re-enabled. " + if "reasoning_effort" not in self.accepts_settings: + self.accepts_settings.append("reasoning_effort") return # <-- if "/o1-mini" in model: @@ -330,6 +353,8 @@ class Model(ModelSettings): self.use_temperature = False self.streaming = False self.system_prompt_prefix = "Formatting re-enabled. " + if "reasoning_effort" not in self.accepts_settings: + self.accepts_settings.append("reasoning_effort") return # <-- if "deepseek" in model and "v3" in model: @@ -344,7 +369,7 @@ class Model(ModelSettings): self.use_repo_map = True self.examples_as_sys_msg = True self.use_temperature = False - self.remove_reasoning = "think" + self.reasoning_tag = "think" return # <-- if ("llama3" in model or "llama-3" in model) and "70b" in model: @@ -370,6 +395,15 @@ class Model(ModelSettings): self.reminder = "sys" return # <-- + if "3-7-sonnet" in model: + self.edit_format = "diff" + self.use_repo_map = True + self.examples_as_sys_msg = True + self.reminder = "user" + if "thinking_tokens" not in self.accepts_settings: + self.accepts_settings.append("thinking_tokens") + return # <-- + if "3.5-sonnet" in model or "3-5-sonnet" in model: self.edit_format = "diff" self.use_repo_map = True @@ -397,7 +431,7 @@ class Model(ModelSettings): self.edit_format = "diff" self.editor_edit_format = "editor-diff" self.use_repo_map = True - self.remove_resoning = "think" + self.reasoning_tag = "think" self.examples_as_sys_msg = True self.use_temperature = 0.6 self.extra_params = dict(top_p=0.95) @@ -558,6 +592,21 @@ class Model(ModelSettings): model = self.name res = litellm.validate_environment(model) + + # If missing AWS credential keys but AWS_PROFILE is set, consider AWS credentials valid + if res["missing_keys"] and any( + key in ["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY"] for key in res["missing_keys"] + ): + if model.startswith("bedrock/") or model.startswith("us.anthropic."): + if os.environ.get("AWS_PROFILE"): + res["missing_keys"] = [ + k + for k in res["missing_keys"] + if k not in ["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY"] + ] + if not res["missing_keys"]: + res["keys_in_environment"] = True + if res["keys_in_environment"]: return res if res["missing_keys"]: @@ -582,6 +631,107 @@ class Model(ModelSettings): map_tokens = max(map_tokens, 1024) return map_tokens + def set_reasoning_effort(self, effort): + """Set the reasoning effort parameter for models that support it""" + if effort is not None: + if not self.extra_params: + self.extra_params = {} + if "extra_body" not in self.extra_params: + self.extra_params["extra_body"] = {} + self.extra_params["extra_body"]["reasoning_effort"] = effort + + def parse_token_value(self, value): + """ + Parse a token value string into an integer. + Accepts formats: 8096, "8k", "10.5k", "0.5M", "10K", etc. + + Args: + value: String or int token value + + Returns: + Integer token value + """ + if isinstance(value, int): + return value + + if not isinstance(value, str): + return int(value) # Try to convert to int + + value = value.strip().upper() + + if value.endswith("K"): + multiplier = 1024 + value = value[:-1] + elif value.endswith("M"): + multiplier = 1024 * 1024 + value = value[:-1] + else: + multiplier = 1 + + # Convert to float first to handle decimal values like "10.5k" + return int(float(value) * multiplier) + + def set_thinking_tokens(self, value): + """ + Set the thinking token budget for models that support it. + Accepts formats: 8096, "8k", "10.5k", "0.5M", "10K", etc. + """ + if value is not None: + num_tokens = self.parse_token_value(value) + self.use_temperature = False + if not self.extra_params: + self.extra_params = {} + + # OpenRouter models use 'reasoning' instead of 'thinking' + if self.name.startswith("openrouter/"): + self.extra_params["reasoning"] = {"max_tokens": num_tokens} + else: + self.extra_params["thinking"] = {"type": "enabled", "budget_tokens": num_tokens} + + def get_thinking_tokens(self, model): + """Get formatted thinking token budget if available""" + budget = None + + if model.extra_params: + # Check for OpenRouter reasoning format + if ( + "reasoning" in model.extra_params + and "max_tokens" in model.extra_params["reasoning"] + ): + budget = model.extra_params["reasoning"]["max_tokens"] + # Check for standard thinking format + elif ( + "thinking" in model.extra_params + and "budget_tokens" in model.extra_params["thinking"] + ): + budget = model.extra_params["thinking"]["budget_tokens"] + + if budget is not None: + # Format as xx.yK for thousands, xx.yM for millions + if budget >= 1024 * 1024: + value = budget / (1024 * 1024) + if value == int(value): + return f"{int(value)}M" + else: + return f"{value:.1f}M" + else: + value = budget / 1024 + if value == int(value): + return f"{int(value)}k" + else: + return f"{value:.1f}k" + return None + + def get_reasoning_effort(self, model): + """Get reasoning effort value if available""" + if ( + model.extra_params + and "extra_body" in model.extra_params + and "reasoning_effort" in model.extra_params["extra_body"] + ): + return model.extra_params["extra_body"]["reasoning_effort"] + return None + def is_deepseek_r1(self): name = self.name.lower() if "deepseek" not in name: @@ -600,7 +750,6 @@ class Model(ModelSettings): kwargs = dict( model=self.name, - messages=messages, stream=stream, ) @@ -629,6 +778,10 @@ class Model(ModelSettings): hash_object = hashlib.sha1(key) if "timeout" not in kwargs: kwargs["timeout"] = request_timeout + if self.verbose: + dump(kwargs) + kwargs["messages"] = messages + res = litellm.completion(**kwargs) return hash_object, res @@ -654,7 +807,7 @@ class Model(ModelSettings): res = response.choices[0].message.content from aider.reasoning_tags import remove_reasoning_content - return remove_reasoning_content(res, self.remove_reasoning) + return remove_reasoning_content(res, self.reasoning_tag) except litellm_ex.exceptions_tuple() as err: ex_info = litellm_ex.get_ex_info(err) @@ -823,7 +976,10 @@ def fuzzy_match_models(name): name = name.lower() chat_models = set() - for orig_model, attrs in litellm.model_cost.items(): + model_metadata = list(litellm.model_cost.items()) + model_metadata += list(model_info_manager.local_model_metadata.items()) + + for orig_model, attrs in model_metadata: model = orig_model.lower() if attrs.get("mode") != "chat": continue diff --git a/aider/onboarding.py b/aider/onboarding.py new file mode 100644 index 000000000..e24224c86 --- /dev/null +++ b/aider/onboarding.py @@ -0,0 +1,432 @@ +import base64 +import hashlib +import http.server +import os +import secrets +import socketserver +import threading +import time +import webbrowser +from urllib.parse import parse_qs, urlparse + +import requests + +from aider import urls +from aider.io import InputOutput +from aider.utils import check_pip_install_extra + + +def check_openrouter_tier(api_key): + """ + Checks if the user is on a free tier for OpenRouter. + + Args: + api_key: The OpenRouter API key to check. + + Returns: + A boolean indicating if the user is on a free tier (True) or paid tier (False). + Returns True if the check fails. + """ + try: + response = requests.get( + "https://openrouter.ai/api/v1/auth/key", + headers={"Authorization": f"Bearer {api_key}"}, + timeout=5, # Add a reasonable timeout + ) + response.raise_for_status() + data = response.json() + # According to the documentation, 'is_free_tier' will be true if the user has never paid + return data.get("data", {}).get("is_free_tier", True) # Default to True if not found + except Exception: + # If there's any error, we'll default to assuming free tier + return True + + +def try_to_select_default_model(): + """ + Attempts to select a default model based on available API keys. + Checks OpenRouter tier status to select appropriate model. + + Returns: + The name of the selected model, or None if no suitable default is found. + """ + # Special handling for OpenRouter + openrouter_key = os.environ.get("OPENROUTER_API_KEY") + if openrouter_key: + # Check if the user is on a free tier + is_free_tier = check_openrouter_tier(openrouter_key) + if is_free_tier: + return "openrouter/google/gemini-2.5-pro-exp-03-25:free" + else: + return "openrouter/anthropic/claude-3.7-sonnet" + + # Select model based on other available API keys + model_key_pairs = [ + ("ANTHROPIC_API_KEY", "sonnet"), + ("DEEPSEEK_API_KEY", "deepseek"), + ("OPENAI_API_KEY", "gpt-4o"), + ("GEMINI_API_KEY", "gemini/gemini-2.5-pro-exp-03-25"), + ("VERTEXAI_PROJECT", "vertex_ai/gemini-2.5-pro-exp-03-25"), + ] + + for env_key, model_name in model_key_pairs: + api_key_value = os.environ.get(env_key) + if api_key_value: + return model_name + + return None + + +def offer_openrouter_oauth(io, analytics): + """ + Offers OpenRouter OAuth flow to the user if no API keys are found. + + Args: + io: The InputOutput object for user interaction. + analytics: The Analytics object for tracking events. + + Returns: + True if authentication was successful, False otherwise. + """ + # No API keys found - Offer OpenRouter OAuth + io.tool_output("OpenRouter provides free and paid access to many LLMs.") + # Use confirm_ask which handles non-interactive cases + if io.confirm_ask( + "Login to OpenRouter or create a free account?", + default="y", + ): + analytics.event("oauth_flow_initiated", provider="openrouter") + openrouter_key = start_openrouter_oauth_flow(io, analytics) + if openrouter_key: + # Successfully got key via OAuth, use the default OpenRouter model + # Ensure OPENROUTER_API_KEY is now set in the environment for later use + os.environ["OPENROUTER_API_KEY"] = openrouter_key + # Track OAuth success leading to model selection + analytics.event("oauth_flow_success") + return True + + # OAuth failed or was cancelled by user implicitly (e.g., closing browser) + # Error messages are handled within start_openrouter_oauth_flow + analytics.event("oauth_flow_failure") + io.tool_error("OpenRouter authentication did not complete successfully.") + # Fall through to the final error message + + return False + + +def select_default_model(args, io, analytics): + """ + Selects a default model based on available API keys if no model is specified. + Offers OAuth flow for OpenRouter if no keys are found. + + Args: + args: The command line arguments object. + io: The InputOutput object for user interaction. + analytics: The Analytics object for tracking events. + + Returns: + The name of the selected model, or None if no suitable default is found. + """ + if args.model: + return args.model # Model already specified + + model = try_to_select_default_model() + if model: + io.tool_warning(f"Using {model} model with API key from environment.") + analytics.event("auto_model_selection", model=model) + return model + + no_model_msg = "No LLM model was specified and no API keys were provided." + io.tool_warning(no_model_msg) + + # Try OAuth if no model was detected + offer_openrouter_oauth(io, analytics) + + # Check again after potential OAuth success + model = try_to_select_default_model() + if model: + return model + + io.offer_url(urls.models_and_keys, "Open documentation URL for more info?") + + +# Helper function to find an available port +def find_available_port(start_port=8484, end_port=8584): + for port in range(start_port, end_port + 1): + try: + # Check if the port is available by trying to bind to it + with socketserver.TCPServer(("localhost", port), None): + return port + except OSError: + # Port is likely already in use + continue + return None + + +# PKCE code generation +def generate_pkce_codes(): + code_verifier = secrets.token_urlsafe(64) + hasher = hashlib.sha256() + hasher.update(code_verifier.encode("utf-8")) + code_challenge = base64.urlsafe_b64encode(hasher.digest()).rstrip(b"=").decode("utf-8") + return code_verifier, code_challenge + + +# Function to exchange the authorization code for an API key +def exchange_code_for_key(code, code_verifier, io): + try: + response = requests.post( + "https://openrouter.ai/api/v1/auth/keys", + headers={"Content-Type": "application/json"}, + json={ + "code": code, + "code_verifier": code_verifier, + "code_challenge_method": "S256", + }, + timeout=30, # Add a timeout + ) + response.raise_for_status() # Raise exception for bad status codes (4xx or 5xx) + data = response.json() + api_key = data.get("key") + if not api_key: + io.tool_error("Error: 'key' not found in OpenRouter response.") + io.tool_error(f"Response: {response.text}") + return None + return api_key + except requests.exceptions.Timeout: + io.tool_error("Error: Request to OpenRouter timed out during code exchange.") + return None + except requests.exceptions.HTTPError as e: + io.tool_error( + f"Error exchanging code for OpenRouter key: {e.status_code} {e.response.reason}" + ) + io.tool_error(f"Response: {e.response.text}") + return None + except requests.exceptions.RequestException as e: + io.tool_error(f"Error exchanging code for OpenRouter key: {e}") + return None + except Exception as e: + io.tool_error(f"Unexpected error during code exchange: {e}") + return None + + +# Function to start the OAuth flow +def start_openrouter_oauth_flow(io, analytics): + """Initiates the OpenRouter OAuth PKCE flow using a local server.""" + + # Check for requests library + if not check_pip_install_extra(io, "requests", "OpenRouter OAuth", "aider[oauth]"): + return None + + port = find_available_port() + if not port: + io.tool_error("Could not find an available port between 8484 and 8584.") + io.tool_error("Please ensure a port in this range is free, or configure manually.") + return None + + callback_url = f"http://localhost:{port}/callback/aider" + auth_code = None + server_error = None + server_started = threading.Event() + shutdown_server = threading.Event() + + class OAuthCallbackHandler(http.server.SimpleHTTPRequestHandler): + def do_GET(self): + nonlocal auth_code, server_error + parsed_path = urlparse(self.path) + if parsed_path.path == "/callback/aider": + query_params = parse_qs(parsed_path.query) + if "code" in query_params: + auth_code = query_params["code"][0] + self.send_response(200) + self.send_header("Content-type", "text/html") + self.end_headers() + self.wfile.write( + b"

Success!

" + b"

Aider has received the authentication code. " + b"You can close this browser tab.

" + ) + # Signal the main thread to shut down the server + # Signal the main thread to shut down the server + shutdown_server.set() + else: + # Redirect to aider website if 'code' is missing (e.g., user visited manually) + self.send_response(302) # Found (temporary redirect) + self.send_header("Location", urls.website) + self.end_headers() + # No need to set server_error, just redirect. + # Do NOT shut down the server here; wait for timeout or success. + else: + # Redirect anything else (e.g., favicon.ico) to the main website as well + self.send_response(302) + self.send_header("Location", urls.website) + self.end_headers() + self.wfile.write(b"Not Found") + + def log_message(self, format, *args): + # Suppress server logging to keep terminal clean + pass + + def run_server(): + nonlocal server_error + try: + with socketserver.TCPServer(("localhost", port), OAuthCallbackHandler) as httpd: + io.tool_output(f"Temporary server listening on {callback_url}", log_only=True) + server_started.set() # Signal that the server is ready + # Wait until shutdown is requested or timeout occurs (handled by main thread) + while not shutdown_server.is_set(): + httpd.handle_request() # Handle one request at a time + # Add a small sleep to prevent busy-waiting if needed, + # though handle_request should block appropriately. + time.sleep(0.1) + io.tool_output("Shutting down temporary server.", log_only=True) + except Exception as e: + server_error = f"Failed to start or run temporary server: {e}" + server_started.set() # Signal even if failed, error will be checked + shutdown_server.set() # Ensure shutdown logic proceeds + + server_thread = threading.Thread(target=run_server, daemon=True) + server_thread.start() + + # Wait briefly for the server to start, or for an error + if not server_started.wait(timeout=5): + io.tool_error("Temporary authentication server failed to start in time.") + shutdown_server.set() # Ensure thread exits if it eventually starts + server_thread.join(timeout=1) + return None + + # Check if server failed during startup + if server_error: + io.tool_error(server_error) + shutdown_server.set() # Ensure thread exits + server_thread.join(timeout=1) + return None + + # Generate codes and URL + code_verifier, code_challenge = generate_pkce_codes() + auth_url_base = "https://openrouter.ai/auth" + auth_params = { + "callback_url": callback_url, + "code_challenge": code_challenge, + "code_challenge_method": "S256", + } + auth_url = f"{auth_url_base}?{'&'.join(f'{k}={v}' for k, v in auth_params.items())}" + + io.tool_output("\nPlease open this URL in your browser to connect Aider with OpenRouter:") + io.tool_output() + print(auth_url) + + MINUTES = 5 + io.tool_output(f"\nWaiting up to {MINUTES} minutes for you to finish in the browser...") + io.tool_output("Use Control-C to interrupt.") + + try: + webbrowser.open(auth_url) + except Exception: + pass + + # Wait for the callback to set the auth_code or for timeout/error + interrupted = False + try: + shutdown_server.wait(timeout=MINUTES * 60) # Convert minutes to seconds + except KeyboardInterrupt: + io.tool_warning("\nOAuth flow interrupted.") + analytics.event("oauth_flow_failed", provider="openrouter", reason="user_interrupt") + interrupted = True + # Ensure the server thread is signaled to shut down + shutdown_server.set() + + # Join the server thread to ensure it's cleaned up + server_thread.join(timeout=1) + + if interrupted: + return None # Return None if interrupted by user + + if server_error: + io.tool_error(f"Authentication failed: {server_error}") + analytics.event("oauth_flow_failed", provider="openrouter", reason=server_error) + return None + + if not auth_code: + io.tool_error("Authentication with OpenRouter failed.") + analytics.event("oauth_flow_failed", provider="openrouter") + return None + + io.tool_output("Completing authentication...") + analytics.event("oauth_flow_code_received", provider="openrouter") + + # Exchange code for key + api_key = exchange_code_for_key(auth_code, code_verifier, io) + + if api_key: + # Set env var for the current session immediately + os.environ["OPENROUTER_API_KEY"] = api_key + + # Save the key to the oauth-keys.env file + try: + config_dir = os.path.expanduser("~/.aider") + os.makedirs(config_dir, exist_ok=True) + key_file = os.path.join(config_dir, "oauth-keys.env") + with open(key_file, "a", encoding="utf-8") as f: + f.write(f'OPENROUTER_API_KEY="{api_key}"\n') + + io.tool_warning("Aider will load the OpenRouter key automatically in future sessions.") + io.tool_output() + + analytics.event("oauth_flow_success", provider="openrouter") + return api_key + except Exception as e: + io.tool_error(f"Successfully obtained key, but failed to save it to file: {e}") + io.tool_warning("Set OPENROUTER_API_KEY environment variable for this session only.") + # Still return the key for the current session even if saving failed + analytics.event("oauth_flow_save_failed", provider="openrouter", reason=str(e)) + return api_key + else: + io.tool_error("Authentication with OpenRouter failed.") + analytics.event("oauth_flow_failed", provider="openrouter", reason="code_exchange_failed") + return None + + +# Dummy Analytics class for testing +class DummyAnalytics: + def event(self, *args, **kwargs): + # print(f"Analytics Event: {args} {kwargs}") # Optional: print events + pass + + +def main(): + """Main function to test the OpenRouter OAuth flow.""" + print("Starting OpenRouter OAuth flow test...") + + # Use a real IO object for interaction + io = InputOutput( + pretty=True, + yes=False, + input_history_file=None, + chat_history_file=None, + tool_output_color="BLUE", + tool_error_color="RED", + ) + # Use a dummy analytics object + analytics = DummyAnalytics() + + # Ensure OPENROUTER_API_KEY is not set, to trigger the flow naturally + # (though start_openrouter_oauth_flow doesn't check this itself) + if "OPENROUTER_API_KEY" in os.environ: + print("Warning: OPENROUTER_API_KEY is already set in environment.") + # del os.environ["OPENROUTER_API_KEY"] # Optionally unset it for testing + + api_key = start_openrouter_oauth_flow(io, analytics) + + if api_key: + print("\nOAuth flow completed successfully!") + print(f"Obtained API Key (first 5 chars): {api_key[:5]}...") + # Be careful printing the key, even partially + else: + print("\nOAuth flow failed or was cancelled.") + + print("\nOpenRouter OAuth flow test finished.") + + +if __name__ == "__main__": + main() diff --git a/aider/queries/tree-sitter-language-pack/README.md b/aider/queries/tree-sitter-language-pack/README.md new file mode 100644 index 000000000..4654865ef --- /dev/null +++ b/aider/queries/tree-sitter-language-pack/README.md @@ -0,0 +1,7 @@ +These scm files are all adapted from the github repositories listed here: + +https://github.com/Goldziher/tree-sitter-language-pack/blob/main/sources/language_definitions.json + +See this URL for information on the licenses of each repo: + +https://github.com/Goldziher/tree-sitter-language-pack/ diff --git a/aider/queries/tree-sitter-language-pack/arduino-tags.scm b/aider/queries/tree-sitter-language-pack/arduino-tags.scm new file mode 100644 index 000000000..71cc3849f --- /dev/null +++ b/aider/queries/tree-sitter-language-pack/arduino-tags.scm @@ -0,0 +1,5 @@ +(function_declarator + declarator: (identifier) @name.definition.function) @definition.function + +(call_expression + function: (identifier) @name.reference.call) @reference.call diff --git a/aider/queries/tree-sitter-language-pack/c-tags.scm b/aider/queries/tree-sitter-language-pack/c-tags.scm new file mode 100644 index 000000000..1035aa224 --- /dev/null +++ b/aider/queries/tree-sitter-language-pack/c-tags.scm @@ -0,0 +1,9 @@ +(struct_specifier name: (type_identifier) @name.definition.class body:(_)) @definition.class + +(declaration type: (union_specifier name: (type_identifier) @name.definition.class)) @definition.class + +(function_declarator declarator: (identifier) @name.definition.function) @definition.function + +(type_definition declarator: (type_identifier) @name.definition.type) @definition.type + +(enum_specifier name: (type_identifier) @name.definition.type) @definition.type diff --git a/aider/queries/tree-sitter-language-pack/chatito-tags.scm b/aider/queries/tree-sitter-language-pack/chatito-tags.scm new file mode 100644 index 000000000..6fbac9420 --- /dev/null +++ b/aider/queries/tree-sitter-language-pack/chatito-tags.scm @@ -0,0 +1,16 @@ +; Definitions +(intent_def + (intent) @name.definition.intent) @definition.intent + +(slot_def + (slot) @name.definition.slot) @definition.slot + +(alias_def + (alias) @name.definition.alias) @definition.alias + +; References +(slot_ref + (slot) @name.reference.slot) @reference.slot + +(alias_ref + (alias) @name.reference.alias) @reference.alias diff --git a/aider/queries/tree-sitter-language-pack/commonlisp-tags.scm b/aider/queries/tree-sitter-language-pack/commonlisp-tags.scm new file mode 100644 index 000000000..a47dfeeda --- /dev/null +++ b/aider/queries/tree-sitter-language-pack/commonlisp-tags.scm @@ -0,0 +1,122 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Function Definitions ;;;;;;;;;;;;;;;;;;;;;;; + +(defun_header + function_name: (sym_lit) @name.definition.function) @definition.function + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Function Calls ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; +;;; Basically, we consider every list literal with symbol as the +;;; first element to be a call to a function named by that element. +;;; But we must exclude some cases. Note, tree-sitter @ignore +;;; cases only work if they are declared before the cases +;;; we want to include. + +;; Exclude lambda lists for function definitions +;; For example: +;; +;; (defun my-func (arg1 arg2) ...) +;; +;; do not treat (arg1 arg2) as a call of function arg1 +;; +(defun_header + lambda_list: (list_lit . [(sym_lit) (package_lit)] @ignore)) + +;; Similar to the above, but for +;; +;; (defmethod m ((type1 param1) (type2 param2)) ...) +;; +;; where list literals having symbol as their first element +;; are nested inside the lambda list. +(defun_header + lambda_list: (list_lit (list_lit . [(sym_lit) (package_lit)] @ignore))) + +;; +;; (let ((var ...) (var2 ...)) ...) +;; +;; - exclude var, var2 +;; - the same for let*, flet, labels, macrolet, symbol-macrolet +(list_lit . [(sym_lit) (package_lit)] @name.reference.call + . (list_lit (list_lit . [(sym_lit) (package_lit)] @ignore)) + (#match? @name.reference.call + "(?i)^(cl:)?(let|let\\*|flet|labels|macrolet|symbol-macrolet)$") + ) + +;; TODO: +;; - exclude also: +;; - (defclass name (parent parent2) +;; ((slot1 ...) +;; (slot2 ...)) +;; exclude the parent, slot1, slot2 +;; - (flet ((func-1 (param1 param2))) ...) +;; - we already exclude func-1, but param1 is still recognized +;; as a function call - exclude it too +;; - the same for labels +;; - the same macrolet +;; - what else? +;; (that's a non-goal to completely support all macros +;; and special operators, but every one we support +;; makes the solution a little bit better) +;; - (flet ((func-1 (param1 param2))) ...) +;; - instead of simply excluding it, as we do today, +;; tag func-1 as @local.definition.function (I suppose) +;; - the same for labels, macrolet +;; - @local.scope for let, let*, flet, labels, macrolet +;; - I guess the whole span of the scope text, +;; till the closing paren, should be tagged as @local.scope; +;; Hopefully, combined with @local.definition.function +;; within the scope, the usual @reference.call within +;; that scope will refer to the local definition, +;; and there will be no need to use @local.reference.call +;; (which is more difficult to implement). +;; - When implementing, remember the scope rules differences +;; of let vs let*, flet vs labels. + + +;; Include all other cases - list literal with symbol as the +;; first element +(list_lit . [(sym_lit) (package_lit)] @name.reference.call) @reference.call + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; classes + +(list_lit . [(sym_lit) (package_lit)] @ignore + . [(sym_lit) (package_lit)] @name.definition.class + (#match? @ignore "(?i)^(cl:)?defclass$") + ) @definition.class + +(list_lit . [(sym_lit) (package_lit)] @ignore + . (quoting_lit [(sym_lit) (package_lit)] @name.reference.class) + (#match? @ignore "(?i)^(cl:)?make-instance$") + ) @reference.class + +;;; TODO: +;; - @reference.class for base classes + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; TODO: +;; - Symbols referenced in defpackage +;; +;; (defpackage ... +;; (:export (symbol-a :symbol-b #:symbol-c "SYMBOL-D"))) +;; +;; The goal is to allow quick navigation from the API +;; overview in the form of defpackage, to the definition +;; where user can read parameters, docstring, etc. +;; - The @name must not include the colon, or sharpsign colon, quotes, +;; just symbol-a, symbol-b, symbol-c, sybmol-d +;; - Downcase the names specified as string literals? +;; ("SYMBOL-D" -> symbol-d) +;; - We don't know if the exported symbol is a function, variable, +;; class or something else. The official doc +;; (https://tree-sitter.github.io/tree-sitter/code-navigation-systems) +;; does not even suggest a tag for variable reference. +;; (Although in practice, the `tree-sitter tags` command +;; allows any @reference.* and @definition.* tags) +;; Probably it's better to just use @reference.call for all +;; the symbols in the :export clause. +;; +;; - The same for the export function call: +;; +;; (export '(symbol-a :symbol-b #:symbol-c "SYMBOL-D")) diff --git a/aider/queries/tree-sitter-language-pack/cpp-tags.scm b/aider/queries/tree-sitter-language-pack/cpp-tags.scm new file mode 100644 index 000000000..00cc96637 --- /dev/null +++ b/aider/queries/tree-sitter-language-pack/cpp-tags.scm @@ -0,0 +1,15 @@ +(struct_specifier name: (type_identifier) @name.definition.class body:(_)) @definition.class + +(declaration type: (union_specifier name: (type_identifier) @name.definition.class)) @definition.class + +(function_declarator declarator: (identifier) @name.definition.function) @definition.function + +(function_declarator declarator: (field_identifier) @name.definition.function) @definition.function + +(function_declarator declarator: (qualified_identifier scope: (namespace_identifier) @local.scope name: (identifier) @name.definition.method)) @definition.method + +(type_definition declarator: (type_identifier) @name.definition.type) @definition.type + +(enum_specifier name: (type_identifier) @name.definition.type) @definition.type + +(class_specifier name: (type_identifier) @name.definition.class) @definition.class diff --git a/aider/queries/tree-sitter-language-pack/d-tags.scm b/aider/queries/tree-sitter-language-pack/d-tags.scm new file mode 100644 index 000000000..7572cc4a6 --- /dev/null +++ b/aider/queries/tree-sitter-language-pack/d-tags.scm @@ -0,0 +1,26 @@ +(module_def (module_declaration (module_fqn) @name.definition.module)) @definition.module + +(struct_declaration (struct) . (identifier) @name.definition.class) @definition.class +(interface_declaration (interface) . (identifier) @name.definition.interface) @definition.interface +(enum_declaration (enum) . (identifier) @name.definition.type) @definition.type + +(class_declaration (class) . (identifier) @name.definition.class) @definition.class +(constructor (this) @name.definition.method) @definition.method +(destructor (this) @name.definition.method) @definition.method +(postblit (this) @name.definition.method) @definition.method + +(manifest_declarator . (identifier) @name.definition.type) @definition.type + +(function_declaration (identifier) @name.definition.function) @definition.function + +(union_declaration (union) . (identifier) @name.definition.type) @definition.type + +(anonymous_enum_declaration (enum_member . (identifier) @name.definition.constant)) @definition.constant + +(enum_declaration (enum_member . (identifier) @name.definition.constant)) @definition.constant + +(call_expression (identifier) @name.reference.call) @reference.call +(call_expression (type (template_instance (identifier) @name.reference.call))) @reference.call +(parameter (type (identifier) @name.reference.class) @reference.class (identifier)) + +(variable_declaration (type (identifier) @name.reference.class) @reference.class (declarator)) diff --git a/aider/queries/tree-sitter-language-pack/dart-tags.scm b/aider/queries/tree-sitter-language-pack/dart-tags.scm new file mode 100644 index 000000000..a11fafcb1 --- /dev/null +++ b/aider/queries/tree-sitter-language-pack/dart-tags.scm @@ -0,0 +1,92 @@ + +(class_definition + name: (identifier) @name.definition.class) @definition.class + +(method_signature + (function_signature)) @definition.method + +(type_alias + (type_identifier) @name.definition.type) @definition.type + +(method_signature +(getter_signature + name: (identifier) @name.definition.method)) @definition.method + +(method_signature +(setter_signature + name: (identifier) @name.definition.method)) @definition.method + +(method_signature + (function_signature + name: (identifier) @name.definition.method)) @definition.method + +(method_signature + (factory_constructor_signature + (identifier) @name.definition.method)) @definition.method + +(method_signature + (constructor_signature + name: (identifier) @name.definition.method)) @definition.method + +(method_signature + (operator_signature)) @definition.method + +(method_signature) @definition.method + +(mixin_declaration + (mixin) + (identifier) @name.definition.mixin) @definition.mixin + +(extension_declaration + name: (identifier) @name.definition.extension) @definition.extension + + +(new_expression + (type_identifier) @name.reference.class) @reference.class + +(enum_declaration + name: (identifier) @name.definition.enum) @definition.enum + +(function_signature + name: (identifier) @name.definition.function) @definition.function + +(initialized_variable_definition + name: (identifier) + value: (identifier) @name.reference.class + value: (selector + "!"? + (argument_part + (arguments + (argument)*))?)?) @reference.class + +(assignment_expression + left: (assignable_expression + (identifier) + (unconditional_assignable_selector + "." + (identifier) @name.reference.send))) @reference.call + +(assignment_expression + left: (assignable_expression + (identifier) + (conditional_assignable_selector + "?." + (identifier) @name.reference.send))) @reference.call + +((identifier) @name.reference.send + (selector + "!"? + (conditional_assignable_selector + "?." (identifier) @name.reference.send)? + (unconditional_assignable_selector + "."? (identifier) @name.reference.send)? + (argument_part + (arguments + (argument)*))?)* + (cascade_section + (cascade_selector + (identifier)) @name.reference.send + (argument_part + (arguments + (argument)*))?)?) @reference.call + diff --git a/aider/queries/tree-sitter-language-pack/elisp-tags.scm b/aider/queries/tree-sitter-language-pack/elisp-tags.scm new file mode 100644 index 000000000..81e50d8e0 --- /dev/null +++ b/aider/queries/tree-sitter-language-pack/elisp-tags.scm @@ -0,0 +1,5 @@ +;; defun/defsubst +(function_definition name: (symbol) @name.definition.function) @definition.function + +;; Treat macros as function definitions for the sake of TAGS. +(macro_definition name: (symbol) @name.definition.function) @definition.function diff --git a/aider/queries/tree-sitter-language-pack/elixir-tags.scm b/aider/queries/tree-sitter-language-pack/elixir-tags.scm new file mode 100644 index 000000000..e0a351e32 --- /dev/null +++ b/aider/queries/tree-sitter-language-pack/elixir-tags.scm @@ -0,0 +1,54 @@ +; Definitions + +; * modules and protocols +(call + target: (identifier) @ignore + (arguments (alias) @name.definition.module) + (#any-of? @ignore "defmodule" "defprotocol")) @definition.module + +; * functions/macros +(call + target: (identifier) @ignore + (arguments + [ + ; zero-arity functions with no parentheses + (identifier) @name.definition.function + ; regular function clause + (call target: (identifier) @name.definition.function) + ; function clause with a guard clause + (binary_operator + left: (call target: (identifier) @name.definition.function) + operator: "when") + ]) + (#any-of? @ignore "def" "defp" "defdelegate" "defguard" "defguardp" "defmacro" "defmacrop" "defn" "defnp")) @definition.function + +; References + +; ignore calls to kernel/special-forms keywords +(call + target: (identifier) @ignore + (#any-of? @ignore "def" "defp" "defdelegate" "defguard" "defguardp" "defmacro" "defmacrop" "defn" "defnp" "defmodule" "defprotocol" "defimpl" "defstruct" "defexception" "defoverridable" "alias" "case" "cond" "else" "for" "if" "import" "quote" "raise" "receive" "require" "reraise" "super" "throw" "try" "unless" "unquote" "unquote_splicing" "use" "with")) + +; ignore module attributes +(unary_operator + operator: "@" + operand: (call + target: (identifier) @ignore)) + +; * function call +(call + target: [ + ; local + (identifier) @name.reference.call + ; remote + (dot + right: (identifier) @name.reference.call) + ]) @reference.call + +; * pipe into function call +(binary_operator + operator: "|>" + right: (identifier) @name.reference.call) @reference.call + +; * modules +(alias) @name.reference.module @reference.module diff --git a/aider/queries/tree-sitter-language-pack/elm-tags.scm b/aider/queries/tree-sitter-language-pack/elm-tags.scm new file mode 100644 index 000000000..c2e042763 --- /dev/null +++ b/aider/queries/tree-sitter-language-pack/elm-tags.scm @@ -0,0 +1,19 @@ +(value_declaration (function_declaration_left (lower_case_identifier) @name.definition.function)) @definition.function + +(function_call_expr (value_expr (value_qid) @name.reference.function)) @reference.function +(exposed_value (lower_case_identifier) @name.reference.function) @reference.function +(type_annotation ((lower_case_identifier) @name.reference.function) (colon)) @reference.function + +(type_declaration ((upper_case_identifier) @name.definition.type) ) @definition.type + +(type_ref (upper_case_qid (upper_case_identifier) @name.reference.type)) @reference.type +(exposed_type (upper_case_identifier) @name.reference.type) @reference.type + +(type_declaration (union_variant (upper_case_identifier) @name.definition.union)) @definition.union + +(value_expr (upper_case_qid (upper_case_identifier) @name.reference.union)) @reference.union + + +(module_declaration + (upper_case_qid (upper_case_identifier)) @name.definition.module +) @definition.module diff --git a/aider/queries/tree-sitter-language-pack/gleam-tags.scm b/aider/queries/tree-sitter-language-pack/gleam-tags.scm new file mode 100644 index 000000000..b1b934c20 --- /dev/null +++ b/aider/queries/tree-sitter-language-pack/gleam-tags.scm @@ -0,0 +1,41 @@ +; Modules +(module) @name.reference.module @reference.module +(import alias: (identifier) @name.reference.module) @reference.module +(remote_type_identifier + module: (identifier) @name.reference.module) @reference.module +((field_access + record: (identifier) @name.reference.module) + (#is-not? local)) @reference.module + +; Functions +(function + name: (identifier) @name.definition.function) @definition.function +(external_function + name: (identifier) @name.definition.function) @definition.function +(unqualified_import (identifier) @name.reference.function) @reference.function +((function_call + function: (identifier) @name.reference.function) @reference.function + (#is-not? local)) +((field_access + record: (identifier) @ignore + field: (label) @name.reference.function) + (#is-not? local)) @reference.function +((binary_expression + operator: "|>" + right: (identifier) @name.reference.function) + (#is-not? local)) @reference.function + +; Types +(type_definition + (type_name + name: (type_identifier) @name.definition.type)) @definition.type +(type_definition + (data_constructors + (data_constructor + name: (constructor_name) @name.definition.constructor))) @definition.constructor +(external_type + (type_name + name: (type_identifier) @name.definition.type)) @definition.type + +(type_identifier) @name.reference.type @reference.type +(constructor_name) @name.reference.constructor @reference.constructor diff --git a/aider/queries/tree-sitter-language-pack/go-tags.scm b/aider/queries/tree-sitter-language-pack/go-tags.scm new file mode 100644 index 000000000..16ecc4de8 --- /dev/null +++ b/aider/queries/tree-sitter-language-pack/go-tags.scm @@ -0,0 +1,42 @@ +( + (comment)* @doc + . + (function_declaration + name: (identifier) @name.definition.function) @definition.function + (#strip! @doc "^//\\s*") + (#set-adjacent! @doc @definition.function) +) + +( + (comment)* @doc + . + (method_declaration + name: (field_identifier) @name.definition.method) @definition.method + (#strip! @doc "^//\\s*") + (#set-adjacent! @doc @definition.method) +) + +(call_expression + function: [ + (identifier) @name.reference.call + (parenthesized_expression (identifier) @name.reference.call) + (selector_expression field: (field_identifier) @name.reference.call) + (parenthesized_expression (selector_expression field: (field_identifier) @name.reference.call)) + ]) @reference.call + +(type_spec + name: (type_identifier) @name.definition.type) @definition.type + +(type_identifier) @name.reference.type @reference.type + +(package_clause "package" (package_identifier) @name.definition.module) + +(type_declaration (type_spec name: (type_identifier) @name.definition.interface type: (interface_type))) + +(type_declaration (type_spec name: (type_identifier) @name.definition.class type: (struct_type))) + +(import_declaration (import_spec) @name.reference.module) + +(var_declaration (var_spec name: (identifier) @name.definition.variable)) + +(const_declaration (const_spec name: (identifier) @name.definition.constant)) diff --git a/aider/queries/tree-sitter-language-pack/java-tags.scm b/aider/queries/tree-sitter-language-pack/java-tags.scm new file mode 100644 index 000000000..ae4481e9e --- /dev/null +++ b/aider/queries/tree-sitter-language-pack/java-tags.scm @@ -0,0 +1,20 @@ +(class_declaration + name: (identifier) @name.definition.class) @definition.class + +(method_declaration + name: (identifier) @name.definition.method) @definition.method + +(method_invocation + name: (identifier) @name.reference.method + arguments: (argument_list) @reference.call) + +(interface_declaration + name: (identifier) @name.definition.interface) @definition.interface + +(type_list + (type_identifier) @name.reference.interface) @reference.implementation + +(object_creation_expression + type: (type_identifier) @name.reference.class) @reference.class + +(superclass (type_identifier) @name.reference.class) @reference.class diff --git a/aider/queries/tree-sitter-language-pack/lua-tags.scm b/aider/queries/tree-sitter-language-pack/lua-tags.scm new file mode 100644 index 000000000..0910cf153 --- /dev/null +++ b/aider/queries/tree-sitter-language-pack/lua-tags.scm @@ -0,0 +1,34 @@ +(function_declaration + name: [ + (identifier) @name.definition.function + (dot_index_expression + field: (identifier) @name.definition.function) + ]) @definition.function + +(function_declaration + name: (method_index_expression + method: (identifier) @name.definition.method)) @definition.method + +(assignment_statement + (variable_list . + name: [ + (identifier) @name.definition.function + (dot_index_expression + field: (identifier) @name.definition.function) + ]) + (expression_list . + value: (function_definition))) @definition.function + +(table_constructor + (field + name: (identifier) @name.definition.function + value: (function_definition))) @definition.function + +(function_call + name: [ + (identifier) @name.reference.call + (dot_index_expression + field: (identifier) @name.reference.call) + (method_index_expression + method: (identifier) @name.reference.method) + ]) @reference.call diff --git a/aider/queries/tree-sitter-language-pack/pony-tags.scm b/aider/queries/tree-sitter-language-pack/pony-tags.scm new file mode 100644 index 000000000..695f628ea --- /dev/null +++ b/aider/queries/tree-sitter-language-pack/pony-tags.scm @@ -0,0 +1,39 @@ +;Class definitions @definition.class +;Function definitions @definition.function +;Interface definitions @definition.interface +;Method definitions @definition.method +;Module definitions @definition.module +;Function/method calls @reference.call +;Class reference @reference.class +;Interface implementation @reference.implementation +( + (identifier) @reference.class + (#match? @reference.class "^_*[A-Z][a-zA-Z0-9_]*$") +) + +(class_definition (identifier) @name.definition.class) @definition.class +(actor_definition (identifier) @name.definition.class) @definition.class +(primitive_definition (identifier) @name.definition.class) @definition.class +(struct_definition (identifier) @name.definition.class) @definition.class +(type_alias (identifier) @name.definition.class) @definition.class + +(trait_definition (identifier) @name.definition.interface) @definition.interface +(interface_definition (identifier) @name.definition.interface) @definition.interface + +(constructor (identifier) @name.definition.method) @definition.method +(method (identifier) @name.definition.method) @definition.method +(behavior (identifier) @name.definition.method) @definition.method + +(class_definition (type) @name.reference.implementation) @reference.implementation +(actor_definition (type) @name.reference.implementation) @reference.implementation +(primitive_definition (type) @name.reference.implementation) @reference.implementation +(struct_definition (type) @name.reference.implementation) @reference.implementation +(type_alias (type) @name.reference.implementation) @reference.implementation + +; calls - not catching all possible call cases of callees for capturing the method name +(call_expression callee: [(identifier) (ffi_identifier)] @name.reference.call) @reference.call +(call_expression callee: (generic_expression [(identifier) (ffi_identifier)] @name.reference.call)) @reference.call +(call_expression callee: (member_expression (identifier) @name.reference.call .)) @reference.call +(call_expression callee: (member_expression (generic_expression [(identifier) (ffi_identifier)] @name.reference.call) .)) @reference.call +; TODO: add more possible callee expressions +(call_expression) @reference.call diff --git a/aider/queries/tree-sitter-language-pack/properties-tags.scm b/aider/queries/tree-sitter-language-pack/properties-tags.scm new file mode 100644 index 000000000..1d70c6a7f --- /dev/null +++ b/aider/queries/tree-sitter-language-pack/properties-tags.scm @@ -0,0 +1,5 @@ +(property + (key) @name.definition.property) @definition.property + +(substitution + (key) @name.reference.property) @reference.property diff --git a/aider/queries/tree-sitter-language-pack/python-tags.scm b/aider/queries/tree-sitter-language-pack/python-tags.scm new file mode 100644 index 000000000..dab8b941d --- /dev/null +++ b/aider/queries/tree-sitter-language-pack/python-tags.scm @@ -0,0 +1,14 @@ +(module (expression_statement (assignment left: (identifier) @name.definition.constant) @definition.constant)) + +(class_definition + name: (identifier) @name.definition.class) @definition.class + +(function_definition + name: (identifier) @name.definition.function) @definition.function + +(call + function: [ + (identifier) @name.reference.call + (attribute + attribute: (identifier) @name.reference.call) + ]) @reference.call diff --git a/aider/queries/tree-sitter-language-pack/r-tags.scm b/aider/queries/tree-sitter-language-pack/r-tags.scm new file mode 100644 index 000000000..5ffc72332 --- /dev/null +++ b/aider/queries/tree-sitter-language-pack/r-tags.scm @@ -0,0 +1,21 @@ +(binary_operator + lhs: (identifier) @name.definition.function + operator: "<-" + rhs: (function_definition) +) @definition.function + +(binary_operator + lhs: (identifier) @name.definition.function + operator: "=" + rhs: (function_definition) +) @definition.function + +(call + function: (identifier) @name.reference.call +) @reference.call + +(call + function: (namespace_operator + rhs: (identifier) @name.reference.call + ) +) @reference.call diff --git a/aider/queries/tree-sitter-language-pack/racket-tags.scm b/aider/queries/tree-sitter-language-pack/racket-tags.scm new file mode 100644 index 000000000..b3034026c --- /dev/null +++ b/aider/queries/tree-sitter-language-pack/racket-tags.scm @@ -0,0 +1,12 @@ +(list + . + (symbol) @reference._define + (#match? @reference._define "^(define|define/contract)$") + . + (list + . + (symbol) @name.definition.function) @definition.function) + +(list + . + (symbol) @name.reference.call) diff --git a/aider/queries/tree-sitter-language-pack/ruby-tags.scm b/aider/queries/tree-sitter-language-pack/ruby-tags.scm new file mode 100644 index 000000000..79e71d2d6 --- /dev/null +++ b/aider/queries/tree-sitter-language-pack/ruby-tags.scm @@ -0,0 +1,64 @@ +; Method definitions + +( + (comment)* @doc + . + [ + (method + name: (_) @name.definition.method) @definition.method + (singleton_method + name: (_) @name.definition.method) @definition.method + ] + (#strip! @doc "^#\\s*") + (#select-adjacent! @doc @definition.method) +) + +(alias + name: (_) @name.definition.method) @definition.method + +(setter + (identifier) @ignore) + +; Class definitions + +( + (comment)* @doc + . + [ + (class + name: [ + (constant) @name.definition.class + (scope_resolution + name: (_) @name.definition.class) + ]) @definition.class + (singleton_class + value: [ + (constant) @name.definition.class + (scope_resolution + name: (_) @name.definition.class) + ]) @definition.class + ] + (#strip! @doc "^#\\s*") + (#select-adjacent! @doc @definition.class) +) + +; Module definitions + +( + (module + name: [ + (constant) @name.definition.module + (scope_resolution + name: (_) @name.definition.module) + ]) @definition.module +) + +; Calls + +(call method: (identifier) @name.reference.call) @reference.call + +( + [(identifier) (constant)] @name.reference.call @reference.call + (#is-not? local) + (#not-match? @name.reference.call "^(lambda|load|require|require_relative|__FILE__|__LINE__)$") +) diff --git a/aider/queries/tree-sitter-language-pack/rust-tags.scm b/aider/queries/tree-sitter-language-pack/rust-tags.scm new file mode 100644 index 000000000..0888cc0d8 --- /dev/null +++ b/aider/queries/tree-sitter-language-pack/rust-tags.scm @@ -0,0 +1,60 @@ +; ADT definitions + +(struct_item + name: (type_identifier) @name.definition.class) @definition.class + +(enum_item + name: (type_identifier) @name.definition.class) @definition.class + +(union_item + name: (type_identifier) @name.definition.class) @definition.class + +; type aliases + +(type_item + name: (type_identifier) @name.definition.class) @definition.class + +; method definitions + +(declaration_list + (function_item + name: (identifier) @name.definition.method) @definition.method) + +; function definitions + +(function_item + name: (identifier) @name.definition.function) @definition.function + +; trait definitions +(trait_item + name: (type_identifier) @name.definition.interface) @definition.interface + +; module definitions +(mod_item + name: (identifier) @name.definition.module) @definition.module + +; macro definitions + +(macro_definition + name: (identifier) @name.definition.macro) @definition.macro + +; references + +(call_expression + function: (identifier) @name.reference.call) @reference.call + +(call_expression + function: (field_expression + field: (field_identifier) @name.reference.call)) @reference.call + +(macro_invocation + macro: (identifier) @name.reference.call) @reference.call + +; implementations + +(impl_item + trait: (type_identifier) @name.reference.implementation) @reference.implementation + +(impl_item + type: (type_identifier) @name.reference.implementation + !trait) @reference.implementation diff --git a/aider/queries/tree-sitter-language-pack/solidity-tags.scm b/aider/queries/tree-sitter-language-pack/solidity-tags.scm new file mode 100644 index 000000000..d56bc19a0 --- /dev/null +++ b/aider/queries/tree-sitter-language-pack/solidity-tags.scm @@ -0,0 +1,43 @@ +;; Method and Function declarations +(contract_declaration (_ + (function_definition + name: (identifier) @name.definition.function) @definition.method)) + +(source_file + (function_definition + name: (identifier) @name.definition.function) @definition.function) + +;; Contract, struct, enum and interface declarations +(contract_declaration + name: (identifier) @name.definition.class) @definition.class + +(interface_declaration + name: (identifier) @name.definition.interface) @definition.interface + +(library_declaration + name: (identifier) @name.definition.class) @definition.interface + +(struct_declaration name: (identifier) @name.definition.class) @definition.class +(enum_declaration name: (identifier) @name.definition.class) @definition.class +(event_definition name: (identifier) @name.definition.class) @definition.class + +;; Function calls +(call_expression (expression (identifier)) @name.reference.call ) @reference.call + +(call_expression + (expression (member_expression + property: (_) @name.reference.method ))) @reference.call + +;; Log emit +(emit_statement name: (_) @name.reference.class) @reference.class + + +;; Inheritance + +(inheritance_specifier + ancestor: (user_defined_type (_) @name.reference.class . )) @reference.class + + +;; Imports ( note that unknown is not standardised ) +(import_directive + import_name: (_) @name.reference.module ) @reference.unknown diff --git a/aider/queries/tree-sitter-language-pack/swift-tags.scm b/aider/queries/tree-sitter-language-pack/swift-tags.scm new file mode 100644 index 000000000..9b81cf7bd --- /dev/null +++ b/aider/queries/tree-sitter-language-pack/swift-tags.scm @@ -0,0 +1,51 @@ +(class_declaration + name: (type_identifier) @name.definition.class) @definition.class + +(protocol_declaration + name: (type_identifier) @name.definition.interface) @definition.interface + +(class_declaration + (class_body + [ + (function_declaration + name: (simple_identifier) @name.definition.method + ) + (subscript_declaration + (parameter (simple_identifier) @name.definition.method) + ) + (init_declaration "init" @name.definition.method) + (deinit_declaration "deinit" @name.definition.method) + ] + ) +) @definition.method + +(protocol_declaration + (protocol_body + [ + (protocol_function_declaration + name: (simple_identifier) @name.definition.method + ) + (subscript_declaration + (parameter (simple_identifier) @name.definition.method) + ) + (init_declaration "init" @name.definition.method) + ] + ) +) @definition.method + +(class_declaration + (class_body + [ + (property_declaration + (pattern (simple_identifier) @name.definition.property) + ) + ] + ) +) @definition.property + +(property_declaration + (pattern (simple_identifier) @name.definition.property) +) @definition.property + +(function_declaration + name: (simple_identifier) @name.definition.function) @definition.function diff --git a/aider/queries/tree-sitter-language-pack/udev-tags.scm b/aider/queries/tree-sitter-language-pack/udev-tags.scm new file mode 100644 index 000000000..a3a60b569 --- /dev/null +++ b/aider/queries/tree-sitter-language-pack/udev-tags.scm @@ -0,0 +1,20 @@ +(assignment + key: "LABEL" + (value + (content) @name.definition.label)) @definition.label + +(assignment + key: "GOTO" + (value + (content) @name.reference.label)) @reference.label + +(assignment + key: "ENV" + (env_var) @name.definition.variable) @definition.variable + +(match + key: "ENV" + (env_var) @name.reference.variable) @reference.variable + +(var_sub + (env_var) @name.reference.variable) @reference.variable diff --git a/aider/queries/tree-sitter-languages/scala-tags.scm b/aider/queries/tree-sitter-languages/scala-tags.scm new file mode 100644 index 000000000..4bf3953ff --- /dev/null +++ b/aider/queries/tree-sitter-languages/scala-tags.scm @@ -0,0 +1,65 @@ +; Definitions + +(package_clause + name: (package_identifier) @name.definition.module) @definition.module + +(trait_definition + name: (identifier) @name.definition.interface) @definition.interface + +(enum_definition + name: (identifier) @name.definition.enum) @definition.enum + +(simple_enum_case + name: (identifier) @name.definition.class) @definition.class + +(full_enum_case + name: (identifier) @name.definition.class) @definition.class + +(class_definition + name: (identifier) @name.definition.class) @definition.class + +(object_definition + name: (identifier) @name.definition.object) @definition.object + +(function_definition + name: (identifier) @name.definition.function) @definition.function + +(val_definition + pattern: (identifier) @name.definition.variable) @definition.variable + +(given_definition + name: (identifier) @name.definition.variable) @definition.variable + +(var_definition + pattern: (identifier) @name.definition.variable) @definition.variable + +(val_declaration + name: (identifier) @name.definition.variable) @definition.variable + +(var_declaration + name: (identifier) @name.definition.variable) @definition.variable + +(type_definition + name: (type_identifier) @name.definition.type) @definition.type + +(class_parameter + name: (identifier) @name.definition.property) @definition.property + +; References + +(call_expression + (identifier) @name.reference.call) @reference.call + +(instance_expression + (type_identifier) @name.reference.interface) @reference.interface + +(instance_expression + (generic_type + (type_identifier) @name.reference.interface)) @reference.interface + +(extends_clause + (type_identifier) @name.reference.class) @reference.class + +(extends_clause + (generic_type + (type_identifier) @name.reference.class)) @reference.class diff --git a/aider/reasoning_tags.py b/aider/reasoning_tags.py index 137e617ed..e87922383 100644 --- a/aider/reasoning_tags.py +++ b/aider/reasoning_tags.py @@ -7,8 +7,8 @@ from aider.dump import dump # noqa # Standard tag identifier REASONING_TAG = "thinking-content-" + "7bbeb8e1441453ad999a0bbba8a46d4b" # Output formatting -REASONING_START = "> Thinking ..." -REASONING_END = "> ... done thinking.\n\n------" +REASONING_START = "--------------\n► **THINKING**" +REASONING_END = "------------\n► **ANSWER**" def remove_reasoning_content(res, reasoning_tag): diff --git a/aider/repo.py b/aider/repo.py index b0956973f..94143b5f3 100644 --- a/aider/repo.py +++ b/aider/repo.py @@ -56,6 +56,7 @@ class GitRepo: attribute_commit_message_committer=False, commit_prompt=None, subtree_only=False, + git_commit_verify=True, ): self.io = io self.models = models @@ -69,6 +70,7 @@ class GitRepo: self.attribute_commit_message_committer = attribute_commit_message_committer self.commit_prompt = commit_prompt self.subtree_only = subtree_only + self.git_commit_verify = git_commit_verify self.ignore_file_cache = {} if git_dname: @@ -133,7 +135,9 @@ class GitRepo: # if context: # full_commit_message += "\n\n# Aider chat conversation:\n\n" + context - cmd = ["-m", full_commit_message, "--no-verify"] + cmd = ["-m", full_commit_message] + if not self.git_commit_verify: + cmd.append("--no-verify") if fnames: fnames = [str(self.abs_root_path(fn)) for fn in fnames] for fname in fnames: diff --git a/aider/repomap.py b/aider/repomap.py index de5a162b6..598770d18 100644 --- a/aider/repomap.py +++ b/aider/repomap.py @@ -398,13 +398,30 @@ class RepoMap: # dump(fname) rel_fname = self.get_rel_fname(fname) + current_pers = 0.0 # Start with 0 personalization score if fname in chat_fnames: - personalization[rel_fname] = personalize + current_pers += personalize chat_rel_fnames.add(rel_fname) if rel_fname in mentioned_fnames: - personalization[rel_fname] = personalize + # Use max to avoid double counting if in chat_fnames and mentioned_fnames + current_pers = max(current_pers, personalize) + + # Check path components against mentioned_idents + path_obj = Path(rel_fname) + path_components = set(path_obj.parts) + basename_with_ext = path_obj.name + basename_without_ext, _ = os.path.splitext(basename_with_ext) + components_to_check = path_components.union({basename_with_ext, basename_without_ext}) + + matched_idents = components_to_check.intersection(mentioned_idents) + if matched_idents: + # Add personalization *once* if any path component matches a mentioned ident + current_pers += personalize + + if current_pers > 0: + personalization[rel_fname] = current_pers # Assign the final calculated value tags = list(self.get_tags(fname, rel_fname)) if tags is None: @@ -445,12 +462,19 @@ class RepoMap: progress() definers = defines[ident] + + mul = 1.0 + + is_snake = ("_" in ident) and any(c.isalpha() for c in ident) + is_camel = any(c.isupper() for c in ident) and any(c.islower() for c in ident) if ident in mentioned_idents: - mul = 10 - elif ident.startswith("_"): - mul = 0.1 - else: - mul = 1 + mul *= 10 + if (is_snake or is_camel) and len(ident) >= 8: + mul *= 10 + if ident.startswith("_"): + mul *= 0.1 + if len(defines[ident]) > 5: + mul *= 0.1 for referencer, num_refs in Counter(references[ident]).items(): for definer in definers: @@ -458,10 +482,14 @@ class RepoMap: # if referencer == definer: # continue + use_mul = mul + if referencer in chat_rel_fnames: + use_mul *= 50 + # scale down so high freq (low value) mentions don't dominate num_refs = math.sqrt(num_refs) - G.add_edge(referencer, definer, weight=mul * num_refs, ident=ident) + G.add_edge(referencer, definer, weight=use_mul * num_refs, ident=ident) if not references: pass diff --git a/aider/resources/model-metadata.json b/aider/resources/model-metadata.json index 5db04769a..64d851599 100644 --- a/aider/resources/model-metadata.json +++ b/aider/resources/model-metadata.json @@ -63,6 +63,22 @@ //"supports_tool_choice": true, "supports_prompt_caching": true }, + "openrouter/deepseek/deepseek-chat-v3-0324": { + "max_tokens": 8192, + "max_input_tokens": 64000, + "max_output_tokens": 8192, + "input_cost_per_token": 0.00000055, + "input_cost_per_token_cache_hit": 0.00000014, + "cache_read_input_token_cost": 0.00000014, + "cache_creation_input_token_cost": 0.0, + "output_cost_per_token": 0.00000219, + "litellm_provider": "openrouter", + "mode": "chat", + //"supports_function_calling": true, + "supports_assistant_prefill": true, + //"supports_tool_choice": true, + "supports_prompt_caching": true + }, "fireworks_ai/accounts/fireworks/models/deepseek-r1": { "max_tokens": 160000, "max_input_tokens": 128000, @@ -241,4 +257,113 @@ "supports_system_messages": true, "supports_tool_choice": true }, + "gemini/gemini-2.5-pro-exp-03-25": { + "max_tokens": 8192, + "max_input_tokens": 1048576, + "max_output_tokens": 64000, + "max_images_per_prompt": 3000, + "max_videos_per_prompt": 10, + "max_video_length": 1, + "max_audio_length_hours": 8.4, + "max_audio_per_prompt": 1, + "max_pdf_size_mb": 30, + "input_cost_per_image": 0, + "input_cost_per_video_per_second": 0, + "input_cost_per_audio_per_second": 0, + "input_cost_per_token": 0, + "input_cost_per_character": 0, + "input_cost_per_token_above_128k_tokens": 0, + "input_cost_per_character_above_128k_tokens": 0, + "input_cost_per_image_above_128k_tokens": 0, + "input_cost_per_video_per_second_above_128k_tokens": 0, + "input_cost_per_audio_per_second_above_128k_tokens": 0, + "output_cost_per_token": 0, + "output_cost_per_character": 0, + "output_cost_per_token_above_128k_tokens": 0, + "output_cost_per_character_above_128k_tokens": 0, + //"litellm_provider": "vertex_ai-language-models", + "litellm_provider": "gemini", + "mode": "chat", + "supports_system_messages": true, + "supports_function_calling": true, + "supports_vision": true, + "supports_audio_input": true, + "supports_video_input": true, + "supports_pdf_input": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "source": "https://cloud.google.com/vertex-ai/generative-ai/pricing" + }, + "vertex_ai/gemini-2.5-pro-exp-03-25": { + "max_tokens": 8192, + "max_input_tokens": 1048576, + "max_output_tokens": 64000, + "max_images_per_prompt": 3000, + "max_videos_per_prompt": 10, + "max_video_length": 1, + "max_audio_length_hours": 8.4, + "max_audio_per_prompt": 1, + "max_pdf_size_mb": 30, + "input_cost_per_image": 0, + "input_cost_per_video_per_second": 0, + "input_cost_per_audio_per_second": 0, + "input_cost_per_token": 0, + "input_cost_per_character": 0, + "input_cost_per_token_above_128k_tokens": 0, + "input_cost_per_character_above_128k_tokens": 0, + "input_cost_per_image_above_128k_tokens": 0, + "input_cost_per_video_per_second_above_128k_tokens": 0, + "input_cost_per_audio_per_second_above_128k_tokens": 0, + "output_cost_per_token": 0, + "output_cost_per_character": 0, + "output_cost_per_token_above_128k_tokens": 0, + "output_cost_per_character_above_128k_tokens": 0, + "litellm_provider": "vertex_ai-language-models", + "mode": "chat", + "supports_system_messages": true, + "supports_function_calling": true, + "supports_vision": true, + "supports_audio_input": true, + "supports_video_input": true, + "supports_pdf_input": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "source": "https://cloud.google.com/vertex-ai/generative-ai/pricing" + }, + "openrouter/google/gemini-2.5-pro-exp-03-25:free": { + "max_tokens": 8192, + "max_input_tokens": 1048576, + "max_output_tokens": 64000, + "max_images_per_prompt": 3000, + "max_videos_per_prompt": 10, + "max_video_length": 1, + "max_audio_length_hours": 8.4, + "max_audio_per_prompt": 1, + "max_pdf_size_mb": 30, + "input_cost_per_image": 0, + "input_cost_per_video_per_second": 0, + "input_cost_per_audio_per_second": 0, + "input_cost_per_token": 0, + "input_cost_per_character": 0, + "input_cost_per_token_above_128k_tokens": 0, + "input_cost_per_character_above_128k_tokens": 0, + "input_cost_per_image_above_128k_tokens": 0, + "input_cost_per_video_per_second_above_128k_tokens": 0, + "input_cost_per_audio_per_second_above_128k_tokens": 0, + "output_cost_per_token": 0, + "output_cost_per_character": 0, + "output_cost_per_token_above_128k_tokens": 0, + "output_cost_per_character_above_128k_tokens": 0, + "litellm_provider": "openrouter", + "mode": "chat", + "supports_system_messages": true, + "supports_function_calling": true, + "supports_vision": true, + "supports_audio_input": true, + "supports_video_input": true, + "supports_pdf_input": true, + "supports_response_schema": true, + "supports_tool_choice": true, + "source": "https://cloud.google.com/vertex-ai/generative-ai/pricing" + }, } diff --git a/aider/resources/model-settings.yml b/aider/resources/model-settings.yml index c3ca37187..136bac76c 100644 --- a/aider/resources/model-settings.yml +++ b/aider/resources/model-settings.yml @@ -185,6 +185,7 @@ editor_edit_format: editor-diff - name: anthropic/claude-3-7-sonnet-20250219 + overeager: true edit_format: diff weak_model_name: anthropic/claude-3-5-haiku-20241022 use_repo_map: true @@ -196,8 +197,10 @@ cache_control: true editor_model_name: anthropic/claude-3-7-sonnet-20250219 editor_edit_format: editor-diff + accepts_settings: ["thinking_tokens"] - name: anthropic/claude-3-7-sonnet-latest + overeager: true edit_format: diff weak_model_name: anthropic/claude-3-5-haiku-20241022 use_repo_map: true @@ -209,6 +212,7 @@ cache_control: true editor_model_name: anthropic/claude-3-7-sonnet-latest editor_edit_format: editor-diff + accepts_settings: ["thinking_tokens"] - name: claude-3-7-sonnet-20250219 edit_format: diff @@ -222,8 +226,10 @@ cache_control: true editor_model_name: claude-3-7-sonnet-20250219 editor_edit_format: editor-diff + accepts_settings: ["thinking_tokens"] - name: claude-3-7-sonnet-latest + overeager: true edit_format: diff weak_model_name: claude-3-5-haiku-20241022 use_repo_map: true @@ -235,8 +241,10 @@ cache_control: true editor_model_name: claude-3-7-sonnet-latest editor_edit_format: editor-diff + accepts_settings: ["thinking_tokens"] - name: bedrock/anthropic.claude-3-7-sonnet-20250219-v1:0 + overeager: true edit_format: diff weak_model_name: bedrock/anthropic.claude-3-5-haiku-20241022-v1:0 use_repo_map: true @@ -248,8 +256,10 @@ cache_control: true editor_model_name: bedrock/anthropic.claude-3-7-sonnet-20250219-v1:0 editor_edit_format: editor-diff + accepts_settings: ["thinking_tokens"] - name: bedrock/us.anthropic.claude-3-7-sonnet-20250219-v1:0 + overeager: true edit_format: diff weak_model_name: bedrock/us.anthropic.claude-3-5-haiku-20241022-v1:0 use_repo_map: true @@ -261,8 +271,10 @@ cache_control: true editor_model_name: bedrock/us.anthropic.claude-3-7-sonnet-20250219-v1:0 editor_edit_format: editor-diff + accepts_settings: ["thinking_tokens"] - name: bedrock_converse/anthropic.claude-3-7-sonnet-20250219-v1:0 + overeager: true edit_format: diff weak_model_name: bedrock_converse/anthropic.claude-3-5-haiku-20241022-v1:0 use_repo_map: true @@ -274,8 +286,10 @@ cache_control: true editor_model_name: bedrock_converse/anthropic.claude-3-7-sonnet-20250219-v1:0 editor_edit_format: editor-diff + accepts_settings: ["thinking_tokens"] - name: bedrock_converse/us.anthropic.claude-3-7-sonnet-20250219-v1:0 + overeager: true edit_format: diff weak_model_name: bedrock_converse/us.anthropic.claude-3-5-haiku-20241022-v1:0 use_repo_map: true @@ -287,8 +301,10 @@ cache_control: true editor_model_name: bedrock_converse/us.anthropic.claude-3-7-sonnet-20250219-v1:0 editor_edit_format: editor-diff + accepts_settings: ["thinking_tokens"] - name: vertex_ai/claude-3-7-sonnet@20250219 + overeager: true edit_format: diff weak_model_name: vertex_ai/claude-3-5-haiku@20241022 use_repo_map: true @@ -297,8 +313,10 @@ max_tokens: 64000 editor_model_name: vertex_ai/claude-3-7-sonnet@20250219 editor_edit_format: editor-diff + accepts_settings: ["thinking_tokens"] - name: vertex_ai-anthropic_models/vertex_ai/claude-3-7-sonnet@20250219 + overeager: true edit_format: diff weak_model_name: vertex_ai/claude-3-5-haiku@20241022 use_repo_map: true @@ -307,8 +325,10 @@ max_tokens: 64000 editor_model_name: vertex_ai-anthropic_models/vertex_ai/claude-3-7-sonnet@20250219 editor_edit_format: editor-diff + accepts_settings: ["thinking_tokens"] - name: openrouter/anthropic/claude-3.7-sonnet + overeager: true edit_format: diff weak_model_name: openrouter/anthropic/claude-3-5-haiku use_repo_map: true @@ -320,8 +340,10 @@ cache_control: true editor_model_name: openrouter/anthropic/claude-3.7-sonnet editor_edit_format: editor-diff + accepts_settings: ["thinking_tokens"] - name: openrouter/anthropic/claude-3.7-sonnet:beta + overeager: true edit_format: diff weak_model_name: openrouter/anthropic/claude-3-5-haiku use_repo_map: true @@ -333,6 +355,7 @@ cache_control: true editor_model_name: openrouter/anthropic/claude-3.7-sonnet editor_edit_format: editor-diff + accepts_settings: ["thinking_tokens"] - name: bedrock/anthropic.claude-3-5-sonnet-20241022-v2:0 edit_format: diff @@ -547,8 +570,8 @@ examples_as_sys_msg: true extra_params: max_tokens: 8192 + include_reasoning: true caches_by_default: true - use_temperature: false editor_model_name: openrouter/deepseek/deepseek-chat editor_edit_format: editor-diff @@ -635,6 +658,15 @@ reminder: sys examples_as_sys_msg: true +- name: openrouter/deepseek/deepseek-chat-v3-0324 + edit_format: diff + use_repo_map: true + reminder: sys + examples_as_sys_msg: true + extra_params: + max_tokens: 8192 + caches_by_default: true + - name: openrouter/openai/gpt-4o edit_format: diff weak_model_name: openrouter/openai/gpt-4o-mini @@ -694,6 +726,7 @@ streaming: false editor_model_name: azure/gpt-4o editor_edit_format: editor-diff + accepts_settings: ["reasoning_effort"] - name: o1-preview edit_format: architect @@ -732,6 +765,7 @@ editor_model_name: openrouter/openai/gpt-4o editor_edit_format: editor-diff system_prompt_prefix: "Formatting re-enabled. " + accepts_settings: ["reasoning_effort"] - name: openai/o1 edit_format: diff @@ -742,6 +776,7 @@ editor_model_name: openai/gpt-4o editor_edit_format: editor-diff system_prompt_prefix: "Formatting re-enabled. " + accepts_settings: ["reasoning_effort"] - name: o1 edit_format: diff @@ -752,6 +787,7 @@ editor_model_name: gpt-4o editor_edit_format: editor-diff system_prompt_prefix: "Formatting re-enabled. " + accepts_settings: ["reasoning_effort"] - name: openrouter/qwen/qwen-2.5-coder-32b-instruct edit_format: diff @@ -780,7 +816,7 @@ streaming: true editor_model_name: fireworks_ai/accounts/fireworks/models/deepseek-v3 editor_edit_format: editor-diff - remove_reasoning: think + reasoning_tag: think extra_params: max_tokens: 160000 @@ -800,6 +836,7 @@ editor_model_name: gpt-4o editor_edit_format: editor-diff system_prompt_prefix: "Formatting re-enabled. " + accepts_settings: ["reasoning_effort"] - name: o3-mini edit_format: diff @@ -809,6 +846,7 @@ editor_model_name: gpt-4o editor_edit_format: editor-diff system_prompt_prefix: "Formatting re-enabled. " + accepts_settings: ["reasoning_effort"] - name: openrouter/openai/o3-mini edit_format: diff @@ -818,6 +856,7 @@ editor_model_name: openrouter/openai/gpt-4o editor_edit_format: editor-diff system_prompt_prefix: "Formatting re-enabled. " + accepts_settings: ["reasoning_effort"] - name: openrouter/openai/o3-mini-high edit_format: diff @@ -827,6 +866,7 @@ editor_model_name: openrouter/openai/gpt-4o editor_edit_format: editor-diff system_prompt_prefix: "Formatting re-enabled. " + accepts_settings: ["reasoning_effort"] - name: azure/o3-mini edit_format: diff @@ -836,6 +876,7 @@ editor_model_name: azure/gpt-4o editor_edit_format: editor-diff system_prompt_prefix: "Formatting re-enabled. " + accepts_settings: ["reasoning_effort"] - name: gpt-4.5-preview edit_format: diff @@ -858,7 +899,7 @@ editor_edit_format: editor-diff - name: fireworks_ai/accounts/fireworks/models/qwq-32b - remove_reasoning: think + reasoning_tag: think edit_format: diff weak_model_name: fireworks_ai/accounts/fireworks/models/qwen2p5-coder-32b-instruct use_repo_map: true @@ -872,7 +913,7 @@ top_p: 0.95 - name: groq/qwen-qwq-32b - remove_reasoning: think + reasoning_tag: think edit_format: diff weak_model_name: groq/qwen-2.5-coder-32b use_repo_map: true @@ -1003,3 +1044,30 @@ extra_headers: editor-version: Neovim/0.9.0 Copilot-Integration-Id: vscode-chat + +- name: cohere_chat/command-a-03-2025 + examples_as_sys_msg: true + +- name: openrouter/cohere/command-a-03-2025 + examples_as_sys_msg: true + +- name: gemini/gemma-3-27b-it + use_system_prompt: false + +- name: openrouter/google/gemma-3-27b-it:free + use_system_prompt: false + +- name: openrouter/google/gemma-3-27b-it + use_system_prompt: false + +- name: gemini/gemini-2.5-pro-exp-03-25 + edit_format: diff-fenced + use_repo_map: true + +- name: openrouter/google/gemini-2.5-pro-exp-03-25:free + edit_format: diff-fenced + use_repo_map: true + +- name: vertex_ai/gemini-2.5-pro-exp-03-25 + edit_format: diff-fenced + use_repo_map: true diff --git a/aider/scrape.py b/aider/scrape.py index 7977a8548..8ab5a93ed 100755 --- a/aider/scrape.py +++ b/aider/scrape.py @@ -159,7 +159,8 @@ class Scraper: try: response = page.goto(url, wait_until="networkidle", timeout=5000) except PlaywrightTimeoutError: - self.print_error(f"Timeout while loading {url}") + print(f"Page didn't quiesce, scraping content anyway: {url}") + response = None except PlaywrightError as e: self.print_error(f"Error navigating to {url}: {str(e)}") return None, None diff --git a/aider/watch.py b/aider/watch.py index 989aa8bf6..e7b115730 100644 --- a/aider/watch.py +++ b/aider/watch.py @@ -64,7 +64,7 @@ class FileWatcher: """Watches source files for changes and AI comments""" # Compiled regex pattern for AI comments - ai_comment_pattern = re.compile(r"(?:#|//|--) *(ai\b.*|ai\b.*|.*\bai[?!]?) *$", re.IGNORECASE) + ai_comment_pattern = re.compile(r"(?:#|//|--|;+) *(ai\b.*|ai\b.*|.*\bai[?!]?) *$", re.IGNORECASE) def __init__(self, coder, gitignores=None, verbose=False, analytics=None, root=None): self.coder = coder @@ -140,7 +140,10 @@ class FileWatcher: roots_to_watch = self.get_roots_to_watch() for changes in watch( - *roots_to_watch, watch_filter=self.filter_func, stop_event=self.stop_event + *roots_to_watch, + watch_filter=self.filter_func, + stop_event=self.stop_event, + ignore_permission_denied=True, ): if self.handle_changes(changes): return @@ -259,7 +262,7 @@ class FileWatcher: line_nums.append(i) comments.append(comment) comment = comment.lower() - comment = comment.lstrip("/#-") + comment = comment.lstrip("/#-;") # Added semicolon for Lisp comments comment = comment.strip() if comment.startswith("ai!") or comment.endswith("ai!"): has_action = "!" diff --git a/aider/website/HISTORY.md b/aider/website/HISTORY.md index ce180c84b..951e1eac7 100644 --- a/aider/website/HISTORY.md +++ b/aider/website/HISTORY.md @@ -7,12 +7,13 @@ description: Release notes and stats on aider writing its own code. # Release history -{% include blame.md %} - -The above -[stats are based on the git commit history](/docs/faq.html#how-are-the-aider-wrote-xx-of-code-stats-computed) +Aider writes most of its own code, usually about 70-80% of the new code in each release. +These +[statistics are based on the git commit history](/docs/faq.html#how-are-the-aider-wrote-xx-of-code-stats-computed) of the aider repo. +{% include blame.md %} + ## Release notes + + + + diff --git a/aider/website/_includes/recording.css b/aider/website/_includes/recording.css new file mode 100644 index 000000000..292407d2a --- /dev/null +++ b/aider/website/_includes/recording.css @@ -0,0 +1,228 @@ +/* Terminal header styling */ +.terminal-header { + background-color: #e0e0e0; + border-top-left-radius: 6px; + border-top-right-radius: 6px; + padding: 4px 10px; + display: flex; + align-items: center; + border-bottom: 1px solid #c0c0c0; +} + +.terminal-buttons { + display: flex; + gap: 4px; + margin-right: 10px; +} + +.terminal-button { + width: 10px; + height: 10px; + border-radius: 50%; +} + +.terminal-close { + background-color: #ff5f56; + border: 1px solid #e0443e; +} + +.terminal-minimize { + background-color: #ffbd2e; + border: 1px solid #dea123; +} + +.terminal-expand { + background-color: #27c93f; + border: 1px solid #1aab29; +} + +.terminal-title { + flex-grow: 1; + text-align: center; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; + font-size: 11px; + color: #666; +} + +/* Toast notification styling */ +.toast-container { + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + z-index: 9999; + pointer-events: none; +} + +.toast-notification { + background-color: rgba(0, 0, 0, 0.7); + color: white; + padding: 12px 25px; + border-radius: 8px; + margin-bottom: 10px; + box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2); + opacity: 0; + transition: opacity 0.3s ease-in-out; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; + font-size: 18px; + text-align: center; + display: inline-block; + min-width: 200px; + max-width: 90%; +} + +/* Page container styling */ +.page-container { + max-width: 950px; + margin-left: auto; + margin-right: auto; + position: relative; +} + +/* macOS backdrop styling */ +.macos-backdrop { + background: linear-gradient(135deg, #ff9966, #ff5e62, #6666ff, #0066ff); + border-radius: 12px; + padding: clamp(5px, 5vw, 50px) clamp(5px, 2.5vw, 50px); + margin: 20px 0; + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2); + position: relative; + overflow: hidden; +} + +/* Add subtle wave animation to backdrop */ +.macos-backdrop::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: radial-gradient(circle at center, rgba(255,255,255,0.1) 0%, rgba(255,255,255,0) 70%); + opacity: 0.7; + pointer-events: none; +} + +/* Add decorative curved lines to the backdrop */ +.macos-backdrop::after { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-image: + radial-gradient(circle at 20% 30%, transparent 0%, transparent 60%, rgba(255,255,255,0.2) 61%, transparent 62%), + radial-gradient(circle at 80% 70%, transparent 0%, transparent 40%, rgba(255,255,255,0.2) 41%, transparent 42%), + radial-gradient(circle at 40% 90%, transparent 0%, transparent 70%, rgba(255,255,255,0.2) 71%, transparent 72%), + radial-gradient(circle at 60% 10%, transparent 0%, transparent 50%, rgba(255,255,255,0.2) 51%, transparent 52%); + background-size: 100% 100%; + opacity: 1; + pointer-events: none; + z-index: 0; +} + +.terminal-container { + border-radius: 8px; + overflow: hidden; + box-shadow: 0 5px 15px rgba(0, 0, 0, 0.2); + margin-top: 0; + margin-bottom: 0; + position: relative; + background-color: white; /* Add background color to terminal container */ + z-index: 2; /* Ensure terminal appears above the backdrop effects */ +} + +/* Timestamp link styling */ +.timestamp-link { + color: #0366d6; + text-decoration: none; + font-weight: bold; + cursor: pointer; +} + +.timestamp-link:hover { + text-decoration: underline; +} + +/* Active timestamp styling */ +.timestamp-active { + background-color: #f0f8ff; /* Light blue background */ + border-radius: 3px; + padding: 2px 4px; + margin: -2px -4px; +} + +/* Highlight the list item containing the active timestamp */ +li.active-marker { + background-color: #f6f8fa; + border-radius: 4px; + padding: 4px 8px; + margin-left: -8px; +} + +/* Make list items clickable */ +.transcript-item { + cursor: pointer; + transition: background-color 0.2s ease; + padding: 4px 8px; + margin-left: -8px; + border-radius: 4px; +} + +.transcript-item:hover { + background-color: #f0f0f0; +} + +/* Keyboard shortcuts styling */ +.keyboard-shortcuts { + text-align: center; + font-size: 14px; + color: #666; + margin-top: 10px; + margin-bottom: 20px; +} + +/* Hide keyboard shortcuts on devices likely without physical keyboards */ +.no-physical-keyboard .keyboard-shortcuts { + display: none; +} + +.keyboard-shortcuts kbd { + background-color: #f7f7f7; + border: 1px solid #ccc; + border-radius: 3px; + box-shadow: 0 1px 0 rgba(0,0,0,0.2); + color: #333; + display: inline-block; + font-family: monospace; + line-height: 1; + margin: 0 2px; + padding: 3px 5px; + white-space: nowrap; +} +.asciinema-player-theme-aider { + /* Foreground (default text) color */ + --term-color-foreground: #444444; /* colour238 */ + + /* Background color */ + --term-color-background: #dadada; /* colour253 */ + + /* Palette of 16 standard ANSI colors */ + --term-color-0: #21222c; + --term-color-1: #ff5555; + --term-color-2: #50fa7b; + --term-color-3: #f1fa8c; + --term-color-4: #bd93f9; + --term-color-5: #ff79c6; + --term-color-6: #8be9fd; + --term-color-7: #f8f8f2; + --term-color-8: #6272a4; + --term-color-9: #ff6e6e; + --term-color-10: #69ff94; + --term-color-11: #ffffa5; + --term-color-12: #d6acff; + --term-color-13: #ff92df; + --term-color-14: #a4ffff; + --term-color-15: #ffffff; +} diff --git a/aider/website/_includes/recording.js b/aider/website/_includes/recording.js new file mode 100644 index 000000000..a2f8cf627 --- /dev/null +++ b/aider/website/_includes/recording.js @@ -0,0 +1,428 @@ +document.addEventListener('DOMContentLoaded', function() { + let player; // Store player reference to make it accessible to click handlers + let globalAudio; // Global audio element to be reused + + // Detect if device likely has no physical keyboard + function detectNoKeyboard() { + // Check if it's a touch device (most mobile devices) + const isTouchDevice = ('ontouchstart' in window) || + (navigator.maxTouchPoints > 0) || + (navigator.msMaxTouchPoints > 0); + + // Check common mobile user agents as additional signal + const isMobileUA = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent); + + // If it's a touch device and has a mobile user agent, likely has no physical keyboard + if (isTouchDevice && isMobileUA) { + document.body.classList.add('no-physical-keyboard'); + } + } + + // Run detection + detectNoKeyboard(); + + // Parse the transcript section to create markers and convert timestamps to links + function parseTranscript() { + const markers = []; + // Find the Commentary heading + const transcriptHeading = Array.from(document.querySelectorAll('h2')).find(el => el.textContent.trim() === 'Commentary'); + + if (transcriptHeading) { + // Get all list items after the transcript heading + let currentElement = transcriptHeading.nextElementSibling; + + while (currentElement && currentElement.tagName === 'UL') { + const listItems = currentElement.querySelectorAll('li'); + + listItems.forEach(item => { + const text = item.textContent.trim(); + const match = text.match(/(\d+):(\d+)\s+(.*)/); + + if (match) { + const minutes = parseInt(match[1], 10); + const seconds = parseInt(match[2], 10); + const timeInSeconds = minutes * 60 + seconds; + const formattedTime = `${minutes}:${seconds.toString().padStart(2, '0')}`; + const message = match[3].trim(); + + // Create link for the timestamp + const timeLink = document.createElement('a'); + timeLink.href = '#'; + timeLink.textContent = formattedTime; + timeLink.className = 'timestamp-link'; + timeLink.dataset.time = timeInSeconds; + timeLink.dataset.message = message; + + // Add click event to seek the player + timeLink.addEventListener('click', function(e) { + e.preventDefault(); + if (player && typeof player.seek === 'function') { + player.seek(timeInSeconds); + player.play(); + + // Also trigger toast and speech + showToast(message); + speakText(message, timeInSeconds); + + // Highlight this timestamp + highlightTimestamp(timeInSeconds); + } + }); + + // Replace text with the link + message + item.textContent = ''; + item.appendChild(timeLink); + item.appendChild(document.createTextNode(' ' + message)); + + // Add class and click handler to the entire list item + item.classList.add('transcript-item'); + item.dataset.time = timeInSeconds; + item.dataset.message = message; + + item.addEventListener('click', function(e) { + // Prevent click event if the user clicked directly on the timestamp link + // This prevents double-firing of the event + if (e.target !== timeLink) { + e.preventDefault(); + if (player && typeof player.seek === 'function') { + player.seek(timeInSeconds); + player.play(); + + // Also trigger toast and speech + showToast(message); + speakText(message, timeInSeconds); + + // Highlight this timestamp + highlightTimestamp(timeInSeconds); + } + } + }); + + markers.push([timeInSeconds, message]); + } + }); + + currentElement = currentElement.nextElementSibling; + } + } + + return markers; + } + + // Parse transcript and create markers + const markers = parseTranscript(); + + // Create player with a single call + player = AsciinemaPlayer.create( + recording_url, + document.getElementById('demo'), + { + speed: 1.25, + idleTimeLimit: 1, + theme: "aider", + poster: "npt:0:01", + markers: markers, + controls: true + } + ); + + // Focus on the player element so keyboard shortcuts work immediately + setTimeout(() => { + // Use setTimeout to ensure the player is fully initialized + if (player && typeof player.focus === 'function') { + player.focus(); + } else { + // If player doesn't have a focus method, try to find and focus the terminal element + const playerElement = document.querySelector('.asciinema-terminal'); + if (playerElement) { + playerElement.focus(); + } else { + // Last resort - try to find element with tabindex + const tabbableElement = document.querySelector('[tabindex]'); + if (tabbableElement) { + tabbableElement.focus(); + } + } + } + }, 100); + + // Track active toast elements + let activeToast = null; + + // Function to display toast notification + function showToast(text) { + // Get the appropriate container based on fullscreen state + let container = document.getElementById('toast-container'); + const isFullscreen = document.fullscreenElement || + document.webkitFullscreenElement || + document.mozFullScreenElement || + document.msFullscreenElement; + + // If in fullscreen, check if we need to create a fullscreen toast container + if (isFullscreen) { + // Target the fullscreen element as the container parent + const fullscreenElement = document.fullscreenElement || + document.webkitFullscreenElement || + document.mozFullScreenElement || + document.msFullscreenElement; + + // Look for an existing fullscreen toast container + let fsContainer = fullscreenElement.querySelector('.fs-toast-container'); + + if (!fsContainer) { + // Create a new container for fullscreen mode + fsContainer = document.createElement('div'); + fsContainer.className = 'toast-container fs-toast-container'; + fsContainer.id = 'fs-toast-container'; + fullscreenElement.appendChild(fsContainer); + } + + container = fsContainer; + } + + // Remove any existing toast + if (activeToast) { + hideToast(activeToast); + } + + // Create toast element + const toast = document.createElement('div'); + toast.className = 'toast-notification'; + toast.textContent = text; + + // Add to container + container.appendChild(toast); + + // Store reference to active toast + activeToast = { + element: toast, + container: container + }; + + // Trigger animation + setTimeout(() => { + toast.style.opacity = '1'; + }, 10); + + return activeToast; + } + + // Function to hide a toast + function hideToast(toastInfo) { + if (!toastInfo || !toastInfo.element) return; + + toastInfo.element.style.opacity = '0'; + setTimeout(() => { + if (toastInfo.container && toastInfo.container.contains(toastInfo.element)) { + toastInfo.container.removeChild(toastInfo.element); + } + + // If this was the active toast, clear the reference + if (activeToast === toastInfo) { + activeToast = null; + } + }, 300); // Wait for fade out animation + } + + // Track if TTS is currently in progress to prevent duplicates + let ttsInProgress = false; + let currentToast = null; + + // Improved browser TTS function + function useBrowserTTS(text) { + // Don't start new speech if already in progress + if (ttsInProgress) { + console.log('Speech synthesis already in progress, skipping'); + return false; + } + + if ('speechSynthesis' in window) { + console.log('Using browser TTS fallback'); + + // Set flag to prevent duplicate speech + ttsInProgress = true; + + // Cancel any ongoing speech + window.speechSynthesis.cancel(); + + const utterance = new SpeechSynthesisUtterance(text); + utterance.rate = 1.0; + utterance.pitch = 1.0; + utterance.volume = 1.0; + + // For iOS, use a shorter utterance if possible + if (/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream) { + utterance.text = text.length > 100 ? text.substring(0, 100) + '...' : text; + } + + utterance.onstart = () => console.log('Speech started'); + utterance.onend = () => { + console.log('Speech ended'); + ttsInProgress = false; // Reset flag when speech completes + + // Hide toast when speech ends + if (currentToast) { + hideToast(currentToast); + currentToast = null; + } + }; + utterance.onerror = (e) => { + console.warn('Speech error:', e); + ttsInProgress = false; // Reset flag on error + + // Also hide toast on error + if (currentToast) { + hideToast(currentToast); + currentToast = null; + } + }; + + window.speechSynthesis.speak(utterance); + return true; + } + console.warn('SpeechSynthesis not supported'); + return false; + } + + // Function to play pre-generated TTS audio files + function speakText(text, timeInSeconds) { + // Show the toast and keep reference + currentToast = showToast(text); + + // Format time for filename (MM-SS) + const minutes = Math.floor(timeInSeconds / 60); + const seconds = timeInSeconds % 60; + const formattedTime = `${minutes.toString().padStart(2, '0')}-${seconds.toString().padStart(2, '0')}`; + + // Get recording_id from the page or use default from the URL + const recordingId = typeof recording_id !== 'undefined' ? recording_id : + window.location.pathname.split('/').pop().replace('.html', ''); + + // Construct audio file path + const audioPath = `/assets/audio/${recordingId}/${formattedTime}.mp3`; + + // Log for debugging + console.log(`Attempting to play audio: ${audioPath}`); + + // Detect iOS + const isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream; + console.log(`Device is iOS: ${isIOS}`); + + // Flag to track if we've already fallen back to TTS + let fallenBackToTTS = false; + + try { + // Create or reuse audio element + if (!globalAudio) { + globalAudio = new Audio(); + console.log("Created new global Audio element"); + } + + // Set up event handlers + globalAudio.onended = () => { + console.log('Audio playback ended'); + // Hide toast when audio ends + if (currentToast) { + hideToast(currentToast); + currentToast = null; + } + }; + + globalAudio.onerror = (e) => { + console.warn(`Audio error: ${e.type}`, e); + if (!fallenBackToTTS) { + fallenBackToTTS = true; + useBrowserTTS(text); + } else if (currentToast) { + // If we've already tried TTS and that failed too, hide the toast + hideToast(currentToast); + currentToast = null; + } + }; + + // For iOS, preload might help with subsequent plays + if (isIOS) { + globalAudio.preload = "auto"; + } + + // Set the new source + globalAudio.src = audioPath; + + // Play with proper error handling + const playPromise = globalAudio.play(); + + if (playPromise !== undefined) { + playPromise.catch(error => { + console.warn(`Play error: ${error.message}`); + + // On iOS, a user gesture might be required + if (isIOS) { + console.log("iOS playback failed, trying SpeechSynthesis"); + } + + if (!fallenBackToTTS) { + fallenBackToTTS = true; + useBrowserTTS(text); + } + }); + } + } catch (e) { + console.error(`Exception in audio playback: ${e.message}`); + useBrowserTTS(text); + } + } + + // Function to highlight the active timestamp in the transcript + function highlightTimestamp(timeInSeconds) { + // Remove previous highlights + document.querySelectorAll('.timestamp-active').forEach(el => { + el.classList.remove('timestamp-active'); + }); + + document.querySelectorAll('.active-marker').forEach(el => { + el.classList.remove('active-marker'); + }); + + // Find the timestamp link with matching time + const timestampLinks = document.querySelectorAll('.timestamp-link'); + let activeLink = null; + + for (const link of timestampLinks) { + if (parseInt(link.dataset.time) === timeInSeconds) { + activeLink = link; + break; + } + } + + if (activeLink) { + // Add highlight class to the link + activeLink.classList.add('timestamp-active'); + + // Also highlight the parent list item + const listItem = activeLink.closest('li'); + if (listItem) { + listItem.classList.add('active-marker'); + + // No longer scrolling into view to avoid shifting focus + } + } + } + + // Add event listener with safety checks + if (player && typeof player.addEventListener === 'function') { + player.addEventListener('marker', function(event) { + try { + const { index, time, label } = event; + console.log(`marker! ${index} - ${time} - ${label}`); + + // Speak the marker label (toast is now shown within speakText) + speakText(label, time); + + // Highlight the corresponding timestamp in the transcript + highlightTimestamp(time); + } catch (error) { + console.error('Error in marker event handler:', error); + } + }); + } +}); diff --git a/aider/website/_includes/recording.md b/aider/website/_includes/recording.md new file mode 100644 index 000000000..f4fc346de --- /dev/null +++ b/aider/website/_includes/recording.md @@ -0,0 +1,34 @@ + + + + + + + +
+
+ +
+
+
+
+
+
+
+
+
aider
+
+
+
+
+
+ +
+ Space Play/pause — + f Fullscreen — + ±5s +
diff --git a/aider/website/assets/Glass_TTY_VT220.ttf b/aider/website/assets/Glass_TTY_VT220.ttf new file mode 100644 index 000000000..ed8fd8505 Binary files /dev/null and b/aider/website/assets/Glass_TTY_VT220.ttf differ diff --git a/aider/website/assets/asciinema/asciinema-player.css b/aider/website/assets/asciinema/asciinema-player.css new file mode 100644 index 000000000..24fbf3eda --- /dev/null +++ b/aider/website/assets/asciinema/asciinema-player.css @@ -0,0 +1,2366 @@ +div.ap-wrapper { + outline: none; + height: 100%; + display: flex; + justify-content: center; +} +div.ap-wrapper .title-bar { + display: none; + top: -78px; + transition: top 0.15s linear; + position: absolute; + left: 0; + right: 0; + box-sizing: content-box; + font-size: 20px; + line-height: 1em; + padding: 15px; + font-family: sans-serif; + color: white; + background-color: rgba(0, 0, 0, 0.8); +} +div.ap-wrapper .title-bar img { + vertical-align: middle; + height: 48px; + margin-right: 16px; +} +div.ap-wrapper .title-bar a { + color: white; + text-decoration: underline; +} +div.ap-wrapper .title-bar a:hover { + text-decoration: none; +} +div.ap-wrapper:fullscreen { + background-color: #000; + width: 100%; + align-items: center; +} +div.ap-wrapper:fullscreen .title-bar { + display: initial; +} +div.ap-wrapper:fullscreen.hud .title-bar { + top: 0; +} +div.ap-wrapper div.ap-player { + text-align: left; + display: inline-block; + padding: 0px; + position: relative; + box-sizing: content-box; + overflow: hidden; + max-width: 100%; + border-radius: 4px; + font-size: 15px; + background-color: var(--term-color-background); +} +.ap-player { + --term-color-foreground: #ffffff; + --term-color-background: #000000; + --term-color-0: var(--term-color-foreground); + --term-color-1: var(--term-color-foreground); + --term-color-2: var(--term-color-foreground); + --term-color-3: var(--term-color-foreground); + --term-color-4: var(--term-color-foreground); + --term-color-5: var(--term-color-foreground); + --term-color-6: var(--term-color-foreground); + --term-color-7: var(--term-color-foreground); + --term-color-8: var(--term-color-0); + --term-color-9: var(--term-color-1); + --term-color-10: var(--term-color-2); + --term-color-11: var(--term-color-3); + --term-color-12: var(--term-color-4); + --term-color-13: var(--term-color-5); + --term-color-14: var(--term-color-6); + --term-color-15: var(--term-color-7); +} +.ap-player .fg-0 { + --fg: var(--term-color-0); +} +.ap-player .bg-0 { + --bg: var(--term-color-0); +} +.ap-player .fg-1 { + --fg: var(--term-color-1); +} +.ap-player .bg-1 { + --bg: var(--term-color-1); +} +.ap-player .fg-2 { + --fg: var(--term-color-2); +} +.ap-player .bg-2 { + --bg: var(--term-color-2); +} +.ap-player .fg-3 { + --fg: var(--term-color-3); +} +.ap-player .bg-3 { + --bg: var(--term-color-3); +} +.ap-player .fg-4 { + --fg: var(--term-color-4); +} +.ap-player .bg-4 { + --bg: var(--term-color-4); +} +.ap-player .fg-5 { + --fg: var(--term-color-5); +} +.ap-player .bg-5 { + --bg: var(--term-color-5); +} +.ap-player .fg-6 { + --fg: var(--term-color-6); +} +.ap-player .bg-6 { + --bg: var(--term-color-6); +} +.ap-player .fg-7 { + --fg: var(--term-color-7); +} +.ap-player .bg-7 { + --bg: var(--term-color-7); +} +.ap-player .fg-8 { + --fg: var(--term-color-8); +} +.ap-player .bg-8 { + --bg: var(--term-color-8); +} +.ap-player .fg-9 { + --fg: var(--term-color-9); +} +.ap-player .bg-9 { + --bg: var(--term-color-9); +} +.ap-player .fg-10 { + --fg: var(--term-color-10); +} +.ap-player .bg-10 { + --bg: var(--term-color-10); +} +.ap-player .fg-11 { + --fg: var(--term-color-11); +} +.ap-player .bg-11 { + --bg: var(--term-color-11); +} +.ap-player .fg-12 { + --fg: var(--term-color-12); +} +.ap-player .bg-12 { + --bg: var(--term-color-12); +} +.ap-player .fg-13 { + --fg: var(--term-color-13); +} +.ap-player .bg-13 { + --bg: var(--term-color-13); +} +.ap-player .fg-14 { + --fg: var(--term-color-14); +} +.ap-player .bg-14 { + --bg: var(--term-color-14); +} +.ap-player .fg-15 { + --fg: var(--term-color-15); +} +.ap-player .bg-15 { + --bg: var(--term-color-15); +} +.ap-player .fg-8, +.ap-player .fg-9, +.ap-player .fg-10, +.ap-player .fg-11, +.ap-player .fg-12, +.ap-player .fg-13, +.ap-player .fg-14, +.ap-player .fg-15 { + font-weight: bold; +} +pre.ap-terminal { + box-sizing: content-box; + overflow: hidden; + padding: 0; + margin: 0px; + display: block; + white-space: pre; + word-wrap: normal; + word-break: normal; + border-radius: 0; + border-style: solid; + cursor: text; + border-width: 0.75em; + color: var(--term-color-foreground); + background-color: var(--term-color-background); + border-color: var(--term-color-background); + outline: none; + line-height: var(--term-line-height); + font-family: Consolas, Menlo, 'Bitstream Vera Sans Mono', monospace, 'Powerline Symbols'; + font-variant-ligatures: none; +} +pre.ap-terminal .ap-line { + letter-spacing: normal; + overflow: hidden; +} +pre.ap-terminal .ap-line span { + padding: 0; + display: inline-block; + height: 100%; +} +pre.ap-terminal .ap-line { + display: block; + width: 100%; + height: var(--term-line-height); + position: relative; +} +pre.ap-terminal .ap-line span { + position: absolute; + left: calc(100% * var(--offset) / var(--term-cols)); + color: var(--fg); + background-color: var(--bg); +} +pre.ap-terminal .ap-line .ap-inverse { + color: var(--bg); + background-color: var(--fg); +} +pre.ap-terminal .ap-line .cp-2580 { + border-top: calc(0.5 * var(--term-line-height)) solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2581 { + border-bottom: calc(0.125 * var(--term-line-height)) solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2582 { + border-bottom: calc(0.25 * var(--term-line-height)) solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2583 { + border-bottom: calc(0.375 * var(--term-line-height)) solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2584 { + border-bottom: calc(0.5 * var(--term-line-height)) solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2585 { + border-bottom: calc(0.625 * var(--term-line-height)) solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2586 { + border-bottom: calc(0.75 * var(--term-line-height)) solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2587 { + border-bottom: calc(0.875 * var(--term-line-height)) solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2588 { + background-color: var(--fg); +} +pre.ap-terminal .ap-line .cp-2589 { + border-left: 0.875ch solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-258a { + border-left: 0.75ch solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-258b { + border-left: 0.625ch solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-258c { + border-left: 0.5ch solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-258d { + border-left: 0.375ch solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-258e { + border-left: 0.25ch solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-258f { + border-left: 0.125ch solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2590 { + border-right: 0.5ch solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2591 { + background-color: color-mix(in srgb, var(--fg) 25%, var(--bg)); +} +pre.ap-terminal .ap-line .cp-2592 { + background-color: color-mix(in srgb, var(--fg) 50%, var(--bg)); +} +pre.ap-terminal .ap-line .cp-2593 { + background-color: color-mix(in srgb, var(--fg) 75%, var(--bg)); +} +pre.ap-terminal .ap-line .cp-2594 { + border-top: calc(0.125 * var(--term-line-height)) solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2595 { + border-right: 0.125ch solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2596 { + border-right: 0.5ch solid var(--bg); + border-top: calc(0.5 * var(--term-line-height)) solid var(--bg); + background-color: var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2597 { + border-left: 0.5ch solid var(--bg); + border-top: calc(0.5 * var(--term-line-height)) solid var(--bg); + background-color: var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2598 { + border-right: 0.5ch solid var(--bg); + border-bottom: calc(0.5 * var(--term-line-height)) solid var(--bg); + background-color: var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-2599 { + border-left: 0.5ch solid var(--fg); + border-bottom: calc(0.5 * var(--term-line-height)) solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-259a { + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-259a::before, +pre.ap-terminal .ap-line .cp-259a::after { + content: ''; + position: absolute; + width: 0.5ch; + height: calc(0.5 * var(--term-line-height)); + background-color: var(--fg); +} +pre.ap-terminal .ap-line .cp-259a::before { + top: 0; + left: 0; +} +pre.ap-terminal .ap-line .cp-259a::after { + bottom: 0; + right: 0; +} +pre.ap-terminal .ap-line .cp-259b { + border-left: 0.5ch solid var(--fg); + border-top: calc(0.5 * var(--term-line-height)) solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-259c { + border-right: 0.5ch solid var(--fg); + border-top: calc(0.5 * var(--term-line-height)) solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-259d { + border-left: 0.5ch solid var(--bg); + border-bottom: calc(0.5 * var(--term-line-height)) solid var(--bg); + background-color: var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-259e { + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-259e::before, +pre.ap-terminal .ap-line .cp-259e::after { + content: ''; + position: absolute; + width: 0.5ch; + height: calc(0.5 * var(--term-line-height)); + background-color: var(--fg); +} +pre.ap-terminal .ap-line .cp-259e::before { + top: 0; + right: 0; +} +pre.ap-terminal .ap-line .cp-259e::after { + bottom: 0; + left: 0; +} +pre.ap-terminal .ap-line .cp-259f { + border-right: 0.5ch solid var(--fg); + border-bottom: calc(0.5 * var(--term-line-height)) solid var(--fg); + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-e0b0 { + border-left: 1ch solid var(--fg); + border-top: calc(0.5 * var(--term-line-height)) solid transparent; + border-bottom: calc(0.5 * var(--term-line-height)) solid transparent; + box-sizing: border-box; +} +pre.ap-terminal .ap-line .cp-e0b2 { + border-right: 1ch solid var(--fg); + border-top: calc(0.5 * var(--term-line-height)) solid transparent; + border-bottom: calc(0.5 * var(--term-line-height)) solid transparent; + box-sizing: border-box; +} +pre.ap-terminal.ap-cursor-on .ap-line .ap-cursor { + color: var(--bg); + background-color: var(--fg); + border-radius: 0.05em; +} +pre.ap-terminal.ap-cursor-on .ap-line .ap-cursor.ap-inverse { + color: var(--fg); + background-color: var(--bg); +} +pre.ap-terminal:not(.ap-blink) .ap-line .ap-blink { + color: transparent; + border-color: transparent; +} +pre.ap-terminal .ap-bright { + font-weight: bold; +} +pre.ap-terminal .ap-faint { + opacity: 0.5; +} +pre.ap-terminal .ap-underline { + text-decoration: underline; +} +pre.ap-terminal .ap-italic { + font-style: italic; +} +pre.ap-terminal .ap-strikethrough { + text-decoration: line-through; +} +.ap-line span { + --fg: var(--term-color-foreground); + --bg: var(--term-color-background); +} +div.ap-player div.ap-control-bar { + width: 100%; + height: 32px; + display: flex; + justify-content: space-between; + align-items: stretch; + color: var(--term-color-foreground); + box-sizing: content-box; + line-height: 1; + position: absolute; + bottom: 0; + left: 0; + opacity: 0; + transition: opacity 0.15s linear; + user-select: none; + border-top: 2px solid color-mix(in oklab, var(--term-color-background) 80%, var(--term-color-foreground)); + z-index: 30; +} +div.ap-player div.ap-control-bar * { + box-sizing: inherit; +} +div.ap-control-bar svg.ap-icon path { + fill: var(--term-color-foreground); +} +div.ap-control-bar span.ap-button { + display: flex; + flex: 0 0 auto; + cursor: pointer; +} +div.ap-control-bar span.ap-playback-button { + width: 12px; + height: 12px; + padding: 10px; +} +div.ap-control-bar span.ap-playback-button svg { + height: 12px; + width: 12px; +} +div.ap-control-bar span.ap-timer { + display: flex; + flex: 0 0 auto; + min-width: 50px; + margin: 0 10px; + height: 100%; + text-align: center; + font-size: 13px; + line-height: 100%; + cursor: default; +} +div.ap-control-bar span.ap-timer span { + font-family: Consolas, Menlo, 'Bitstream Vera Sans Mono', monospace; + font-size: inherit; + font-weight: 600; + margin: auto; +} +div.ap-control-bar span.ap-timer .ap-time-remaining { + display: none; +} +div.ap-control-bar span.ap-timer:hover .ap-time-elapsed { + display: none; +} +div.ap-control-bar span.ap-timer:hover .ap-time-remaining { + display: flex; +} +div.ap-control-bar .ap-progressbar { + display: block; + flex: 1 1 auto; + height: 100%; + padding: 0 10px; +} +div.ap-control-bar .ap-progressbar .ap-bar { + display: block; + position: relative; + cursor: default; + height: 100%; + font-size: 0; +} +div.ap-control-bar .ap-progressbar .ap-bar .ap-gutter { + display: block; + position: absolute; + top: 15px; + left: 0; + right: 0; + height: 3px; +} +div.ap-control-bar .ap-progressbar .ap-bar .ap-gutter-empty { + background-color: color-mix(in oklab, var(--term-color-foreground) 20%, var(--term-color-background)); +} +div.ap-control-bar .ap-progressbar .ap-bar .ap-gutter-full { + width: 100%; + transform-origin: left center; + background-color: var(--term-color-foreground); + border-radius: 3px; +} +div.ap-control-bar.ap-seekable .ap-progressbar .ap-bar { + cursor: pointer; +} +div.ap-control-bar .ap-fullscreen-button { + width: 14px; + height: 14px; + padding: 9px; +} +div.ap-control-bar .ap-fullscreen-button svg { + width: 14px; + height: 14px; +} +div.ap-control-bar .ap-fullscreen-button svg.ap-icon-fullscreen-on { + display: inline; +} +div.ap-control-bar .ap-fullscreen-button svg.ap-icon-fullscreen-off { + display: none; +} +div.ap-control-bar .ap-fullscreen-button .ap-tooltip { + right: 5px; + left: initial; + transform: none; +} +div.ap-control-bar .ap-kbd-button { + height: 14px; + padding: 9px; + margin: 0 4px; +} +div.ap-control-bar .ap-kbd-button svg { + width: 26px; + height: 14px; +} +div.ap-control-bar .ap-kbd-button .ap-tooltip { + right: 5px; + left: initial; + transform: none; +} +div.ap-wrapper.ap-hud .ap-control-bar { + opacity: 1; +} +div.ap-wrapper:fullscreen .ap-fullscreen-button svg.ap-icon-fullscreen-on { + display: none; +} +div.ap-wrapper:fullscreen .ap-fullscreen-button svg.ap-icon-fullscreen-off { + display: inline; +} +span.ap-progressbar span.ap-marker-container { + display: block; + top: 0; + bottom: 0; + width: 21px; + position: absolute; + margin-left: -10px; +} +span.ap-marker-container span.ap-marker { + display: block; + top: 13px; + bottom: 12px; + left: 7px; + right: 7px; + background-color: color-mix(in oklab, var(--term-color-foreground) 33%, var(--term-color-background)); + position: absolute; + transition: top 0.1s, bottom 0.1s, left 0.1s, right 0.1s, background-color 0.1s; + border-radius: 50%; +} +span.ap-marker-container span.ap-marker.ap-marker-past { + background-color: var(--term-color-foreground); +} +span.ap-marker-container span.ap-marker:hover, +span.ap-marker-container:hover span.ap-marker { + background-color: var(--term-color-foreground); + top: 11px; + bottom: 10px; + left: 5px; + right: 5px; +} +.ap-tooltip-container span.ap-tooltip { + visibility: hidden; + background-color: var(--term-color-foreground); + color: var(--term-color-background); + font-family: Consolas, Menlo, 'Bitstream Vera Sans Mono', monospace; + font-weight: bold; + text-align: center; + padding: 0 0.5em; + border-radius: 4px; + position: absolute; + z-index: 1; + white-space: nowrap; + /* Prevents the text from wrapping and makes sure the tooltip width adapts to the text length */ + font-size: 13px; + line-height: 2em; + bottom: 100%; + left: 50%; + transform: translateX(-50%); +} +.ap-tooltip-container:hover span.ap-tooltip { + visibility: visible; +} +.ap-player .ap-overlay { + z-index: 10; + background-repeat: no-repeat; + background-position: center; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + display: flex; + justify-content: center; + align-items: center; +} +.ap-player .ap-overlay-start { + cursor: pointer; +} +.ap-player .ap-overlay-start .ap-play-button { + font-size: 0px; + position: absolute; + left: 0; + top: 0; + right: 0; + bottom: 0; + text-align: center; + color: white; + height: 80px; + max-height: 66%; + margin: auto; +} +.ap-player .ap-overlay-start .ap-play-button div { + height: 100%; +} +.ap-player .ap-overlay-start .ap-play-button div span { + height: 100%; + display: block; +} +.ap-player .ap-overlay-start .ap-play-button div span svg { + height: 100%; +} +.ap-player .ap-overlay-start .ap-play-button svg { + filter: drop-shadow(0px 0px 5px rgba(0, 0, 0, 0.4)); +} +.ap-player .ap-overlay-loading .ap-loader { + width: 48px; + height: 48px; + border-radius: 50%; + display: inline-block; + position: relative; + border: 10px solid; + border-color: rgba(255, 255, 255, 0.3) rgba(255, 255, 255, 0.5) rgba(255, 255, 255, 0.7) #ffffff; + border-color: color-mix(in srgb, var(--term-color-foreground) 30%, var(--term-color-background)) color-mix(in srgb, var(--term-color-foreground) 50%, var(--term-color-background)) color-mix(in srgb, var(--term-color-foreground) 70%, var(--term-color-background)) color-mix(in srgb, var(--term-color-foreground) 100%, var(--term-color-background)); + box-sizing: border-box; + animation: ap-loader-rotation 1s linear infinite; +} +.ap-player .ap-overlay-info { + background-color: var(--term-color-background); +} +.ap-player .ap-overlay-info span { + font-family: Consolas, Menlo, 'Bitstream Vera Sans Mono', monospace, 'Powerline Symbols'; + font-variant-ligatures: none; + font-size: 2em; + color: var(--term-color-foreground); +} +.ap-player .ap-overlay-info span .ap-line { + letter-spacing: normal; + overflow: hidden; +} +.ap-player .ap-overlay-info span .ap-line span { + padding: 0; + display: inline-block; + height: 100%; +} +.ap-player .ap-overlay-help { + background-color: rgba(0, 0, 0, 0.8); + container-type: inline-size; +} +.ap-player .ap-overlay-help > div { + font-family: Consolas, Menlo, 'Bitstream Vera Sans Mono', monospace, 'Powerline Symbols'; + font-variant-ligatures: none; + max-width: 85%; + max-height: 85%; + font-size: 18px; + color: var(--term-color-foreground); + box-sizing: border-box; + margin-bottom: 32px; +} +.ap-player .ap-overlay-help > div .ap-line { + letter-spacing: normal; + overflow: hidden; +} +.ap-player .ap-overlay-help > div .ap-line span { + padding: 0; + display: inline-block; + height: 100%; +} +.ap-player .ap-overlay-help > div div { + padding: calc(min(4cqw, 40px)); + font-size: calc(min(1.9cqw, 18px)); + background-color: var(--term-color-background); + border: 1px solid color-mix(in oklab, var(--term-color-background) 90%, var(--term-color-foreground)); + border-radius: 6px; +} +.ap-player .ap-overlay-help > div div p { + font-weight: bold; + margin: 0 0 2em 0; +} +.ap-player .ap-overlay-help > div div ul { + list-style: none; + padding: 0; +} +.ap-player .ap-overlay-help > div div ul li { + margin: 0 0 0.75em 0; +} +.ap-player .ap-overlay-help > div div kbd { + color: var(--term-color-background); + background-color: var(--term-color-foreground); + padding: 0.2em 0.5em; + border-radius: 0.2em; + font-family: inherit; + font-size: 0.85em; + border: none; + margin: 0; +} +.ap-player .ap-overlay-error span { + font-size: 8em; +} +@keyframes ap-loader-rotation { + 0% { + transform: rotate(0deg); + } + 100% { + transform: rotate(360deg); + } +} +.ap-terminal .fg-16 { + --fg: #000000; +} +.ap-terminal .bg-16 { + --bg: #000000; +} +.ap-terminal .fg-17 { + --fg: #00005f; +} +.ap-terminal .bg-17 { + --bg: #00005f; +} +.ap-terminal .fg-18 { + --fg: #000087; +} +.ap-terminal .bg-18 { + --bg: #000087; +} +.ap-terminal .fg-19 { + --fg: #0000af; +} +.ap-terminal .bg-19 { + --bg: #0000af; +} +.ap-terminal .fg-20 { + --fg: #0000d7; +} +.ap-terminal .bg-20 { + --bg: #0000d7; +} +.ap-terminal .fg-21 { + --fg: #0000ff; +} +.ap-terminal .bg-21 { + --bg: #0000ff; +} +.ap-terminal .fg-22 { + --fg: #005f00; +} +.ap-terminal .bg-22 { + --bg: #005f00; +} +.ap-terminal .fg-23 { + --fg: #005f5f; +} +.ap-terminal .bg-23 { + --bg: #005f5f; +} +.ap-terminal .fg-24 { + --fg: #005f87; +} +.ap-terminal .bg-24 { + --bg: #005f87; +} +.ap-terminal .fg-25 { + --fg: #005faf; +} +.ap-terminal .bg-25 { + --bg: #005faf; +} +.ap-terminal .fg-26 { + --fg: #005fd7; +} +.ap-terminal .bg-26 { + --bg: #005fd7; +} +.ap-terminal .fg-27 { + --fg: #005fff; +} +.ap-terminal .bg-27 { + --bg: #005fff; +} +.ap-terminal .fg-28 { + --fg: #008700; +} +.ap-terminal .bg-28 { + --bg: #008700; +} +.ap-terminal .fg-29 { + --fg: #00875f; +} +.ap-terminal .bg-29 { + --bg: #00875f; +} +.ap-terminal .fg-30 { + --fg: #008787; +} +.ap-terminal .bg-30 { + --bg: #008787; +} +.ap-terminal .fg-31 { + --fg: #0087af; +} +.ap-terminal .bg-31 { + --bg: #0087af; +} +.ap-terminal .fg-32 { + --fg: #0087d7; +} +.ap-terminal .bg-32 { + --bg: #0087d7; +} +.ap-terminal .fg-33 { + --fg: #0087ff; +} +.ap-terminal .bg-33 { + --bg: #0087ff; +} +.ap-terminal .fg-34 { + --fg: #00af00; +} +.ap-terminal .bg-34 { + --bg: #00af00; +} +.ap-terminal .fg-35 { + --fg: #00af5f; +} +.ap-terminal .bg-35 { + --bg: #00af5f; +} +.ap-terminal .fg-36 { + --fg: #00af87; +} +.ap-terminal .bg-36 { + --bg: #00af87; +} +.ap-terminal .fg-37 { + --fg: #00afaf; +} +.ap-terminal .bg-37 { + --bg: #00afaf; +} +.ap-terminal .fg-38 { + --fg: #00afd7; +} +.ap-terminal .bg-38 { + --bg: #00afd7; +} +.ap-terminal .fg-39 { + --fg: #00afff; +} +.ap-terminal .bg-39 { + --bg: #00afff; +} +.ap-terminal .fg-40 { + --fg: #00d700; +} +.ap-terminal .bg-40 { + --bg: #00d700; +} +.ap-terminal .fg-41 { + --fg: #00d75f; +} +.ap-terminal .bg-41 { + --bg: #00d75f; +} +.ap-terminal .fg-42 { + --fg: #00d787; +} +.ap-terminal .bg-42 { + --bg: #00d787; +} +.ap-terminal .fg-43 { + --fg: #00d7af; +} +.ap-terminal .bg-43 { + --bg: #00d7af; +} +.ap-terminal .fg-44 { + --fg: #00d7d7; +} +.ap-terminal .bg-44 { + --bg: #00d7d7; +} +.ap-terminal .fg-45 { + --fg: #00d7ff; +} +.ap-terminal .bg-45 { + --bg: #00d7ff; +} +.ap-terminal .fg-46 { + --fg: #00ff00; +} +.ap-terminal .bg-46 { + --bg: #00ff00; +} +.ap-terminal .fg-47 { + --fg: #00ff5f; +} +.ap-terminal .bg-47 { + --bg: #00ff5f; +} +.ap-terminal .fg-48 { + --fg: #00ff87; +} +.ap-terminal .bg-48 { + --bg: #00ff87; +} +.ap-terminal .fg-49 { + --fg: #00ffaf; +} +.ap-terminal .bg-49 { + --bg: #00ffaf; +} +.ap-terminal .fg-50 { + --fg: #00ffd7; +} +.ap-terminal .bg-50 { + --bg: #00ffd7; +} +.ap-terminal .fg-51 { + --fg: #00ffff; +} +.ap-terminal .bg-51 { + --bg: #00ffff; +} +.ap-terminal .fg-52 { + --fg: #5f0000; +} +.ap-terminal .bg-52 { + --bg: #5f0000; +} +.ap-terminal .fg-53 { + --fg: #5f005f; +} +.ap-terminal .bg-53 { + --bg: #5f005f; +} +.ap-terminal .fg-54 { + --fg: #5f0087; +} +.ap-terminal .bg-54 { + --bg: #5f0087; +} +.ap-terminal .fg-55 { + --fg: #5f00af; +} +.ap-terminal .bg-55 { + --bg: #5f00af; +} +.ap-terminal .fg-56 { + --fg: #5f00d7; +} +.ap-terminal .bg-56 { + --bg: #5f00d7; +} +.ap-terminal .fg-57 { + --fg: #5f00ff; +} +.ap-terminal .bg-57 { + --bg: #5f00ff; +} +.ap-terminal .fg-58 { + --fg: #5f5f00; +} +.ap-terminal .bg-58 { + --bg: #5f5f00; +} +.ap-terminal .fg-59 { + --fg: #5f5f5f; +} +.ap-terminal .bg-59 { + --bg: #5f5f5f; +} +.ap-terminal .fg-60 { + --fg: #5f5f87; +} +.ap-terminal .bg-60 { + --bg: #5f5f87; +} +.ap-terminal .fg-61 { + --fg: #5f5faf; +} +.ap-terminal .bg-61 { + --bg: #5f5faf; +} +.ap-terminal .fg-62 { + --fg: #5f5fd7; +} +.ap-terminal .bg-62 { + --bg: #5f5fd7; +} +.ap-terminal .fg-63 { + --fg: #5f5fff; +} +.ap-terminal .bg-63 { + --bg: #5f5fff; +} +.ap-terminal .fg-64 { + --fg: #5f8700; +} +.ap-terminal .bg-64 { + --bg: #5f8700; +} +.ap-terminal .fg-65 { + --fg: #5f875f; +} +.ap-terminal .bg-65 { + --bg: #5f875f; +} +.ap-terminal .fg-66 { + --fg: #5f8787; +} +.ap-terminal .bg-66 { + --bg: #5f8787; +} +.ap-terminal .fg-67 { + --fg: #5f87af; +} +.ap-terminal .bg-67 { + --bg: #5f87af; +} +.ap-terminal .fg-68 { + --fg: #5f87d7; +} +.ap-terminal .bg-68 { + --bg: #5f87d7; +} +.ap-terminal .fg-69 { + --fg: #5f87ff; +} +.ap-terminal .bg-69 { + --bg: #5f87ff; +} +.ap-terminal .fg-70 { + --fg: #5faf00; +} +.ap-terminal .bg-70 { + --bg: #5faf00; +} +.ap-terminal .fg-71 { + --fg: #5faf5f; +} +.ap-terminal .bg-71 { + --bg: #5faf5f; +} +.ap-terminal .fg-72 { + --fg: #5faf87; +} +.ap-terminal .bg-72 { + --bg: #5faf87; +} +.ap-terminal .fg-73 { + --fg: #5fafaf; +} +.ap-terminal .bg-73 { + --bg: #5fafaf; +} +.ap-terminal .fg-74 { + --fg: #5fafd7; +} +.ap-terminal .bg-74 { + --bg: #5fafd7; +} +.ap-terminal .fg-75 { + --fg: #5fafff; +} +.ap-terminal .bg-75 { + --bg: #5fafff; +} +.ap-terminal .fg-76 { + --fg: #5fd700; +} +.ap-terminal .bg-76 { + --bg: #5fd700; +} +.ap-terminal .fg-77 { + --fg: #5fd75f; +} +.ap-terminal .bg-77 { + --bg: #5fd75f; +} +.ap-terminal .fg-78 { + --fg: #5fd787; +} +.ap-terminal .bg-78 { + --bg: #5fd787; +} +.ap-terminal .fg-79 { + --fg: #5fd7af; +} +.ap-terminal .bg-79 { + --bg: #5fd7af; +} +.ap-terminal .fg-80 { + --fg: #5fd7d7; +} +.ap-terminal .bg-80 { + --bg: #5fd7d7; +} +.ap-terminal .fg-81 { + --fg: #5fd7ff; +} +.ap-terminal .bg-81 { + --bg: #5fd7ff; +} +.ap-terminal .fg-82 { + --fg: #5fff00; +} +.ap-terminal .bg-82 { + --bg: #5fff00; +} +.ap-terminal .fg-83 { + --fg: #5fff5f; +} +.ap-terminal .bg-83 { + --bg: #5fff5f; +} +.ap-terminal .fg-84 { + --fg: #5fff87; +} +.ap-terminal .bg-84 { + --bg: #5fff87; +} +.ap-terminal .fg-85 { + --fg: #5fffaf; +} +.ap-terminal .bg-85 { + --bg: #5fffaf; +} +.ap-terminal .fg-86 { + --fg: #5fffd7; +} +.ap-terminal .bg-86 { + --bg: #5fffd7; +} +.ap-terminal .fg-87 { + --fg: #5fffff; +} +.ap-terminal .bg-87 { + --bg: #5fffff; +} +.ap-terminal .fg-88 { + --fg: #870000; +} +.ap-terminal .bg-88 { + --bg: #870000; +} +.ap-terminal .fg-89 { + --fg: #87005f; +} +.ap-terminal .bg-89 { + --bg: #87005f; +} +.ap-terminal .fg-90 { + --fg: #870087; +} +.ap-terminal .bg-90 { + --bg: #870087; +} +.ap-terminal .fg-91 { + --fg: #8700af; +} +.ap-terminal .bg-91 { + --bg: #8700af; +} +.ap-terminal .fg-92 { + --fg: #8700d7; +} +.ap-terminal .bg-92 { + --bg: #8700d7; +} +.ap-terminal .fg-93 { + --fg: #8700ff; +} +.ap-terminal .bg-93 { + --bg: #8700ff; +} +.ap-terminal .fg-94 { + --fg: #875f00; +} +.ap-terminal .bg-94 { + --bg: #875f00; +} +.ap-terminal .fg-95 { + --fg: #875f5f; +} +.ap-terminal .bg-95 { + --bg: #875f5f; +} +.ap-terminal .fg-96 { + --fg: #875f87; +} +.ap-terminal .bg-96 { + --bg: #875f87; +} +.ap-terminal .fg-97 { + --fg: #875faf; +} +.ap-terminal .bg-97 { + --bg: #875faf; +} +.ap-terminal .fg-98 { + --fg: #875fd7; +} +.ap-terminal .bg-98 { + --bg: #875fd7; +} +.ap-terminal .fg-99 { + --fg: #875fff; +} +.ap-terminal .bg-99 { + --bg: #875fff; +} +.ap-terminal .fg-100 { + --fg: #878700; +} +.ap-terminal .bg-100 { + --bg: #878700; +} +.ap-terminal .fg-101 { + --fg: #87875f; +} +.ap-terminal .bg-101 { + --bg: #87875f; +} +.ap-terminal .fg-102 { + --fg: #878787; +} +.ap-terminal .bg-102 { + --bg: #878787; +} +.ap-terminal .fg-103 { + --fg: #8787af; +} +.ap-terminal .bg-103 { + --bg: #8787af; +} +.ap-terminal .fg-104 { + --fg: #8787d7; +} +.ap-terminal .bg-104 { + --bg: #8787d7; +} +.ap-terminal .fg-105 { + --fg: #8787ff; +} +.ap-terminal .bg-105 { + --bg: #8787ff; +} +.ap-terminal .fg-106 { + --fg: #87af00; +} +.ap-terminal .bg-106 { + --bg: #87af00; +} +.ap-terminal .fg-107 { + --fg: #87af5f; +} +.ap-terminal .bg-107 { + --bg: #87af5f; +} +.ap-terminal .fg-108 { + --fg: #87af87; +} +.ap-terminal .bg-108 { + --bg: #87af87; +} +.ap-terminal .fg-109 { + --fg: #87afaf; +} +.ap-terminal .bg-109 { + --bg: #87afaf; +} +.ap-terminal .fg-110 { + --fg: #87afd7; +} +.ap-terminal .bg-110 { + --bg: #87afd7; +} +.ap-terminal .fg-111 { + --fg: #87afff; +} +.ap-terminal .bg-111 { + --bg: #87afff; +} +.ap-terminal .fg-112 { + --fg: #87d700; +} +.ap-terminal .bg-112 { + --bg: #87d700; +} +.ap-terminal .fg-113 { + --fg: #87d75f; +} +.ap-terminal .bg-113 { + --bg: #87d75f; +} +.ap-terminal .fg-114 { + --fg: #87d787; +} +.ap-terminal .bg-114 { + --bg: #87d787; +} +.ap-terminal .fg-115 { + --fg: #87d7af; +} +.ap-terminal .bg-115 { + --bg: #87d7af; +} +.ap-terminal .fg-116 { + --fg: #87d7d7; +} +.ap-terminal .bg-116 { + --bg: #87d7d7; +} +.ap-terminal .fg-117 { + --fg: #87d7ff; +} +.ap-terminal .bg-117 { + --bg: #87d7ff; +} +.ap-terminal .fg-118 { + --fg: #87ff00; +} +.ap-terminal .bg-118 { + --bg: #87ff00; +} +.ap-terminal .fg-119 { + --fg: #87ff5f; +} +.ap-terminal .bg-119 { + --bg: #87ff5f; +} +.ap-terminal .fg-120 { + --fg: #87ff87; +} +.ap-terminal .bg-120 { + --bg: #87ff87; +} +.ap-terminal .fg-121 { + --fg: #87ffaf; +} +.ap-terminal .bg-121 { + --bg: #87ffaf; +} +.ap-terminal .fg-122 { + --fg: #87ffd7; +} +.ap-terminal .bg-122 { + --bg: #87ffd7; +} +.ap-terminal .fg-123 { + --fg: #87ffff; +} +.ap-terminal .bg-123 { + --bg: #87ffff; +} +.ap-terminal .fg-124 { + --fg: #af0000; +} +.ap-terminal .bg-124 { + --bg: #af0000; +} +.ap-terminal .fg-125 { + --fg: #af005f; +} +.ap-terminal .bg-125 { + --bg: #af005f; +} +.ap-terminal .fg-126 { + --fg: #af0087; +} +.ap-terminal .bg-126 { + --bg: #af0087; +} +.ap-terminal .fg-127 { + --fg: #af00af; +} +.ap-terminal .bg-127 { + --bg: #af00af; +} +.ap-terminal .fg-128 { + --fg: #af00d7; +} +.ap-terminal .bg-128 { + --bg: #af00d7; +} +.ap-terminal .fg-129 { + --fg: #af00ff; +} +.ap-terminal .bg-129 { + --bg: #af00ff; +} +.ap-terminal .fg-130 { + --fg: #af5f00; +} +.ap-terminal .bg-130 { + --bg: #af5f00; +} +.ap-terminal .fg-131 { + --fg: #af5f5f; +} +.ap-terminal .bg-131 { + --bg: #af5f5f; +} +.ap-terminal .fg-132 { + --fg: #af5f87; +} +.ap-terminal .bg-132 { + --bg: #af5f87; +} +.ap-terminal .fg-133 { + --fg: #af5faf; +} +.ap-terminal .bg-133 { + --bg: #af5faf; +} +.ap-terminal .fg-134 { + --fg: #af5fd7; +} +.ap-terminal .bg-134 { + --bg: #af5fd7; +} +.ap-terminal .fg-135 { + --fg: #af5fff; +} +.ap-terminal .bg-135 { + --bg: #af5fff; +} +.ap-terminal .fg-136 { + --fg: #af8700; +} +.ap-terminal .bg-136 { + --bg: #af8700; +} +.ap-terminal .fg-137 { + --fg: #af875f; +} +.ap-terminal .bg-137 { + --bg: #af875f; +} +.ap-terminal .fg-138 { + --fg: #af8787; +} +.ap-terminal .bg-138 { + --bg: #af8787; +} +.ap-terminal .fg-139 { + --fg: #af87af; +} +.ap-terminal .bg-139 { + --bg: #af87af; +} +.ap-terminal .fg-140 { + --fg: #af87d7; +} +.ap-terminal .bg-140 { + --bg: #af87d7; +} +.ap-terminal .fg-141 { + --fg: #af87ff; +} +.ap-terminal .bg-141 { + --bg: #af87ff; +} +.ap-terminal .fg-142 { + --fg: #afaf00; +} +.ap-terminal .bg-142 { + --bg: #afaf00; +} +.ap-terminal .fg-143 { + --fg: #afaf5f; +} +.ap-terminal .bg-143 { + --bg: #afaf5f; +} +.ap-terminal .fg-144 { + --fg: #afaf87; +} +.ap-terminal .bg-144 { + --bg: #afaf87; +} +.ap-terminal .fg-145 { + --fg: #afafaf; +} +.ap-terminal .bg-145 { + --bg: #afafaf; +} +.ap-terminal .fg-146 { + --fg: #afafd7; +} +.ap-terminal .bg-146 { + --bg: #afafd7; +} +.ap-terminal .fg-147 { + --fg: #afafff; +} +.ap-terminal .bg-147 { + --bg: #afafff; +} +.ap-terminal .fg-148 { + --fg: #afd700; +} +.ap-terminal .bg-148 { + --bg: #afd700; +} +.ap-terminal .fg-149 { + --fg: #afd75f; +} +.ap-terminal .bg-149 { + --bg: #afd75f; +} +.ap-terminal .fg-150 { + --fg: #afd787; +} +.ap-terminal .bg-150 { + --bg: #afd787; +} +.ap-terminal .fg-151 { + --fg: #afd7af; +} +.ap-terminal .bg-151 { + --bg: #afd7af; +} +.ap-terminal .fg-152 { + --fg: #afd7d7; +} +.ap-terminal .bg-152 { + --bg: #afd7d7; +} +.ap-terminal .fg-153 { + --fg: #afd7ff; +} +.ap-terminal .bg-153 { + --bg: #afd7ff; +} +.ap-terminal .fg-154 { + --fg: #afff00; +} +.ap-terminal .bg-154 { + --bg: #afff00; +} +.ap-terminal .fg-155 { + --fg: #afff5f; +} +.ap-terminal .bg-155 { + --bg: #afff5f; +} +.ap-terminal .fg-156 { + --fg: #afff87; +} +.ap-terminal .bg-156 { + --bg: #afff87; +} +.ap-terminal .fg-157 { + --fg: #afffaf; +} +.ap-terminal .bg-157 { + --bg: #afffaf; +} +.ap-terminal .fg-158 { + --fg: #afffd7; +} +.ap-terminal .bg-158 { + --bg: #afffd7; +} +.ap-terminal .fg-159 { + --fg: #afffff; +} +.ap-terminal .bg-159 { + --bg: #afffff; +} +.ap-terminal .fg-160 { + --fg: #d70000; +} +.ap-terminal .bg-160 { + --bg: #d70000; +} +.ap-terminal .fg-161 { + --fg: #d7005f; +} +.ap-terminal .bg-161 { + --bg: #d7005f; +} +.ap-terminal .fg-162 { + --fg: #d70087; +} +.ap-terminal .bg-162 { + --bg: #d70087; +} +.ap-terminal .fg-163 { + --fg: #d700af; +} +.ap-terminal .bg-163 { + --bg: #d700af; +} +.ap-terminal .fg-164 { + --fg: #d700d7; +} +.ap-terminal .bg-164 { + --bg: #d700d7; +} +.ap-terminal .fg-165 { + --fg: #d700ff; +} +.ap-terminal .bg-165 { + --bg: #d700ff; +} +.ap-terminal .fg-166 { + --fg: #d75f00; +} +.ap-terminal .bg-166 { + --bg: #d75f00; +} +.ap-terminal .fg-167 { + --fg: #d75f5f; +} +.ap-terminal .bg-167 { + --bg: #d75f5f; +} +.ap-terminal .fg-168 { + --fg: #d75f87; +} +.ap-terminal .bg-168 { + --bg: #d75f87; +} +.ap-terminal .fg-169 { + --fg: #d75faf; +} +.ap-terminal .bg-169 { + --bg: #d75faf; +} +.ap-terminal .fg-170 { + --fg: #d75fd7; +} +.ap-terminal .bg-170 { + --bg: #d75fd7; +} +.ap-terminal .fg-171 { + --fg: #d75fff; +} +.ap-terminal .bg-171 { + --bg: #d75fff; +} +.ap-terminal .fg-172 { + --fg: #d78700; +} +.ap-terminal .bg-172 { + --bg: #d78700; +} +.ap-terminal .fg-173 { + --fg: #d7875f; +} +.ap-terminal .bg-173 { + --bg: #d7875f; +} +.ap-terminal .fg-174 { + --fg: #d78787; +} +.ap-terminal .bg-174 { + --bg: #d78787; +} +.ap-terminal .fg-175 { + --fg: #d787af; +} +.ap-terminal .bg-175 { + --bg: #d787af; +} +.ap-terminal .fg-176 { + --fg: #d787d7; +} +.ap-terminal .bg-176 { + --bg: #d787d7; +} +.ap-terminal .fg-177 { + --fg: #d787ff; +} +.ap-terminal .bg-177 { + --bg: #d787ff; +} +.ap-terminal .fg-178 { + --fg: #d7af00; +} +.ap-terminal .bg-178 { + --bg: #d7af00; +} +.ap-terminal .fg-179 { + --fg: #d7af5f; +} +.ap-terminal .bg-179 { + --bg: #d7af5f; +} +.ap-terminal .fg-180 { + --fg: #d7af87; +} +.ap-terminal .bg-180 { + --bg: #d7af87; +} +.ap-terminal .fg-181 { + --fg: #d7afaf; +} +.ap-terminal .bg-181 { + --bg: #d7afaf; +} +.ap-terminal .fg-182 { + --fg: #d7afd7; +} +.ap-terminal .bg-182 { + --bg: #d7afd7; +} +.ap-terminal .fg-183 { + --fg: #d7afff; +} +.ap-terminal .bg-183 { + --bg: #d7afff; +} +.ap-terminal .fg-184 { + --fg: #d7d700; +} +.ap-terminal .bg-184 { + --bg: #d7d700; +} +.ap-terminal .fg-185 { + --fg: #d7d75f; +} +.ap-terminal .bg-185 { + --bg: #d7d75f; +} +.ap-terminal .fg-186 { + --fg: #d7d787; +} +.ap-terminal .bg-186 { + --bg: #d7d787; +} +.ap-terminal .fg-187 { + --fg: #d7d7af; +} +.ap-terminal .bg-187 { + --bg: #d7d7af; +} +.ap-terminal .fg-188 { + --fg: #d7d7d7; +} +.ap-terminal .bg-188 { + --bg: #d7d7d7; +} +.ap-terminal .fg-189 { + --fg: #d7d7ff; +} +.ap-terminal .bg-189 { + --bg: #d7d7ff; +} +.ap-terminal .fg-190 { + --fg: #d7ff00; +} +.ap-terminal .bg-190 { + --bg: #d7ff00; +} +.ap-terminal .fg-191 { + --fg: #d7ff5f; +} +.ap-terminal .bg-191 { + --bg: #d7ff5f; +} +.ap-terminal .fg-192 { + --fg: #d7ff87; +} +.ap-terminal .bg-192 { + --bg: #d7ff87; +} +.ap-terminal .fg-193 { + --fg: #d7ffaf; +} +.ap-terminal .bg-193 { + --bg: #d7ffaf; +} +.ap-terminal .fg-194 { + --fg: #d7ffd7; +} +.ap-terminal .bg-194 { + --bg: #d7ffd7; +} +.ap-terminal .fg-195 { + --fg: #d7ffff; +} +.ap-terminal .bg-195 { + --bg: #d7ffff; +} +.ap-terminal .fg-196 { + --fg: #ff0000; +} +.ap-terminal .bg-196 { + --bg: #ff0000; +} +.ap-terminal .fg-197 { + --fg: #ff005f; +} +.ap-terminal .bg-197 { + --bg: #ff005f; +} +.ap-terminal .fg-198 { + --fg: #ff0087; +} +.ap-terminal .bg-198 { + --bg: #ff0087; +} +.ap-terminal .fg-199 { + --fg: #ff00af; +} +.ap-terminal .bg-199 { + --bg: #ff00af; +} +.ap-terminal .fg-200 { + --fg: #ff00d7; +} +.ap-terminal .bg-200 { + --bg: #ff00d7; +} +.ap-terminal .fg-201 { + --fg: #ff00ff; +} +.ap-terminal .bg-201 { + --bg: #ff00ff; +} +.ap-terminal .fg-202 { + --fg: #ff5f00; +} +.ap-terminal .bg-202 { + --bg: #ff5f00; +} +.ap-terminal .fg-203 { + --fg: #ff5f5f; +} +.ap-terminal .bg-203 { + --bg: #ff5f5f; +} +.ap-terminal .fg-204 { + --fg: #ff5f87; +} +.ap-terminal .bg-204 { + --bg: #ff5f87; +} +.ap-terminal .fg-205 { + --fg: #ff5faf; +} +.ap-terminal .bg-205 { + --bg: #ff5faf; +} +.ap-terminal .fg-206 { + --fg: #ff5fd7; +} +.ap-terminal .bg-206 { + --bg: #ff5fd7; +} +.ap-terminal .fg-207 { + --fg: #ff5fff; +} +.ap-terminal .bg-207 { + --bg: #ff5fff; +} +.ap-terminal .fg-208 { + --fg: #ff8700; +} +.ap-terminal .bg-208 { + --bg: #ff8700; +} +.ap-terminal .fg-209 { + --fg: #ff875f; +} +.ap-terminal .bg-209 { + --bg: #ff875f; +} +.ap-terminal .fg-210 { + --fg: #ff8787; +} +.ap-terminal .bg-210 { + --bg: #ff8787; +} +.ap-terminal .fg-211 { + --fg: #ff87af; +} +.ap-terminal .bg-211 { + --bg: #ff87af; +} +.ap-terminal .fg-212 { + --fg: #ff87d7; +} +.ap-terminal .bg-212 { + --bg: #ff87d7; +} +.ap-terminal .fg-213 { + --fg: #ff87ff; +} +.ap-terminal .bg-213 { + --bg: #ff87ff; +} +.ap-terminal .fg-214 { + --fg: #ffaf00; +} +.ap-terminal .bg-214 { + --bg: #ffaf00; +} +.ap-terminal .fg-215 { + --fg: #ffaf5f; +} +.ap-terminal .bg-215 { + --bg: #ffaf5f; +} +.ap-terminal .fg-216 { + --fg: #ffaf87; +} +.ap-terminal .bg-216 { + --bg: #ffaf87; +} +.ap-terminal .fg-217 { + --fg: #ffafaf; +} +.ap-terminal .bg-217 { + --bg: #ffafaf; +} +.ap-terminal .fg-218 { + --fg: #ffafd7; +} +.ap-terminal .bg-218 { + --bg: #ffafd7; +} +.ap-terminal .fg-219 { + --fg: #ffafff; +} +.ap-terminal .bg-219 { + --bg: #ffafff; +} +.ap-terminal .fg-220 { + --fg: #ffd700; +} +.ap-terminal .bg-220 { + --bg: #ffd700; +} +.ap-terminal .fg-221 { + --fg: #ffd75f; +} +.ap-terminal .bg-221 { + --bg: #ffd75f; +} +.ap-terminal .fg-222 { + --fg: #ffd787; +} +.ap-terminal .bg-222 { + --bg: #ffd787; +} +.ap-terminal .fg-223 { + --fg: #ffd7af; +} +.ap-terminal .bg-223 { + --bg: #ffd7af; +} +.ap-terminal .fg-224 { + --fg: #ffd7d7; +} +.ap-terminal .bg-224 { + --bg: #ffd7d7; +} +.ap-terminal .fg-225 { + --fg: #ffd7ff; +} +.ap-terminal .bg-225 { + --bg: #ffd7ff; +} +.ap-terminal .fg-226 { + --fg: #ffff00; +} +.ap-terminal .bg-226 { + --bg: #ffff00; +} +.ap-terminal .fg-227 { + --fg: #ffff5f; +} +.ap-terminal .bg-227 { + --bg: #ffff5f; +} +.ap-terminal .fg-228 { + --fg: #ffff87; +} +.ap-terminal .bg-228 { + --bg: #ffff87; +} +.ap-terminal .fg-229 { + --fg: #ffffaf; +} +.ap-terminal .bg-229 { + --bg: #ffffaf; +} +.ap-terminal .fg-230 { + --fg: #ffffd7; +} +.ap-terminal .bg-230 { + --bg: #ffffd7; +} +.ap-terminal .fg-231 { + --fg: #ffffff; +} +.ap-terminal .bg-231 { + --bg: #ffffff; +} +.ap-terminal .fg-232 { + --fg: #080808; +} +.ap-terminal .bg-232 { + --bg: #080808; +} +.ap-terminal .fg-233 { + --fg: #121212; +} +.ap-terminal .bg-233 { + --bg: #121212; +} +.ap-terminal .fg-234 { + --fg: #1c1c1c; +} +.ap-terminal .bg-234 { + --bg: #1c1c1c; +} +.ap-terminal .fg-235 { + --fg: #262626; +} +.ap-terminal .bg-235 { + --bg: #262626; +} +.ap-terminal .fg-236 { + --fg: #303030; +} +.ap-terminal .bg-236 { + --bg: #303030; +} +.ap-terminal .fg-237 { + --fg: #3a3a3a; +} +.ap-terminal .bg-237 { + --bg: #3a3a3a; +} +.ap-terminal .fg-238 { + --fg: #444444; +} +.ap-terminal .bg-238 { + --bg: #444444; +} +.ap-terminal .fg-239 { + --fg: #4e4e4e; +} +.ap-terminal .bg-239 { + --bg: #4e4e4e; +} +.ap-terminal .fg-240 { + --fg: #585858; +} +.ap-terminal .bg-240 { + --bg: #585858; +} +.ap-terminal .fg-241 { + --fg: #626262; +} +.ap-terminal .bg-241 { + --bg: #626262; +} +.ap-terminal .fg-242 { + --fg: #6c6c6c; +} +.ap-terminal .bg-242 { + --bg: #6c6c6c; +} +.ap-terminal .fg-243 { + --fg: #767676; +} +.ap-terminal .bg-243 { + --bg: #767676; +} +.ap-terminal .fg-244 { + --fg: #808080; +} +.ap-terminal .bg-244 { + --bg: #808080; +} +.ap-terminal .fg-245 { + --fg: #8a8a8a; +} +.ap-terminal .bg-245 { + --bg: #8a8a8a; +} +.ap-terminal .fg-246 { + --fg: #949494; +} +.ap-terminal .bg-246 { + --bg: #949494; +} +.ap-terminal .fg-247 { + --fg: #9e9e9e; +} +.ap-terminal .bg-247 { + --bg: #9e9e9e; +} +.ap-terminal .fg-248 { + --fg: #a8a8a8; +} +.ap-terminal .bg-248 { + --bg: #a8a8a8; +} +.ap-terminal .fg-249 { + --fg: #b2b2b2; +} +.ap-terminal .bg-249 { + --bg: #b2b2b2; +} +.ap-terminal .fg-250 { + --fg: #bcbcbc; +} +.ap-terminal .bg-250 { + --bg: #bcbcbc; +} +.ap-terminal .fg-251 { + --fg: #c6c6c6; +} +.ap-terminal .bg-251 { + --bg: #c6c6c6; +} +.ap-terminal .fg-252 { + --fg: #d0d0d0; +} +.ap-terminal .bg-252 { + --bg: #d0d0d0; +} +.ap-terminal .fg-253 { + --fg: #dadada; +} +.ap-terminal .bg-253 { + --bg: #dadada; +} +.ap-terminal .fg-254 { + --fg: #e4e4e4; +} +.ap-terminal .bg-254 { + --bg: #e4e4e4; +} +.ap-terminal .fg-255 { + --fg: #eeeeee; +} +.ap-terminal .bg-255 { + --bg: #eeeeee; +} +.asciinema-player-theme-asciinema { + --term-color-foreground: #cccccc; + --term-color-background: #121314; + --term-color-0: hsl(0, 0%, 0%); + --term-color-1: hsl(343, 70%, 55%); + --term-color-2: hsl(103, 70%, 44%); + --term-color-3: hsl(43, 70%, 55%); + --term-color-4: hsl(193, 70%, 49.5%); + --term-color-5: hsl(283, 70%, 60.5%); + --term-color-6: hsl(163, 70%, 60.5%); + --term-color-7: hsl(0, 0%, 85%); + --term-color-8: hsl(0, 0%, 30%); + --term-color-9: hsl(343, 70%, 55%); + --term-color-10: hsl(103, 70%, 44%); + --term-color-11: hsl(43, 70%, 55%); + --term-color-12: hsl(193, 70%, 49.5%); + --term-color-13: hsl(283, 70%, 60.5%); + --term-color-14: hsl(163, 70%, 60.5%); + --term-color-15: hsl(0, 0%, 100%); +} +/* + Based on Dracula: https://draculatheme.com + */ +.asciinema-player-theme-dracula { + --term-color-foreground: #f8f8f2; + --term-color-background: #282a36; + --term-color-0: #21222c; + --term-color-1: #ff5555; + --term-color-2: #50fa7b; + --term-color-3: #f1fa8c; + --term-color-4: #bd93f9; + --term-color-5: #ff79c6; + --term-color-6: #8be9fd; + --term-color-7: #f8f8f2; + --term-color-8: #6272a4; + --term-color-9: #ff6e6e; + --term-color-10: #69ff94; + --term-color-11: #ffffa5; + --term-color-12: #d6acff; + --term-color-13: #ff92df; + --term-color-14: #a4ffff; + --term-color-15: #ffffff; +} +/* Based on Monokai from base16 collection - https://github.com/chriskempson/base16 */ +.asciinema-player-theme-monokai { + --term-color-foreground: #f8f8f2; + --term-color-background: #272822; + --term-color-0: #272822; + --term-color-1: #f92672; + --term-color-2: #a6e22e; + --term-color-3: #f4bf75; + --term-color-4: #66d9ef; + --term-color-5: #ae81ff; + --term-color-6: #a1efe4; + --term-color-7: #f8f8f2; + --term-color-8: #75715e; + --term-color-15: #f9f8f5; +} +/* + Based on Nord: https://github.com/arcticicestudio/nord + Via: https://github.com/neilotoole/asciinema-theme-nord + */ +.asciinema-player-theme-nord { + --term-color-foreground: #eceff4; + --term-color-background: #2e3440; + --term-color-0: #3b4252; + --term-color-1: #bf616a; + --term-color-2: #a3be8c; + --term-color-3: #ebcb8b; + --term-color-4: #81a1c1; + --term-color-5: #b48ead; + --term-color-6: #88c0d0; + --term-color-7: #eceff4; +} +.asciinema-player-theme-seti { + --term-color-foreground: #cacecd; + --term-color-background: #111213; + --term-color-0: #323232; + --term-color-1: #c22832; + --term-color-2: #8ec43d; + --term-color-3: #e0c64f; + --term-color-4: #43a5d5; + --term-color-5: #8b57b5; + --term-color-6: #8ec43d; + --term-color-7: #eeeeee; + --term-color-15: #ffffff; +} +/* + Based on Solarized Dark: https://ethanschoonover.com/solarized/ + */ +.asciinema-player-theme-solarized-dark { + --term-color-foreground: #839496; + --term-color-background: #002b36; + --term-color-0: #073642; + --term-color-1: #dc322f; + --term-color-2: #859900; + --term-color-3: #b58900; + --term-color-4: #268bd2; + --term-color-5: #d33682; + --term-color-6: #2aa198; + --term-color-7: #eee8d5; + --term-color-8: #002b36; + --term-color-9: #cb4b16; + --term-color-10: #586e75; + --term-color-11: #657b83; + --term-color-12: #839496; + --term-color-13: #6c71c4; + --term-color-14: #93a1a1; + --term-color-15: #fdf6e3; +} +/* + Based on Solarized Light: https://ethanschoonover.com/solarized/ + */ +.asciinema-player-theme-solarized-light { + --term-color-foreground: #657b83; + --term-color-background: #fdf6e3; + --term-color-0: #073642; + --term-color-1: #dc322f; + --term-color-2: #859900; + --term-color-3: #b58900; + --term-color-4: #268bd2; + --term-color-5: #d33682; + --term-color-6: #2aa198; + --term-color-7: #eee8d5; + --term-color-8: #002b36; + --term-color-9: #cb4b16; + --term-color-10: #586e75; + --term-color-11: #657c83; + --term-color-12: #839496; + --term-color-13: #6c71c4; + --term-color-14: #93a1a1; + --term-color-15: #fdf6e3; +} +.asciinema-player-theme-solarized-light .ap-overlay-start .ap-play-button svg .ap-play-btn-fill { + fill: var(--term-color-1); +} +.asciinema-player-theme-solarized-light .ap-overlay-start .ap-play-button svg .ap-play-btn-stroke { + stroke: var(--term-color-1); +} +/* + Based on Tango: https://en.wikipedia.org/wiki/Tango_Desktop_Project + */ +.asciinema-player-theme-tango { + --term-color-foreground: #cccccc; + --term-color-background: #121314; + --term-color-0: #000000; + --term-color-1: #cc0000; + --term-color-2: #4e9a06; + --term-color-3: #c4a000; + --term-color-4: #3465a4; + --term-color-5: #75507b; + --term-color-6: #06989a; + --term-color-7: #d3d7cf; + --term-color-8: #555753; + --term-color-9: #ef2929; + --term-color-10: #8ae234; + --term-color-11: #fce94f; + --term-color-12: #729fcf; + --term-color-13: #ad7fa8; + --term-color-14: #34e2e2; + --term-color-15: #eeeeec; +} diff --git a/aider/website/assets/asciinema/asciinema-player.min.js b/aider/website/assets/asciinema/asciinema-player.min.js new file mode 100644 index 000000000..d90e64c82 --- /dev/null +++ b/aider/website/assets/asciinema/asciinema-player.min.js @@ -0,0 +1 @@ +var AsciinemaPlayer=function(A){"use strict";function g(A){return"number"==typeof A?A:"string"==typeof A?A.split(":").reverse().map(parseFloat).reduce(((A,g,I)=>A+g*Math.pow(60,I))):void 0}class I{log(){}debug(){}info(){}warn(){}error(){}}class B{constructor(A,g){this.logger=A,this.prefix=g}log(A){for(var g=arguments.length,I=new Array(g>1?g-1:0),B=1;B1?g-1:0),B=1;B1?g-1:0),B=1;B1?g-1:0),B=1;B1?g-1:0),B=1;B{throw Error("TextDecoder not available")}};"undefined"!=typeof TextDecoder&&i.decode();let t=null;function o(){return null!==t&&0!==t.byteLength||(t=new Uint8Array(Q.memory.buffer)),t}function s(A,g){return A>>>=0,i.decode(o().subarray(A,A+g))}function n(A){V===C.length&&C.push(C.length+1);const g=V;return V=C[g],C[g]=A,g}function r(A){const g=typeof A;if("number"==g||"boolean"==g||null==A)return`${A}`;if("string"==g)return`"${A}"`;if("symbol"==g){const g=A.description;return null==g?"Symbol":`Symbol(${g})`}if("function"==g){const g=A.name;return"string"==typeof g&&g.length>0?`Function(${g})`:"Function"}if(Array.isArray(A)){const g=A.length;let I="[";g>0&&(I+=r(A[0]));for(let B=1;B1))return toString.call(A);if(B=I[1],"Object"==B)try{return"Object("+JSON.stringify(A)+")"}catch(A){return"Object"}return A instanceof Error?`${A.name}: ${A.message}\n${A.stack}`:B}let a=0;const c="undefined"!=typeof TextEncoder?new TextEncoder("utf-8"):{encode:()=>{throw Error("TextEncoder not available")}},D="function"==typeof c.encodeInto?function(A,g){return c.encodeInto(A,g)}:function(A,g){const I=c.encode(A);return g.set(I),{read:A.length,written:I.length}};function w(A,g,I){if(void 0===I){const I=c.encode(A),B=g(I.length,1)>>>0;return o().subarray(B,B+I.length).set(I),a=I.length,B}let B=A.length,Q=g(B,1)>>>0;const C=o();let E=0;for(;E127)break;C[Q+E]=g}if(E!==B){0!==E&&(A=A.slice(E)),Q=I(Q,B,B=E+3*A.length,1)>>>0;const g=o().subarray(Q+E,Q+B);E+=D(A,g).written,Q=I(Q,B,E,1)>>>0}return a=E,Q}let h=null;function l(){return null!==h&&0!==h.byteLength||(h=new Int32Array(Q.memory.buffer)),h}let y=null;function k(A,g){return A>>>=0,(null!==y&&0!==y.byteLength||(y=new Uint32Array(Q.memory.buffer)),y).subarray(A/4,A/4+g)}const G="undefined"==typeof FinalizationRegistry?{register:()=>{},unregister:()=>{}}:new FinalizationRegistry((A=>Q.__wbg_vt_free(A>>>0)));class F{static __wrap(A){A>>>=0;const g=Object.create(F.prototype);return g.__wbg_ptr=A,G.register(g,g.__wbg_ptr,g),g}__destroy_into_raw(){const A=this.__wbg_ptr;return this.__wbg_ptr=0,G.unregister(this),A}free(){const A=this.__destroy_into_raw();Q.__wbg_vt_free(A)}feed(A){const g=w(A,Q.__wbindgen_malloc,Q.__wbindgen_realloc),I=a;return e(Q.vt_feed(this.__wbg_ptr,g,I))}resize(A,g){return e(Q.vt_resize(this.__wbg_ptr,A,g))}inspect(){let A,g;try{const C=Q.__wbindgen_add_to_stack_pointer(-16);Q.vt_inspect(C,this.__wbg_ptr);var I=l()[C/4+0],B=l()[C/4+1];return A=I,g=B,s(I,B)}finally{Q.__wbindgen_add_to_stack_pointer(16),Q.__wbindgen_free(A,g,1)}}getSize(){try{const B=Q.__wbindgen_add_to_stack_pointer(-16);Q.vt_getSize(B,this.__wbg_ptr);var A=l()[B/4+0],g=l()[B/4+1],I=k(A,g).slice();return Q.__wbindgen_free(A,4*g,4),I}finally{Q.__wbindgen_add_to_stack_pointer(16)}}getLine(A){return e(Q.vt_getLine(this.__wbg_ptr,A))}getCursor(){return e(Q.vt_getCursor(this.__wbg_ptr))}}function q(){const A={wbg:{}};return A.wbg.__wbindgen_object_drop_ref=function(A){e(A)},A.wbg.__wbindgen_error_new=function(A,g){return n(new Error(s(A,g)))},A.wbg.__wbindgen_object_clone_ref=function(A){return n(E(A))},A.wbg.__wbindgen_number_new=function(A){return n(A)},A.wbg.__wbindgen_bigint_from_u64=function(A){return n(BigInt.asUintN(64,A))},A.wbg.__wbindgen_string_new=function(A,g){return n(s(A,g))},A.wbg.__wbg_set_f975102236d3c502=function(A,g,I){E(A)[e(g)]=e(I)},A.wbg.__wbg_new_b525de17f44a8943=function(){return n(new Array)},A.wbg.__wbg_new_f841cc6f2098f4b5=function(){return n(new Map)},A.wbg.__wbg_new_f9876326328f45ed=function(){return n(new Object)},A.wbg.__wbindgen_is_string=function(A){return"string"==typeof E(A)},A.wbg.__wbg_set_17224bc548dd1d7b=function(A,g,I){E(A)[g>>>0]=e(I)},A.wbg.__wbg_set_388c4c6422704173=function(A,g,I){return n(E(A).set(E(g),E(I)))},A.wbg.__wbindgen_debug_string=function(A,g){const I=w(r(E(g)),Q.__wbindgen_malloc,Q.__wbindgen_realloc),B=a;l()[A/4+1]=B,l()[A/4+0]=I},A.wbg.__wbindgen_throw=function(A,g){throw new Error(s(A,g))},A}function d(A,g){return Q=A.exports,N.__wbindgen_wasm_module=g,h=null,y=null,t=null,Q}async function N(A){if(void 0!==Q)return Q;const g=q();("string"==typeof A||"function"==typeof Request&&A instanceof Request||"function"==typeof URL&&A instanceof URL)&&(A=fetch(A));const{instance:I,module:B}=await async function(A,g){if("function"==typeof Response&&A instanceof Response){if("function"==typeof WebAssembly.instantiateStreaming)try{return await WebAssembly.instantiateStreaming(A,g)}catch(g){if("application/wasm"==A.headers.get("Content-Type"))throw g;console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n",g)}const I=await A.arrayBuffer();return await WebAssembly.instantiate(I,g)}{const I=await WebAssembly.instantiate(A,g);return I instanceof WebAssembly.Instance?{instance:I,module:A}:I}}(await A,g);return d(I,B)}var M=Object.freeze({__proto__:null,Vt:F,create:function(A,g,I){const B=Q.create(A,g,I);return F.__wrap(B)},default:N,initSync:function(A){if(void 0!==Q)return Q;const g=q();return A instanceof WebAssembly.Module||(A=new WebAssembly.Module(A)),d(new WebAssembly.Instance(A,g),A)}});const u=[62,0,0,0,63,52,53,54,55,56,57,58,59,60,61,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,0,0,0,0,0,0,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51];function f(A){return u[A-43]}const R=function(A){let g,I=A.endsWith("==")?2:A.endsWith("=")?1:0,B=A.length,Q=new Uint8Array(B/4*3);for(let I=0,C=0;I>16,Q[C+1]=g>>8&255,Q[C+2]=255&g;return Q.subarray(0,Q.length-I)}("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QQhrIgAgA08NAQwDCyAHQQhrIQALA0AgBkEEaigCACIJQYqUqNAAc0GBgoQIayAJQX9zcSAGKAIAIglBipSo0ABzQYGChAhrIAlBf3NxckGAgYKEeHENAiAGQQhqIQYgACADQQhqIgNPDQALDAELIAIgBEYEQCACIQQMBAtBACEAA0AgACAFai0AAEEKRg0CIAcgAEEBaiIARw0ACyACIQQMAwsgAyAHRgRAIAIhBAwDCwNAIAMgBWotAABBCkYEQCADIQAMAgsgByADQQFqIgNHDQALIAIhBAwCCyAAIARqIgZBAWohBAJAIAIgBk0NACAAIAVqLQAAQQpHDQBBACEFIAQiBiEADAMLIAIgBE8NAAsLQQEhBSACIgAgCCIGRw0AQQAPCwJAIAwtAABFDQAgC0H49MAAQQQgCigCDBEBAEUNAEEBDwsgACAIayEHQQAhAyAAIAhHBEAgACANai0AAEEKRiEDCyABIAhqIQAgDCADOgAAIAYhCCALIAAgByAKKAIMEQEAIgAgBXJFDQALIAAL0gYBBX8jAEHAAWsiAiQAIAAoAgAhAyACQbgBakGojMAANgIAIAJBBGoiAEGsAWpBxJDAADYCACAAQaQBakG0kMAANgIAIABBnAFqQbSQwAA2AgAgAkGYAWpBmI7AADYCACACQZABakGYjsAANgIAIAJBiAFqQaSPwAA2AgAgAkGAAWpBpJDAADYCACAAQfQAakGkj8AANgIAIAJB8ABqQaSPwAA2AgAgAkHoAGpBpI/AADYCACAAQdwAakGkj8AANgIAIAJB2ABqQZSQwAA2AgAgAkHQAGpBmI7AADYCACACQcgAakGEkMAANgIAIAJBQGtBiI/AADYCACACQThqQfSPwAA2AgAgAkEwakHkj8AANgIAIABBJGpB1I/AADYCACACQSBqQcSPwAA2AgAgAkEYakHEj8AANgIAIAJBEGpBmI7AADYCACACIANB3ABqNgKsASACIANBiAFqNgKkASACIANB9ABqNgKcASACIANBrAFqNgKUASACIANBqAFqNgKMASACIANBwgFqNgKEASACIANBwQFqNgJ8IAIgA0HAAWo2AnQgAiADQb8BajYCbCACIANBvgFqNgJkIAIgA0G9AWo2AlwgAiADQdAAajYCVCACIANBpAFqNgJMIAIgA0GwAWo2AkQgAiADQbIB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amohAiADQSBqIQMgCCAHQQRqIgdHDQALCyAGBEAgB0EDdCAFakEEaiEDA0AgAygCACACaiECIANBCGohAyAGQQFrIgYNAAsLIAEoAgwEQCACQQBIDQEgBSgCBEUgAkEQSXENASACQQF0IQILIAINAQtBASEDQQAhAgwBCyACQQBIDQFBqYzBAC0AABogAkEBENcBIgNFDQILIARBADYCCCAEIAM2AgQgBCACNgIAIARBhO/AACABEBhFDQJB5O/AAEEzIARBD2pBmPDAAEHA8MAAEF0ACxCpAQALQQEgAkHkjMEAKAIAIgBB5AAgABsRAgAACyAAIAQpAgA3AgAgAEEIaiAEQQhqKAIANgIAIARBEGokAAvVAgEHf0EBIQkCQAJAIAJFDQAgASACQQF0aiEKIABBgP4DcUEIdiELIABB/wFxIQ0DQCABQQJqIQwgByABLQABIgJqIQggCyABLQAAIgFHBEAgASALSw0CIAghByAKIAwiAUYNAgwBCwJAAkAgByAITQRAIAQgCEkNASADIAdqIQEDQCACRQ0DIAJBAWshAiABLQAAIAFBAWohASANRw0AC0EAIQkMBQsgByAIQbj5wAAQ7AEACyAIIARBuPnAABDqAQALIAghByAKIAwiAUcNAAsLIAZFDQAgBSAGaiEDIABB//8DcSEBA0AgBUEBaiEAAkAgBS0AACICwCIEQQBOBEAgACEFDAELIAAgA0cEQCAFLQABIARB/wBxQQh0ciECIAVBAmohBQwBC0Go+cAAEO4BAAsgASACayIBQQBIDQEgCUEBcyEJIAMgBUcNAAsLIAlBAXEL8wIBBH8gACgCDCECAkACQCABQYACTwRAIAAoAhghAwJAAkAgACACRgRAIABBFEEQIAAoAhQiAhtqKAIAIgENAUEAIQIMAgsgACgCCCIBIAI2AgwgAiABNgIIDAELIABBFGogAEEQaiACGyEEA0AgBCEFIAEiAigCFCEBIAJBFGogAkEQaiABGyEEIAJBFEEQIAEbaigCACIBDQALIAVBADYCAAsgA0UNAiAAIAAoAhxBAnRB+IzBAGoiASgCAEcEQCADQRBBFCADKAIQIABGG2ogAjYCACACRQ0DDAILIAEgAjYCACACDQFBlJDBAEGUkMEAKAIAQX4gACgCHHdxNgIADAILIAIgACgCCCIARwRAIAAgAjYC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IhEoAgAhDyARIAwoAgA2AgAgDCAPNgIAIAVBBGoiBUEkRw0ACyALQQxqIAMoApwBIAMoAqABIgVBAUEAIANBsgFqECsgA0EMahCKASADKAIMIgwEQCADKAIQIAxBBHRBBBDkAQsgAyALQQxqQSQQiAJB3ABqQQAgBRB4CyALQTBqJAAgAxBCCyACQQJqIQIgB0ECayIHDQALCyANBEAgBCANQQF0QQIQ5AELDCALAkAgAi8BAiIEQQEgBEEBSxtBAWsiBCACLwEEIgIgAygCoAEiBSACG0EBayICSSACIAVJcUUEQCADKAKoASEEDAELIAMgAjYCrAEgAyAENgKoAQsgA0EAOgDCASADQQA2AmggAyAEQQAgAy0AvgEbNgJsDB8LIANBAToAcCADQQA7AL0BIANBADsBugEgA0ECOgC2ASADQQI6ALIBIANBADsBsAEgA0IANwKkASADQYCAgAg2AoQBIANBAjoAgAEgA0ECOgB8IANCADcCdCADIAMoAqABQQFrNgKsAQweCyADKAKgASADKAKsASIEQQFqIAQgAygCbCIESRshBSADIAQgBSACLwECIgJBASACQQFLGyADQbIBahAiIANB3ABqIAQgBRB4DB0LIAMgAygCaCADKAJsIgRBACACLwECIgJBASACQQFLGyADQbIBahAoIAQgAygCZCICTw0dIAMoAmAgBGpBAToAAAwcCwJAAkACQAJAIAItAAFBAWsOAwECAwALIAMgAygCaCADKAJsQQEgAyADQbIBahAoIANB3ABqIAMoAmwgAygCoAEQeAwCCyADIAMoAmggAygCbEECIAMgA0GyAWoQKCADQdwAakEAIAMoAmxBAWoQeAwBCyADQQAgAygCHCADQbIBahBLIANB3ABqQQAgAygCoAEQeAsMGwsgAyADKAJoIAMoAmwiBCACLQABQQRqIAMgA0GyAWoQKCAEIAMoAmQiAk8NGyADKAJgIARqQQE6AAAMGgsgAyACLQABOgCxAQwZCyADIAItAAE6ALABDBgLIAMoAlhBAnQhAiADKAJUIQUgAygCaCEHAkACQANAIAJFDQEgAkEEayECIAUoAgAhBCAFQQRqIQUgBCAHTQ0ACyADKAKcASICQQFrIQUMAQsgAygCnAEiAkEBayIFIQQLIANBADoAwgEgAyAEIAUgAiAESxs2AmgMFwsg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+gA2AiggACAAQSRqNgIUIAAgAEEvajYCJCAAQQxqQeCXwAAQpAEACyATQRBqJAAgAAvGAQECfyMAQRBrIgAkACABKAIUQbDswABBCyABKAIYKAIMEQEAIQMgAEEIaiICQQA6AAUgAiADOgAEIAIgATYCACACIgEtAAQhAwJAIAItAAVFBEAgA0EARyEBDAELQQEhAiADRQRAIAEoAgAiAi0AHEEEcUUEQCABIAIoAhRBh/XAAEECIAIoAhgoAgwRAQAiAToABAwCCyACKAIUQYb1wABBASACKAIYKAIMEQEAIQILIAEgAjoABCACIQELIABBEGokACABCzIBAX8gAEEQahAwAkAgACgCACIBQYCAgIB4Rg0AIAFFDQAgACgCBCABQQR0QQQQ5AELCy8BAn8gACAAKAKoASICIAAoAqwBQQFqIgMgASAAQbIBahBZIABB3ABqIAIgAxB4Cy8BAn8gACAAKAKoASICIAAoAqwBQQFqIgMgASAAQbIBahAiIABB3ABqIAIgAxB4CysAIAEgAkkEQEHcosAAQSNBzKPAABCcAQALIAIgACACQQR0aiABIAJrEBILJQAgAEEBNgIEIAAgASgCBCABKAIAa0EEdiIBNgIIIAAgATYCAAslACAARQRAQfCXwABBMhD7AQALIAAgAiADIAQgBSABKAIQEQgACzAAIAEoAhQgAC0AAEECdCIAQYyFwABqKAIAIABB1ITAAGooAgAgASgCGCgCDBEBAAswACABKAIUIAAtAABBAnQiAEGEi8AAaigCACAAQfiKwABqKAIAIAEoAhgoAgwRAQALMAAgASgCFCAALQAAQQJ0IgBB2JTAAGooAgAgAEHMlMAAaigCACABKAIYKAIMEQEACyMAIABFBEBB8JfAAEEyEPsBAAsgACACIAMgBCABKAIQEQUACyMAIABFBEBB8JfAAEEyEPsBAAsgACACIAMgBCABKAIQERgACyMAIABFBEBB8JfAAEEyEPsBAAsgACACIAMgBCABKAIQERoACyMAIABFBEBB8JfAAEEyEPsBAAsgACACIAMgBCABKAIQERwACyMAIABFBEBB8JfAAEEyEPsBAAsgACACIAMgBCABKAIQEQwACygBAX8gACgCACIBQYCAgIB4ckGAgICAeEcEQCAAKAIEIAFBARDkAQsLLgAgASgCFEH8icAAQfeJ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iPjAADYCCCADQgI3AhQgA0HjADYCJCADIANBIGo2AhAgAyADQQRqNgIoIAMgAzYCICADQQhqIAIQpAEACwsAIAA1AgAgARAkC2wBAX8jAEEwayIDJAAgAyABNgIEIAMgADYCACADQSxqQeMANgIAIANBAjYCDCADQbz4wAA2AgggA0ICNwIUIANB4wA2AiQgAyADQSBqNgIQIAMgA0EEajYCKCADIAM2AiAgA0EIaiACEKQBAAsLACAAMQAAIAEQJAsPAEGt8sAAQSsgABCcAQALCwAgACkDACABECQLCwAgACMAaiQAIwALDAAgACgCACABEMMBCwsAIAAoAgAgARAnCwcAIAAQyQELBwAgABDBAQsZACABKAIUQcyHwABBBSABKAIYKAIMEQEAC5cBAQF/IAAoAgAhAiMAQUBqIgAkACAAQgA3AzggAEE4aiACKAIAEA0gACAAKAI8IgI2AjQgACAAKAI4NgIwIAAgAjYCLCAAQd8ANgIoIABBAjYCECAAQcznwAA2AgwgAEIBNwIYIAAgAEEsaiICNgIkIAAgAEEkajYCFCABKAIUIAEoAhggAEEMahAYIAIQyQEgAEFAayQAC6IBAQR/QQIhAyMAQRBrIgIkACABKAIUQazywABBASABKAIYKAIMEQEAIQUgAkEEaiIEQQA6AAUgBCAFOgAEIAQgATYCAANAIAIgADYCDCACQQRqIAJBDGpByIzAABAsIABBAWohACADQQFrIgMNAAsgAkEEaiIALQAEBH9BAQUgACgCACIAKAIUQY71wABBASAAKAIYKAIMEQEACyACQRBqJAALowEBA38jAEEQayICJAAgASgCFEGs8sAAQQEgASgCGCgCDBEBACEEIAJBBGoiA0EAOgAFIAMgBDoABCADIAE2AgBBgAQhAQNAIAIgADYCDCACQQRqIAJBDGpBuIzAABAsIABBEGohACABQRBrIgENAAsgAkEEaiIALQAEBH9BAQUgACgCACIAKAIUQY71wABBASAAKAIYKAIMEQEACyACQRBqJAALBwAgABDCAQsMACAAEIoBIAAQwQELCQAgACABEA4ACw0AQeTowABBGxD7AQALDgBB/+jAAEHPABD7AQALDQAgAEHY6sAAIAEQGAsNACAAQfDqwAAgARAYCw0AIABBhO/AACABEBgLGQAgASgCFEH87sAAQQUgASgCGCgCDBEBAAuGBAEFfyMAQRBrIgMkAAJAAn8CQCABQYABTwRAIANBADYCDCABQYAQSQ0BIAFBgIAESQRAIAMgAUE/cUGAAXI6AA4gAyABQQx2QeABcjoADCADIAFBBnZBP3FBgAFyOgANQQMMAwsgAyABQT9xQYABcjoADyADIAFBBnZBP3FBgAFyOgAOIAMgAUEMdkE/cUGAAXI6AA0gAyABQRJ2QQdxQfABcjoADEEEDAILIAAoAggiAiAAKAIARgRAIwBBIGsiBCQAAkACQCACQQFqIgJFDQAgACgCACIFQQF0IgYgAiACIAZJGyICQQggAkEISxsiAkF/c0EfdiEGIAQgBQR/IAQgBTYCHCAEIAAoAgQ2AhRBAQVBAAs2AhggBEEIaiAGIAIgBEEUahBEIAQoAggEQCAEKAIMIgBFDQEgACAEKAIQQeSMwQAoAgAiAEHkACAAGxECAAALIAQoAgwhBSAAIAI2AgAgACAFNgIEIARBIGokAAwBCxCpAQALIAAoAgghAgsgACACQQFqNgIIIAAoAgQgAmogAToAAAwCCyADIAFBP3FBgAFyOgANIAMgAUEGdkHAAXI6AAxBAgshASABIAAoAgAgACgCCCICa0sEQCAAIAIgARA+IAAoAgghAgsgACgCBCACaiADQQxqIAEQiAIaIAAgASACajYCCAsgA0EQaiQAQQALDQAgAEHg9MAAIAEQGAsKACACIAAgARATC8ECAQN/IAAoAgAhACMAQYABayIEJAACfwJAAkAgASgCHCICQRBxRQRAIAJBIHENASAANQIAIAEQJAwDCyAAKAIAIQJBACEAA0AgACAEakH/AGogAkEPcSIDQTByIANB1wBqIANBCkkbOgAAIABBAWshACACQRBJIAJBBHYhAkUNAAsMAQsgACgCACECQQAhAANAIAAgBGpB/wBqIAJBD3EiA0EwciADQTdqIANBCkkbOgAAIABBAWshACACQRBJIAJBBHYhAkUNAAsgAEGAAWoiAkGBAU8EQCACQYABQaz1wAAQ6QEACyABQbz1wABBAiAAIARqQYABakEAIABrEBUMAQsgAEGAAWoiAkGBAU8EQCACQYABQaz1wAAQ6QEACyABQbz1wABBAiAAIARqQYABakEAIABrEBULIARBgAFqJAALkQUBB38CQAJ/AkAgAiIEIAAgAWtL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AIYIEAAIAAAAjggQAA4AAACcCBAABAAAAKAIEAALAAAAmAcQAAsAAAC0BxAADgAAAKsIEAANAAAAuAgQABAAAADICBAAEAAAANgIEAAKAAAA4ggQAA0AAADvCBAACQAAAPgIEAATAAAACwkQAAsAAAAWCRAACAAAAFByaW1hcnlBbHRlcm5hdGVBcHBsaWNhdGlvbkN1cnNvcmNvbHJvd3Zpc2libGVOb25lU29tZQAAJwAAAAQAAAAEAAAAJgAAACcAAAAEAAAABAAAAEMAAABEaXJ0eUxpbmVzAAAnAAAABAAAAAQAAABEAAAABgAAAAQAAAAFAAAAVwcQAF0HEABhBxAAY2Fubm90IGFjY2VzcyBhIFRocmVhZCBMb2NhbCBTdG9yYWdlIHZhbHVlIGR1cmluZyBvciBhZnRlciBkZXN0cnVjdGlvbgAARgAAAAAAAAABAAAARwAAAC9ydXN0Yy85YjAwOTU2ZTU2MDA5YmFiMmFhMTVkN2JmZjEwOTE2NTk5ZTNkNmQ2L2xpYnJhcnkvc3RkL3NyYy90aHJlYWQvbG9jYWwucnMAvAoQAE8AAAAEAQAAGgAAAAAAAAD//////////yALEABBuJbAAAvZFiBjYW4ndCBiZSByZXByZXNlbnRlZCBhcyBhIEphdmFTY3JpcHQgbnVtYmVyHAsQAAAAAAA4CxAALAAAAEgAAAAvaG9tZS9tYXJjaW4vLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tNmYxN2QyMmJiYTE1MDAxZi9zZXJkZS13YXNtLWJpbmRnZW4tMC42LjUvc3JjL2xpYi5ycwAAAHgLEABlAAAANQAAAA4AAABjbG9zdXJlIGludm9rZWQgcmVjdXJzaXZlbHkgb3IgYWZ0ZXIgYmVpbmcgZHJvcHBlZC9ydXN0Yy85YjAwOTU2ZTU2MDA5YmFiMmFhMTVkN2JmZjEwOTE2NTk5ZTNkNmQ2L2xpYnJhcnkvYWxsb2Mvc3JjL3ZlYy9tb2QucnMAACIMEABMAAAAYAgAACQAAAAiDBAATAAAABoGAAAVAAAAL2hvbWUvbWFyY2luLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTZmMTdkMjJiYmExNTAwMWYvYXZ0LTAuMTUuMC9zcmMvcGFyc2Vy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Ai8wMTIzAgICAgICNAICNTY3Ajg5Ojs8PT4/OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5QDk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTlBAgJCQwICREVGR0hJAko5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTlLAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICOTk5OUwCAgICAk1OT1ACAgJRAlJTAgICAgICAgICAgICAlRVAgJWAlcCAlhZWltcXV5fYGECYmMCZGVmZwJoAmlqa2wCAm1ub3ACcXICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnMCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ0dQICAgICAgJ2dzk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5eDk5OTk5OTk5OXl6AgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ7OTl8OTl9AgICAgICAgICAgICAgICAgICAn4CAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ/AgICgIGCAgICAgICAgICAgICAgICg4QCAgICAgICAgIChYZ1AgKHAgICiAICAgICAgKJigICAgICAgICAgICAgKLjAKNjgKPkJGSk5SVlgKXAgKYmZqbAgICAgICAgICAjk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OZwdHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHR0dHQICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAJ0CAgICnp8CBAIFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdAgIeAgICAgICAh8gISIjAiQlJicoKQIqAgICAqChoqOkpaYup6ipqqusrTMCAgICAgKuAgI1NjcCODk6Ozw9Pq85OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTk5OTlMAgICAgKwTk+xhYZ1AgKHAgICiAICAgICAgKJigICAgICAgICAgICAgKLjLKzjgKPkJGSk5SVlgKXAgKYmZqbAgICAgICAgICAlVVdVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVRVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQBBvLvAAAspVVVVVRUAUFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQEAQe+7wAALxAEQQRBVVVVVVVdVVVVVVVVVVVVRVVUAAEBU9d1VVVVVVVVVVRUAAAAAAFVVVVX8XVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVBQAUABQEUFVVVVVVVVUVUVVVVVVVVVUAAAAAAABAVVVVVVVVVVVV1VdVVVVVVVVVVVVVVQUAAFRVVVVVVVVVVVVVVVVVFQAAVVVRVVVVVVUFEAAAAQFQVVVVVVVVVVVVVQFVVVVVVf////9/VVVVUFUAAFVVVVVVVVVVVVUFAEHAvcAAC5gEQFVVVVVVVVVVVVVVVVVFVAEAVFEBAFVVBVVVVVVVVVVRVVVVVVVVVVVVVVVVVVVEAVRVUVUVVVUFVVVVVVVVRUFVVVVVVVVVVVVVVVVVVVRBFRRQUVVVVVVVVVVQUVVVQVVVVVVVVVVVVVVVVVVVVAEQVFFVVVVVBVVVVVVVBQBRVVVVVVVVVVVVVVVVVVUEAVRVUVUBVVUFVVVVVVVVVUVVVVVVVVVVVVVVVVVVVUVUVVVRVRVVVVVVVVVVVVVVVFRVVVVVVVVVVVVVVVVVBFQFBFBVQVVVBVVVVVVVVVVRVVVVVVVVVVVVVVVVVVUURAUEUFVBVVUFVVVVVVVVVVBVVVVVVVVVVVVVVVVVFUQBVFVBVRVVVQVVVVVVVVVVUVVVVVVVVVVVVVVVVVVVVVVVRRUFRFUVVVVVVVVVVVVVVVVVVVVVVVVVVVVRAEBVVRUAQFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVEAAFRVVQBAVVVVVVVVVVVVVVVVVVVVVVVVUFVVVVVVVRFRVVVVVVVVVVVVVVVVVQEAAEAABFUBAAABAAAAAAAAAABUVUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVAQQAQUFVVVVVVVVQBVRVVVUBVFVVRUFVUVVVVVFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVWqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqoAQYDCwAALkANVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQFVVVVVVVVVVVVVVVUFVFVVVVVVVQVVVVVVVVVVBVVVVVVVVVUFVVVVf//99//911931tXXVRAAUFVFAQAAVVdRVVVVVVVVVVVVVRUAVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVBVVVVVVVVVVVRVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVAFVRVRVUBVVVVVVVVVVVVVVVVVVVVVVVVVVVVVxUUVVVVVVVVVVVVVVVVVVVFAEBEAQBUFQAAFFVVVVVVVVVVVVVVVQAAAAAAAABAVVVVVVVVVVVVVVVVAFVVVVVVVVVVVVVVVQAAUAVVVVVVVVVVVVUVAABVVVVQVVVVVVVVVQVQEFBVVVVVVVVVVVVVVVVVRVARUFVVVVVVVVVVVVVVVVVVAAAFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVAAAAABABUUVVUUFVVVVVVVVVVVVVVVVVVVVVVAEGgxcAAC5MIVVUVAFVVVVVVVQVAVVVVVVVVVVVVVVVVAAAAAFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQAAAAAAAAAAVFVVVVVVVVVVVfVVVVVpVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVX9V9dVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVfVVVVVVVX1VVVVVVVVVVVVVVVf///1VVVVVVVVVVVVXVVVVVVdVVVVVdVfVVVVVVfVVfVXVVV1VVVVV1VfVddV1VXfVVVVVVVVVVV1VVVVVVVVVVd9XfVVVVVVVVVVVVVVVVVVVV/VVVVVVVVVdVVdVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV1VdVVVVVVVVVVVVVVVVXXVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUVUFVVVVVVVVVVVVVVVVVVVf3///////////////9fVdVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVAAAAAAAAAACqqqqqqqqaqqqqqqqqqqqqqqqqqqqqqqqqqqqqqlVVVaqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqWlVVVVVVVaqqqqqqqqqqqqqqqqqqCgCqqqpqqaqqqqqqqqqqqqqqqqqqqqqqqqqqaoGqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqVamqqqqqqqqqqqqqqaqqqqqqqqqqqqqqqqiqqqqqqqqqqqpqqqqqqqqqqqqqqqqqqqqqqqqqqqqqVVWVqqqqqqqqqqqqqqpqqqqqqqqqqqqqqlVVqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqlVVVVVVVVVVVVVVVVVVVVWqqqpWqqqqqqqqqqqqqqqqqmpVVVVVVVVVVVVVVVVVX1VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVRVAAABQVVVVVVVVVQVVVVVVVVVVVVVVVVVVVVVVVVVVVVBVVVVFRRVVVVVVVVVBVVRVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUFVVVVVVVQAAAABQVUUVVVVVVVVVVVVVBQBQVVVVVVUVAABQVVVVqqqqqqqqqlZAVVVVVVVVVVVVVVUVBVBQVVVVVVVVVVVVUVVVVVVVVVVVVVVVVVVVVVUBQEFBVVUVVVVUVVVVVVVVVVVVVVVUVVVVVVVVVVVVVVVVBBRUBVFVVVVVVVVVVVVVUFVFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUVRRVVVVVaqqqqqqqqqqqlVVVQAAAAAAQBUAQb/NwAAL4QxVVVVVVVVVVUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUAAADwqqpaVQAAAACqqqqqqqqqqmqqqqqqaqpVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUVqaqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqVlVVVVVVVVVVVVVVVVVVBVRVVVVVVVVVVVVVVVVVVVWqalVVAABUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVRVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQVAVQFBVQBVVVVVVVVVVVVVQBVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUFVVVVVVVXVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQBVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVRVUVVVVVVVVVVVVVVVVVVVVVVVVVQFVVVVVVVVVVVVVVVVVVVVVVQUAAFRVVVVVVVVVVVVVVQVQVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUVVVVVVVVVVVVVVVVVUAAABAVVVVVVVVVVVVVRRUVRVQVVVVVVVVVVVVVVUVQEFVRVVVVVVVVVVVVVVVVVVVVUBVVVVVVVVVVRUAAQBUVVVVVVVVVVVVVVVVVVUVVVVVUFVVVVVVVVVVVVVVVQUAQAVVARRVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVRVQBFVFUVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVFRUAQFVVVVVVUFVVVVVVVVVVVVVVVVUVRFRVVVVVFVVVVQUAVABUVVVVVVVVVVVVVVVVVVVVVQAABURVVVVVVUVVVVVVVVVVVVVVVVVVVVVVVVVVVRQARBEEVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUVBVBVEFRVVVVVVVVQVVVVVVVVVVVVVVVVVVVVVVVVVVUVAEARVFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUVUQAQVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQEFEABVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVRUAAEFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVRVFQQRVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVAAVVVFVVVVVVVVUBAEBVVVVVVVVVVVUVAARAVRVVVQFAAVVVVVVVVVVVVVUAAAAAQFBVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVAEAAEFVVVVVVVVVVVVVVVVVVVVVVVVVVBQAAAAAABQAEQVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQFARRAAAFVVVVVVVVVVVVVVVVVVVVVVVVARVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVFVRVVUBVVVVVVVVVVVVVVVUFQFVEVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQVAAAAUFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVAFRVVVVVVVVVVVVVVVVVVQBAVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVRVVVVVVVVVVVVVVVVVVVVUVQFVVVVVVVVVVVVVVVVVVVVVVVVWqVFVVWlVVVaqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqlVVqqqqqqqqqqqqqqqqqqqqqqqqqqqqWlVVVVVVVVVVVVWqqlZVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVWqqappqqqqqqqqqqpqVVVVZVVVVVVVVVVqWVVVVapVVaqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqVVVVVVVVVVVBAFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVAEGr2sAAC3VQAAAAAABAVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVEVAFAAAAAEABAFVVVVVVVVUFUFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQVUVVVVVVVVVVVVVVVVVVUAQa3bwAALAkAVAEG728AAC8UGVFVRVVVVVFVVVVUVAAEAAABVVVVVVVVVVVVVVVVVVVVVVVVVVQBAAAAAABQAEARAVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUVVVVVVVVVVVVVVVVVVVVUAVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQBVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUAQFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQBAVVVVVVVVVVVVVVVVVVVXVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVdVVVVVVVVVVVVVVVVVVVVV1/f9/VVVVVVVVVVVVVVVVVVVVVVVV9f///////25VVVWqqrqqqqqq6vq/v1WqqlZVX1VVVapaVVVVVVVV//////////9XVVX9/9////////////////////////f//////1VVVf////////////9/1f9VVVX/////V1f//////////////////////3/3/////////////////////////////////////////////////////////////9f///////////////////9fVVXVf////////1VVVVV1VVVVVVVVfVVVVVdVVVVVVVVVVVVVVVVVVVVVVVVVVdX///////////////////////////9VVVVVVVVVVVVVVVX//////////////////////19VV3/9Vf9VVdVXVf//V1VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVf///1VXVVVVVVVV//////////////9////f/////////////////////////////////////////////////////////////1VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVX///9X//9XVf//////////////3/9fVfX///9V//9XVf//V1WqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqWlVVVVVVVVVVWZZVYaqlWapVVVVVVZVVVVVVVVVVlVVVAEGO4sAACwEDAEGc4sAAC4oqVVVVVVWVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVUVAJZqWlpqqgVAplmVZVVVVVVVVVVVAAAAAFVWVVWpVlVVVVVVVVVVVVZVVVVVVVVVVQAAAAAAAAAAVFVVVZVZWVVVZVVVaVVVVVVVVVVVVVVVlVaVaqqqqlWqqlpVVVVZVaqqqlVVVVVlVVVaVVVVVaVlVlVVVZVVVVVVVVWmlpqWWVllqZaqqmZVqlVaWVVaVmVVVVVqqqWlWlVVVaWqWlVVWVlVVVlVVVVVVZVVVVVVVVVVVVVVVVVVVVVVVVVVVWVV9VVVVWlVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVWqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqmqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqlWqqqqqqqqqqqpVVVWqqqqqpVpVVZqqWlWlpVVaWqWWpVpVVVWlWlWVVVVVfVVpWaVVX1VmVVVVVVVVVVVmVf///1VVVZqaappVVVXVVVVVVdVVVaVdVfVVVVVVvVWvqrqqq6qqmlW6qvquuq5VXfVVVVVVVVVVV1VVVVVZVVVVd9XfVVVVVVVVVaWqqlVVVVVVVdVXVVVVVVVVVVVVVVVVV61aVVVVVVVVVVVVqqqqqqqqqmqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqoAAADAqqpaVQAAAACqqqqqqqqqqmqqqqqqaqpVVVVVVVVVVVVVVVUFVFVVVVVVVVVVVVVVVVVVVapqVVUAAFRZqqpqVaqqqqqqqqpaqqqqqqqqqqqqqqqqqqpaVaqqqqqqqqq6/v+/qqqqqlZVVVVVVVVVVVVVVVVV9f///////0pzVmFsdWUoKQAAAMAzEAAIAAAAyDMQAAEAAABUcmllZCB0byBzaHJpbmsgdG8gYSBsYXJnZXIgY2FwYWNpdHncMxAAJAAAAC9ydXN0Yy85YjAwOTU2ZTU2MDA5YmFiMmFhMTVkN2JmZjEwOTE2NTk5ZTNkNmQ2L2xpYnJhcnkvYWxsb2Mvc3JjL3Jhd192ZWMucnMINBAATAAAAOcBAAAJAAAAbnVsbCBwb2ludGVyIHBhc3NlZCB0byBydXN0cmVjdXJzaXZlIHVzZSBvZiBhbiBvYmplY3QgZGV0ZWN0ZWQgd2hpY2ggd291bGQgbGVhZCB0byB1bnNhZmUgYWxpYXNpbmcgaW4gcnVzdAAAVHJpZWQgdG8gc2hyaW5rIHRvIGEgbGFyZ2VyIGNhcGFjaXR50DQQACQAAAAvcnVzdGMvOWIwMDk1NmU1NjAwOWJhYjJhYTE1ZDdiZmYxMDkxNjU5OWUzZDZkNi9saWJyYXJ5L2FsbG9jL3NyYy9yYXdfdmVjLnJz/DQQAEwAAADnAQAACQAAAGAAAAAMAAAABAAAAGEAAABiAAAAEQAAAGUAAAAMAAAABAAAAGYAAABnAAAAaAAAAC9ydXN0L2RlcHMvZGxtYWxsb2MtMC4yLjYvc3JjL2RsbWFsbG9jLnJzYXNzZXJ0aW9uIGZhaWxlZDogcHNpemUgPj0gc2l6ZSArIG1pbl9vdmVyaGVhZACINRAAKQAAAKgEAAAJAAAAYXNzZXJ0aW9uIGZhaWxlZDogcHNpemUgPD0gc2l6ZSArIG1heF9vdmVyaGVhZAAAiDUQACkAAACuBAAADQAAAEFjY2Vzc0Vycm9ybWVtb3J5IGFsbG9jYXRpb24gb2YgIGJ5dGVzIGZhaWxlZAAAADs2EAAVAAAAUDYQAA0AAABsaWJyYXJ5L3N0ZC9zcmMvYWxsb2MucnNwNhAAGAAAAGIBAAAJAAAAbGlicmFyeS9zdGQvc3JjL3Bhbmlja2luZy5yc5g2EAAcAAAAhAIAAB4AAABlAAAADAAAAAQAAABpAAAAagAAAAgAAAAEAAAAawAAAGoAAAAIAAAABAAAAGwAAABtAAAAbgAAABAAAAAEAAAAbwAAAHAAAABxAAAAAAAAAAEAAAByAAAASGFzaCB0YWJsZSBjYXBhY2l0eSBvdmVyZmxvdxw3EAAcAAAAL3J1c3QvZGVwcy9oYXNoYnJvd24tMC4xNC4zL3NyYy9yYXcvbW9kLnJzAABANxAAKgAAAFYAAAAoAAAARXJyb3IAAABzAAAADAAAAAQAAAB0AAAAdQAAAHYAAABjYXBhY2l0eSBvdmVyZmxvdwAAAJw3EAARAAAAbGlicmFyeS9hbGxvYy9zcmMvcmF3X3ZlYy5yc7g3EAAcAAAAGQAAAAUAAABhIGZvcm1hdHRpbmcgdHJhaXQgaW1wbGVtZW50YXRpb24gcmV0dXJuZWQgYW4gZXJyb3IAdwAAAAAAAAABAAAAeAAAAGxpYnJhcnkvYWxsb2Mvc3JjL2ZtdC5ycyg4EAAY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");class J{constructor(){let A=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1;this.speed=A,this.startTime=performance.now()}getTime(){return this.speed*(performance.now()-this.startTime)/1e3}setTime(A){this.startTime=performance.now()-A/this.speed*1e3}}class S{constructor(){}getTime(A){}setTime(A){}}class Y{constructor(A,g){this.input="function"==typeof A.next?A:A[Symbol.iterator](),this.xfs=g??[]}map(A){return this.transform(function(A){return g=>I=>{g(A(I))}}(A))}flatMap(A){return this.transform(function(A){return g=>I=>{A(I).forEach(g)}}(A))}filter(A){return this.transform(function(A){return g=>I=>{A(I)&&g(I)}}(A))}take(A){return this.transform(function(A){let g=0;return I=>B=>{gB=>{g+=1,g>A&&I(B)}}(A))}transform(A){return new Y(this.input,this.xfs.concat([A]))}multiplex(A,g){return new Y(new p(this[Symbol.iterator](),A[Symbol.iterator](),g))}toArray(){return Array.from(this)}[Symbol.iterator](){let A=0,g=[],I=!1;const B=(Q=this.xfs,C=A=>g.push(A),Q.reverse().reduce(((A,g)=>{const I=U(g(A.step));return{step:I.step,flush:()=>{I.flush(),A.flush()}}}),U(C)));var Q,C;return{next:()=>{for(A===g.length&&(g=[],A=0);0===g.length;){const A=this.input.next();if(A.done)break;B.step(A.value)}return 0!==g.length||I||(B.flush(),I=!0),g.length>0?{done:!1,value:g[A++]}:{done:!0}}}}}function U(A){return"function"==typeof A?{step:A,flush:()=>{}}:A}class p{constructor(A,g,I){this.left=A,this.right=g,this.comparator=I}[Symbol.iterator](){let A,g;return{next:()=>{if(void 0===A&&void 0!==this.left){const g=this.left.next();g.done?this.left=void 0:A=g.value}if(void 0===g&&void 0!==this.right){const A=this.right.next();A.done?this.right=void 0:g=A.value}if(void 0===A&&void 0===g)return{done:!0};if(void 0===A){const A=g;return g=void 0,{done:!1,value:A}}if(void 0===g){const g=A;return A=void 0,{done:!1,value:g}}if(this.comparator(A,g)){const g=A;return A=void 0,{done:!1,value:g}}{const A=g;return g=void 0,{done:!1,value:A}}}}}}async function L(A){let g,I;if(A instanceof Response){const B=await A.text(),Q=function(A){const g=A.split("\n");let I;try{I=JSON.parse(g[0])}catch(A){return}const B=new Y(g).drop(1).filter((A=>"["===A[0])).map(JSON.parse).toArray();return{header:I,events:B}}(B);void 0!==Q?(g=Q.header,I=Q.events):g=JSON.parse(B)}else if("object"==typeof A&&"number"==typeof A.version)g=A;else{if(!Array.isArray(A))throw"invalid data";g=A[0],I=A.slice(1,A.length)}if(1===g.version)return function(A){let g=0;const I=new Y(A.stdout).map((A=>(g+=A[0],[g,"o",A[1]])));return{cols:A.width,rows:A.height,events:I}}(g);if(2===g.version)return function(A,g){return{cols:A.width,rows:A.height,theme:m(A.theme),events:g,idleTimeLimit:A.idle_time_limit}}(g,I);throw`asciicast v${g.version} format not supported`}function m(A){const g=/^#[0-9A-Fa-f]{6}$/,I=A?.fg,B=A?.bg,Q=A?.palette;if(g.test(I)&&g.test(B)&&/^(#[0-9A-Fa-f]{6}:){7,}#[0-9A-Fa-f]{6}$/.test(Q))return{foreground:I,background:B,palette:Q.split(":")}}function K(A){return"number"==typeof A?[A,"m",""]:[A[0],"m",A[1]]}function b(){let A=0;return function(g){return"m"===g[1]?[g[0],g[1],{index:A++,time:g[0],label:g[2]}]:g}}class H{constructor(){this.items=[],this.onPush=void 0}push(A){this.items.push(A),void 0!==this.onPush&&(this.onPush(this.popAll()),this.onPush=void 0)}popAll(){if(this.items.length>0){const A=this.items;return this.items=[],A}{const A=this;return new Promise((g=>{A.onPush=g}))}}}function v(A,g,I,B,Q,C,E,V,e){const i=function(A,g,I,B){return function(Q,C){"o"===Q?A(C):"i"===Q?I(C):"r"===Q?g(C.cols,C.rows):"m"===Q&&B(C)}}(g,I,B,Q);if(0===A)return e.debug("using no buffer"),function(A){return{pushEvent(g){A(g[1],g[2])},pushText(g){A("o",g)},stop(){}}}(i);{let g;return"number"==typeof(A=A??{})?(e.debug(`using fixed time buffer (${A} ms)`),g=g=>A):"function"==typeof A?(e.debug("using custom dynamic buffer"),g=A({logger:e})):(e.debug("using adaptive buffer",A),g=function(A,g){let{logger:I}=A,{minTime:B=25,maxLevel:Q=100,interval:C=50,windowSize:E=20,smoothingFactor:V=.2,minImprovementDuration:e=1e3}=g,i=0,t=a(i),o=[],s=0,n=0,r=null;function a(A){return 0===A?B:C*A}return A=>{if(o.push(A),o.lengthgg>A?g:A))}(o);s=B*V+s*(1-V),n=(B-g)*V+n*(1-V);const C=s+n;if(A>t&&I.debug("buffer underrun",{latency:A,maxJitter:s,jitterRange:n,bufferTime:t}),it)t=a(i+=1),I.debug("jitter increased, raising bufferTime",{latency:A,maxJitter:s,jitterRange:n,bufferTime:t});else if(i>1&&Ce&&(r=performance.now(),t=a(i-=1),I.debug("jitter decreased, lowering bufferTime",{latency:A,maxJitter:s,jitterRange:n,bufferTime:t})),t;return r=null,t}}({logger:e},A)),function(A,g,I,B,Q){let C=arguments.length>5&&void 0!==arguments[5]?arguments[5]:1/60,E=performance.now()-1e3*Q,V=A(0);const e=new H;C*=1e3;let i=-C,t=!1;function o(){return performance.now()-E}return setTimeout((async()=>{for(;!t;){const A=await e.popAll();if(t)return;for(const B of A){const A=1e3*B[0]+V;if(A-i0&&(await T(Q),t))return;I(B[0]),g(B[1],B[2]),i=A}}}),0),{pushEvent(g){let I=o()-1e3*g[0];I<0&&(B.debug(`correcting epoch by ${I} ms`),E+=I,I=0),V=A(I),e.push(g)},pushText(A){e.push([o()/1e3,"o",A])},stop(){t=!0,e.push(void 0)}}}(g,i,C,e,E??0,V)}}function T(A){return new Promise((g=>{setTimeout(g,A)}))}const O=1e6;function x(A){const g=new TextDecoder,I=new TextDecoder;let B,Q=function(A){const g=(new TextDecoder).decode(A);if("ALiS"!==g)throw"not an ALiS v1 live stream";Q=E},C=0;function E(A){const g=new X(new DataView(A)),I=g.getUint8();if(1!==I)throw`expected reset (0x01) frame, got ${I}`;return V(g,A)}function V(A,I){A.decodeVarUint();let E=A.decodeVarUint();B=E,E/=O,C=0;const V=A.decodeVarUint(),i=A.decodeVarUint(),t=A.getUint8();let o;if(8===t){const g=30;o=j(new Uint8Array(I,A.offset,g)),A.forward(g)}else if(16===t){const g=54;o=j(new Uint8Array(I,A.offset,g)),A.forward(g)}else if(0!==t)throw`alis: invalid theme format (${t})`;const s=A.decodeVarUint();let n;return s>0&&(n=g.decode(new Uint8Array(I,A.offset,s))),Q=e,{time:E,term:{size:{cols:V,rows:i},theme:o,init:n}}}function e(e){const i=new X(new DataView(e)),t=i.getUint8();return 1===t?V(i,e):111===t?function(A,I){A.decodeVarUint();const Q=A.decodeVarUint();B+=Q;const C=A.decodeVarUint(),E=g.decode(new Uint8Array(I,A.offset,C));return[B/O,"o",E]}(i,e):105===t?function(A,g){A.decodeVarUint();const Q=A.decodeVarUint();B+=Q;const C=A.decodeVarUint(),E=I.decode(new Uint8Array(g,A.offset,C));return[B/O,"i",E]}(i,e):114===t?function(A){A.decodeVarUint();const g=A.decodeVarUint();B+=g;const I=A.decodeVarUint(),Q=A.decodeVarUint();return[B/O,"r",{cols:I,rows:Q}]}(i):109===t?function(A,g){A.decodeVarUint();const I=A.decodeVarUint();B+=I;const Q=A.decodeVarUint(),E=new TextDecoder,V=C++,e=B/O,i=E.decode(new Uint8Array(g,A.offset,Q));return[e,"m",{index:V,time:e,label:i}]}(i,e):4===t?(Q=E,!1):void A.debug(`alis: unknown frame type: ${t}`)}return function(A){return Q(A)}}function j(A){const g=A.length/3,I=Z(A[0],A[1],A[2]),B=Z(A[3],A[4],A[5]),Q=[];for(let I=2;I1&&void 0!==arguments[1]?arguments[1]:0;this.inner=A,this.offset=g}forward(A){this.offset+=A}getUint8(){const A=this.inner.getUint8(this.offset);return this.offset+=1,A}decodeVarUint(){let A=BigInt(0),g=BigInt(0),I=this.getUint8();for(;I>127;)I&=127,A+=BigInt(I)<(await N(R),M))();class gA{constructor(A){this.core=A,this.driver=A.driver}onEnter(A){}init(){}play(){}pause(){}togglePlay(){}seek(A){return!1}step(A){}stop(){this.driver.stop()}}class IA extends gA{async init(){try{return await this.core._initializeDriver(),this.core._setState("idle")}catch(A){throw this.core._setState("errored"),A}}async play(){this.core._dispatchEvent("play");const A=await this.init();await A.doPlay()}async togglePlay(){await this.play()}async seek(A){const g=await this.init();return await g.seek(A)}async step(A){const g=await this.init();await g.step(A)}stop(){}}class BA extends gA{onEnter(A){let{reason:g,message:I}=A;this.core._dispatchEvent("idle",{message:I}),"paused"===g&&this.core._dispatchEvent("pause")}async play(){this.core._dispatchEvent("play"),await this.doPlay()}async doPlay(){const A=await this.driver.play();!0===A?this.core._setState("playing"):"function"==typeof A&&(this.core._setState("playing"),this.driver.stop=A)}async togglePlay(){await this.play()}seek(A){return this.driver.seek(A)}step(A){this.driver.step(A)}}class QA extends gA{onEnter(){this.core._dispatchEvent("playing")}pause(){!0===this.driver.pause()&&this.core._setState("idle",{reason:"paused"})}togglePlay(){this.pause()}seek(A){return this.driver.seek(A)}}class CA extends gA{onEnter(){this.core._dispatchEvent("loading")}}class EA extends gA{onEnter(A){let{message:g}=A;this.core._dispatchEvent("offline",{message:g})}}class VA extends gA{onEnter(A){let{message:g}=A;this.core._dispatchEvent("ended",{message:g})}async play(){this.core._dispatchEvent("play"),await this.driver.restart()&&this.core._setState("playing")}async togglePlay(){await this.play()}seek(A){return!0===this.driver.seek(A)&&(this.core._setState("idle"),!0)}}class eA extends gA{onEnter(){this.core._dispatchEvent("errored")}}class iA{constructor(A,I){this.logger=I.logger,this.state=new IA(this),this.stateName="uninitialized",this.driver=function(A){if("function"==typeof A)return A;"string"==typeof A&&(A="ws://"==A.substring(0,5)||"wss://"==A.substring(0,6)?{driver:"websocket",url:A}:"clock:"==A.substring(0,6)?{driver:"clock"}:"random:"==A.substring(0,7)?{driver:"random"}:"benchmark:"==A.substring(0,10)?{driver:"benchmark",url:A.substring(10)}:{driver:"recording",url:A});void 0===A.driver&&(A.driver="recording");if("recording"==A.driver&&(void 0===A.parser&&(A.parser="asciicast"),"string"==typeof A.parser)){if(!oA.has(A.parser))throw`unknown parser: ${A.parser}`;A.parser=oA.get(A.parser)}if(tA.has(A.driver)){const g=tA.get(A.driver);return(I,B)=>g(A,I,B)}throw`unsupported driver: ${JSON.stringify(A)}`}(A),this.changedLines=new Set,this.cursor=void 0,this.duration=void 0,this.cols=I.cols,this.rows=I.rows,this.speed=I.speed,this.loop=I.loop,this.autoPlay=I.autoPlay,this.idleTimeLimit=I.idleTimeLimit,this.preload=I.preload,this.startAt=g(I.startAt),this.poster=this._parsePoster(I.poster),this.markers=this._normalizeMarkers(I.markers),this.pauseOnMarkers=I.pauseOnMarkers,this.commandQueue=Promise.resolve(),this.eventHandlers=new Map([["ended",[]],["errored",[]],["idle",[]],["input",[]],["loading",[]],["marker",[]],["metadata",[]],["offline",[]],["pause",[]],["play",[]],["playing",[]],["ready",[]],["reset",[]],["resize",[]],["seeked",[]],["terminalUpdate",[]]])}async init(){this.wasm=await AA;const A=this._feed.bind(this),g=this._now.bind(this),I=this._resetVt.bind(this),B=this._resizeVt.bind(this),Q=this._setState.bind(this),C="npt"===this.poster.type?this.poster.value:void 0;this.driver=this.driver({feed:A,onInput:A=>{this._dispatchEvent("input",{data:A})},onMarker:A=>{let{index:g,time:I,label:B}=A;this._dispatchEvent("marker",{index:g,time:I,label:B})},reset:I,resize:B,now:g,setTimeout:(A,g)=>setTimeout(A,g/this.speed),setInterval:(A,g)=>setInterval(A,g/this.speed),setState:Q,logger:this.logger},{cols:this.cols,rows:this.rows,idleTimeLimit:this.idleTimeLimit,startAt:this.startAt,loop:this.loop,posterTime:C,markers:this.markers,pauseOnMarkers:this.pauseOnMarkers}),"function"==typeof this.driver&&(this.driver={play:this.driver}),(this.preload||void 0!==C)&&this._withState((A=>A.init()));const E="text"===this.poster.type?this._renderPoster(this.poster.value):null,V={isPausable:!!this.driver.pause,isSeekable:!!this.driver.seek,poster:E};if(void 0===this.driver.init&&(this.driver.init=()=>({})),void 0===this.driver.pause&&(this.driver.pause=()=>{}),void 0===this.driver.seek&&(this.driver.seek=A=>!1),void 0===this.driver.step&&(this.driver.step=A=>{}),void 0===this.driver.stop&&(this.driver.stop=()=>{}),void 0===this.driver.restart&&(this.driver.restart=()=>{}),void 0===this.driver.getCurrentTime){const A=this.driver.play;let g=new S;this.driver.play=()=>(g=new J(this.speed),A()),this.driver.getCurrentTime=()=>g.getTime()}this._dispatchEvent("ready",V),this.autoPlay&&this.play()}play(){return this._withState((A=>A.play()))}pause(){return this._withState((A=>A.pause()))}togglePlay(){return this._withState((A=>A.togglePlay()))}seek(A){return this._withState((async g=>{await g.seek(A)&&this._dispatchEvent("seeked")}))}step(A){return this._withState((g=>g.step(A)))}stop(){return this._withState((A=>A.stop()))}getChanges(){const A={};if(this.changedLines.size>0){const g=new Map,I=this.vt.rows;for(const A of this.changedLines)A1&&void 0!==arguments[1]?arguments[1]:{};for(const I of this.eventHandlers.get(A))I(g)}_withState(A){return this._enqueueCommand((()=>A(this.state)))}_enqueueCommand(A){return this.commandQueue=this.commandQueue.then(A),this.commandQueue}_setState(A){let g=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(this.stateName===A)return this.state;if(this.stateName=A,"playing"===A)this.state=new QA(this);else if("idle"===A)this.state=new BA(this);else if("loading"===A)this.state=new CA(this);else if("ended"===A)this.state=new VA(this);else if("offline"===A)this.state=new EA(this);else{if("errored"!==A)throw`invalid state: ${A}`;this.state=new eA(this)}return this.state.onEnter(g),this.state}_feed(A){this._doFeed(A),this._dispatchEvent("terminalUpdate")}_doFeed(A){this.vt.feed(A).forEach((A=>this.changedLines.add(A))),this.cursor=void 0}_now(){return performance.now()*this.speed}async _initializeDriver(){const A=await this.driver.init();this.cols=this.cols??A.cols??80,this.rows=this.rows??A.rows??24,this.duration=this.duration??A.duration,this.markers=this._normalizeMarkers(A.markers)??this.markers??[],0===this.cols&&(this.cols=80),0===this.rows&&(this.rows=24),this._initializeVt(this.cols,this.rows);const g=void 0!==A.poster?this._renderPoster(A.poster):null;this._dispatchEvent("metadata",{cols:this.cols,rows:this.rows,duration:this.duration,markers:this.markers,theme:A.theme,poster:g})}_resetVt(A,g){let I=arguments.length>2&&void 0!==arguments[2]?arguments[2]:void 0,B=arguments.length>3&&void 0!==arguments[3]?arguments[3]:void 0;this.logger.debug(`core: vt reset (${A}x${g})`),this.cols=A,this.rows=g,this.cursor=void 0,this._initializeVt(A,g),void 0!==I&&""!==I&&this._doFeed(I),this._dispatchEvent("reset",{cols:A,rows:g,theme:B})}_resizeVt(A,g){if(A===this.vt.cols&&g===this.vt.rows)return;this.vt.resize(A,g).forEach((A=>this.changedLines.add(A))),this.cursor=void 0,this.vt.cols=A,this.vt.rows=g,this.logger.debug(`core: vt resize (${A}x${g})`),this._dispatchEvent("resize",{cols:A,rows:g})}_initializeVt(A,g){this.vt=this.wasm.create(A,g,!0,100),this.vt.cols=A,this.vt.rows=g,this.changedLines.clear();for(let A=0;AB.feed(A)));const Q=B.getCursor()??!1,C=[];for(let A=0;A"number"==typeof A?[A,""]:A))}}const tA=new Map([["benchmark",function(A,g){let I,{url:B,iterations:Q=10}=A,{feed:C,setState:E,now:V}=g,e=0;return{async init(){const A=await L(await fetch(B)),{cols:g,rows:Q,events:C}=A;I=Array.from(C).filter((A=>{let[g,I,B]=A;return"o"===I})).map((A=>{let[g,I,B]=A;return[g,B]}));const E=I[I.length-1][0];for(const[A,g]of I)e+=new Blob([g]).size;return{cols:g,rows:Q,duration:E}},play(){const A=V();for(let A=0;A{E("stopped",{reason:"ended"})}),0),!0}}}],["clock",function(A,g,I){let{hourColor:B=3,minuteColor:Q=4,separatorColor:C=9}=A,{feed:E}=g,{cols:V=5,rows:e=1}=I;const i=Math.floor(e/2),t=Math.floor(V/2)-2,o=`[?25l[${i}B`;let s;const n=()=>{const A=new Date,g=A.getHours(),I=A.getMinutes(),E=[];E.push("\r");for(let A=0;A{n().forEach(E)};return{init:()=>{const A=[o].concat(n());return{cols:V,rows:e,duration:1440,poster:A}},play:()=>(E(o),r(),s=setInterval(r,1e3),!0),stop:()=>{clearInterval(s)},getCurrentTime:()=>{const A=new Date;return 60*A.getHours()+A.getMinutes()}}}],["eventsource",function(A,g){let I,Q,{url:C,bufferTime:E,minFrameTime:V}=A,{feed:e,reset:i,resize:t,onInput:o,onMarker:s,setState:n,logger:r}=g;r=new B(r,"eventsource: ");let a=new S;function c(A){void 0!==Q&&Q.stop(),Q=v(E,e,t,o,s,(A=>a.setTime(A)),A,V,r)}return{play:()=>{I=new EventSource(C),I.addEventListener("open",(()=>{r.info("opened"),c()})),I.addEventListener("error",(A=>{r.info("errored"),r.debug({e:A}),n("loading")})),I.addEventListener("message",(A=>{const g=JSON.parse(A.data);if(Array.isArray(g))Q.pushEvent(g);else if(void 0!==g.cols||void 0!==g.width){const A=g.cols??g.width,I=g.rows??g.height;r.debug(`vt reset (${A}x${I})`),n("playing"),c(g.time),i(A,I,g.init??void 0),a=new J,"number"==typeof g.time&&a.setTime(g.time)}else"offline"===g.state&&(r.info("stream offline"),n("offline",{message:"Stream offline"}),a=new S)})),I.addEventListener("done",(()=>{r.info("closed"),I.close(),n("ended",{message:"Stream ended"})}))},stop:()=>{void 0!==Q&&Q.stop(),void 0!==I&&I.close()},getCurrentTime:()=>a.getTime()}}],["random",function(A,g){let{feed:I,setTimeout:B}=g;const Q=" ".charCodeAt(0),C="~".charCodeAt(0)-Q;let E;const V=()=>{const A=Math.pow(5,4*Math.random());E=B(e,A)},e=()=>{V();const A=String.fromCharCode(Q+Math.floor(Math.random()*C));I(A)};return()=>(V(),()=>clearInterval(E))}],["recording",function(A,g,I){let B,Q,C,E,V,e,i,t,o,{feed:s,resize:n,onInput:r,onMarker:a,now:c,setTimeout:D,setState:w,logger:h}=g,{idleTimeLimit:l,startAt:y,loop:k,posterTime:G,markers:F,pauseOnMarkers:q,cols:d,rows:N}=I,M=0,u=0,f=0;async function R(A,g){const I=await fetch(A,g);if(!I.ok)throw`failed fetching recording from ${A}: ${I.status} ${I.statusText}`;return I}function J(){const A=C[M];A?i=D(S,function(A){let g=1e3*A-(c()-t);return g<0&&(g=0),g}(A[0])):L()}function S(){let A,g=C[M];do{u=g[0],M++;if(p(g))return;g=C[M],A=c()-t}while(g&&A>1e3*g[0]);J()}function U(){clearTimeout(i),i=null}function p(A){const[g,I,B]=A;if("o"===I)s(B);else if("i"===I)r(B);else if("r"===I){const[A,g]=B.split("x");n(A,g)}else if("m"===I&&(a(B),q))return m(),o=1e3*g,w("idle",{reason:"paused"}),!0;return!1}function L(){U(),f++,!0===k||"number"==typeof k&&f>"===A?A=I+5:"<<<"===A?A=I-.1*V:">>>"===A?A=I+.1*V:"%"===A[A.length-1]&&(A=parseFloat(A.substring(0,A.length-1))/100*V);else if("object"==typeof A)if("prev"===A.marker)A=T(I)??0,g&&I-A<1&&(A=T(A)??0);else if("next"===A.marker)A=function(A){if(0==E.length)return;let g,I=E.length-1,B=E[I];for(;B&&B[0]>A;)g=B[0],B=E[--I];return g}(I)??V;else if("number"==typeof A.marker){const g=E[A.marker];if(void 0===g)throw`invalid marker index: ${A.marker}`;A=g[0]}const B=Math.min(Math.max(A,0),V);B1&&void 0!==arguments[1]?arguments[1]:1/60;return B=>{let Q=0,C=0;return{step:A=>{Q++,void 0!==g?"o"===A[1]&&"o"===g[1]&&A[0]-g[0]{void 0!==g&&(B(g),C++),A.debug(`batched ${Q} frames to ${C} frames`)}}}}(g,C)).map(function(A,g,I){let B=0,Q=0;return function(C){const E=C[0]-B-A;return B=C[0],E>0&&(Q+=E,C[0]"m"!==A[1])).multiplex(V,((A,g)=>A[0]"i"===A[1]?[A[0]+E,A[1],A[2]]:A)),e.sort(((A,g)=>A[0]-g[0])));const t=e[e.length-1][0],o=B-i.offset;return{...A,events:e,duration:t,effectiveStartAt:o}}(await g(await function(A){let{url:g,data:I,fetchOpts:B={}}=A;if("string"==typeof g)return R(g,B);if(Array.isArray(g))return Promise.all(g.map((A=>R(A,B))));if(void 0!==I)return"function"==typeof I&&(I=I()),I instanceof Promise||(I=Promise.resolve(I)),I.then((A=>"string"==typeof A||A instanceof ArrayBuffer?new Response(A):A));throw"failed fetching recording file: url/data missing in src"}(A),{encoding:o}),h,{idleTimeLimit:l,startAt:y,minFrameTime:I,inputOffset:i,markers_:F});if(({cols:B,rows:Q,events:C,duration:V,effectiveStartAt:e}=s),d=d??B,N=N??Q,0===C.length)throw"recording is missing events";void 0!==t&&function(A,g){const I=document.createElement("a"),B=A.events.map((A=>"m"===A[1]?[A[0],A[1],A[2].label]:A)),Q=function(A){return`${JSON.stringify({version:2,width:A.cols,height:A.rows})}\n${A.events.map(JSON.stringify).join("\n")}\n`}({...A,events:B});I.href=URL.createObjectURL(new Blob([Q],{type:"text/plain"})),I.download=g,I.click()}(s,t);const n=void 0!==G?(r=G,C.filter((A=>A[0]A[2]))):void 0;var r;return E=C.filter((A=>"m"===A[1])).map((A=>[A[0],A[2].label])),{cols:B,rows:Q,duration:V,theme:s.theme,poster:n,markers:E}},play:function(){if(i)throw"already playing";if(void 0===C[M])throw"already ended";return null!==e&&v(e),H(),!0},pause:m,seek:v,step:function(A){let g,I;if(void 0===A&&(A=1),A>0){let B=M;g=C[B];for(let Q=0;Q{const A=I.protocol||"raw";a.info("opened"),a.info(`activating ${A} protocol handler`),"v1.alis"===A?I.onmessage=G(x(a)):"v2.asciicast"===A?I.onmessage=G(function(){let A=function(I){const B=JSON.parse(I);if(2!==B.version)throw"not an asciicast v2 stream";return A=g,{time:0,term:{size:{cols:B.width,rows:B.height}}}};function g(A){const g=JSON.parse(A);if("r"===g[1]){const[A,I]=g[2].split("x");return[g[0],"r",{cols:A,rows:I}]}return g}return function(g){return A(g)}}()):"raw"===A&&(I.onmessage=G(z())),c=setTimeout((()=>{h=0}),1e3)},I.onclose=A=>{if(clearTimeout(D),d(),l||1e3===A.code||1005===A.code)a.info("closed"),r("ended",{message:"Stream ended"});else if(1002===A.code)a.debug(`close reason: ${A.reason}`),r("ended",{message:"Err: Player not compatible with the server"});else{clearTimeout(c);const A=V(h++);a.info(`unclean close, reconnecting in ${A}...`),r("loading"),setTimeout(k,A)}},y=!1}function G(A){return D=setTimeout(q,5e3),function(g){try{const I=A(g.data);if(Q)if(Array.isArray(I))Q.pushEvent(I);else if("string"==typeof I)Q.pushText(I);else if("object"!=typeof I||Array.isArray(I)){if(!1===I)q();else if(void 0!==I)throw`unexpected value from protocol handler: ${I}`}else F(I);else if("object"!=typeof I||Array.isArray(I)){if(void 0!==I)throw clearTimeout(D),`unexpected value from protocol handler: ${I}`;clearTimeout(D),D=setTimeout(q,1e3)}else F(I),clearTimeout(D)}catch(A){throw I.close(),A}}}function F(A){let{time:g,term:I}=A;const{size:B,init:C,theme:V}=I,{cols:c,rows:D}=B;a.info(`stream reset (${c}x${D} @${g})`),r("playing"),d(),Q=v(E,i,o,s,n,(A=>w.setTime(A)),g,e,a),t(c,D,C,V),w=new J,y=!0,"number"==typeof g&&w.setTime(g)}function q(){d(),y?(a.info("stream ended"),r("offline",{message:"Stream ended"})):(a.info("stream offline"),r("offline",{message:"Stream offline"})),w=new S}function d(){Q&&Q.stop(),Q=null}return{play:()=>{k()},stop:()=>{l=!0,d(),void 0!==I&&I.close()},getCurrentTime:()=>w.getTime()}}]]),oA=new Map([["asciicast",L],["typescript",async function(A,g){let{encoding:I}=g;const B=new TextDecoder(I);let Q,C,E=(await A[0].text()).split("\n").filter((A=>A.length>0)).map((A=>A.split(" ")));E[0].length<3&&(E=E.map((A=>["O",A[0],A[1]])));const V=await A[1].arrayBuffer(),e=new Uint8Array(V),i=e.findIndex((A=>10==A))+1,t=B.decode(e.subarray(0,i)).match(/COLUMNS="(\d+)" LINES="(\d+)"/);null!==t&&(Q=parseInt(t[1],10),C=parseInt(t[2],10));const o={array:e,cursor:i};let s=o;if(void 0!==A[2]){const g=await A[2].arrayBuffer();s={array:new Uint8Array(g),cursor:i}}const n=[];let r=0;for(const A of E)if(r+=parseFloat(A[1]),"O"===A[0]){const g=parseInt(A[2],10),I=o.array.subarray(o.cursor,o.cursor+g),Q=B.decode(I);n.push([r,"o",Q]),o.cursor+=g}else if("I"===A[0]){const g=parseInt(A[2],10),I=s.array.subarray(s.cursor,s.cursor+g),Q=B.decode(I);n.push([r,"i",Q]),s.cursor+=g}else if("S"===A[0]&&"SIGWINCH"===A[2]){const g=parseInt(A[4].slice(5),10),I=parseInt(A[3].slice(5),10);n.push([r,"r",`${g}x${I}`])}else"H"===A[0]&&"COLUMNS"===A[2]?Q=parseInt(A[3],10):"H"===A[0]&&"LINES"===A[2]&&(C=parseInt(A[3],10));return Q=Q??80,C=C??24,{cols:Q,rows:C,events:n}}],["ttyrec",async function(A,g){let{encoding:I}=g;const B=new TextDecoder(I),Q=await A.arrayBuffer(),C=new Uint8Array(Q),E=_(C),V=E.time,e=B.decode(E.data).match(/\x1b\[8;(\d+);(\d+)t/),i=[];let t=80,o=24;null!==e&&(t=parseInt(e[2],10),o=parseInt(e[1],10));let s=0,n=_(C);for(;void 0!==n;){const A=n.time-V,g=B.decode(n.data);i.push([A,"o",g]),s+=n.len,n=_(C.subarray(s))}return{cols:t,rows:o,events:i}}]]);const sA={};const nA=Symbol("solid-proxy"),rA=Symbol("solid-track"),aA={equals:(A,g)=>A===g};let cA=vA;const DA=1,wA=2,hA={owned:null,cleanups:null,context:null,owner:null};var lA=null;let yA=null,kA=null,GA=null,FA=null,qA=0;function dA(A,g){const I=kA,B=lA,Q=0===A.length,C=Q?hA:{owned:null,cleanups:null,context:null,owner:void 0===g?B:g},E=Q?A:()=>A((()=>RA((()=>jA(C)))));lA=C,kA=null;try{return HA(E,!0)}finally{kA=I,lA=B}}function NA(A,g){const I={value:A,observers:null,observerSlots:null,comparator:(g=g?Object.assign({},aA,g):aA).equals||void 0};return[pA.bind(I),A=>("function"==typeof A&&(A=A(I.value)),LA(I,A))]}function MA(A,g,I){mA(KA(A,g,!1,DA))}function uA(A,g,I){I=I?Object.assign({},aA,I):aA;const B=KA(A,g,!0,0);return B.observers=null,B.observerSlots=null,B.comparator=I.equals||void 0,mA(B),pA.bind(B)}function fA(A){return HA(A,!1)}function RA(A){if(null===kA)return A();const g=kA;kA=null;try{return A()}finally{kA=g}}function JA(A){!function(A,g,I){cA=TA;const B=KA(A,g,!1,DA);B.user=!0,FA?FA.push(B):mA(B)}((()=>RA(A)))}function SA(A){return null===lA||(null===lA.cleanups?lA.cleanups=[A]:lA.cleanups.push(A)),A}function YA(){return kA}function UA(A){const g=uA(A),I=uA((()=>WA(g())));return I.toArray=()=>{const A=I();return Array.isArray(A)?A:null!=A?[A]:[]},I}function pA(){const A=yA;if(this.sources&&(this.state||A))if(this.state===DA||A)mA(this);else{const A=GA;GA=null,HA((()=>OA(this)),!1),GA=A}if(kA){const A=this.observers?this.observers.length:0;kA.sources?(kA.sources.push(this),kA.sourceSlots.push(A)):(kA.sources=[this],kA.sourceSlots=[A]),this.observers?(this.observers.push(kA),this.observerSlots.push(kA.sources.length-1)):(this.observers=[kA],this.observerSlots=[kA.sources.length-1])}return this.value}function LA(A,g,I){let B=A.value;return A.comparator&&A.comparator(B,g)||(A.value=g,A.observers&&A.observers.length&&HA((()=>{for(let g=0;g1e6)throw GA=[],new Error}),!1)),g}function mA(A){if(!A.fn)return;jA(A);const g=lA,I=kA,B=qA;kA=lA=A,function(A,g,I){let B;try{B=A.fn(g)}catch(g){A.pure&&(A.state=DA,A.owned&&A.owned.forEach(jA),A.owned=null),ZA(g)}(!A.updatedAt||A.updatedAt<=I)&&(null!=A.updatedAt&&"observers"in A?LA(A,B):A.value=B,A.updatedAt=I)}(A,A.value,B),kA=I,lA=g}function KA(A,g,I,B=DA,Q){const C={fn:A,state:B,updatedAt:null,owned:null,sources:null,sourceSlots:null,cleanups:null,value:g,owner:lA,context:null,pure:I};return null===lA||lA!==hA&&(lA.owned?lA.owned.push(C):lA.owned=[C]),C}function bA(A){const g=yA;if(0===A.state||g)return;if(A.state===wA||g)return OA(A);if(A.suspense&&RA(A.suspense.inFallback))return A.suspense.effects.push(A);const I=[A];for(;(A=A.owner)&&(!A.updatedAt||A.updatedAt=0;B--)if((A=I[B]).state===DA||g)mA(A);else if(A.state===wA||g){const g=GA;GA=null,HA((()=>OA(A,I[0])),!1),GA=g}}function HA(A,g){if(GA)return A();let I=!1;g||(GA=[]),FA?I=!0:FA=[],qA++;try{const g=A();return function(A){GA&&(vA(GA),GA=null);if(A)return;const g=FA;FA=null,g.length&&HA((()=>cA(g)),!1)}(I),g}catch(A){I||(FA=null),GA=null,ZA(A)}}function vA(A){for(let g=0;gA(g||{})))}function _A(){return!0}const $A={get:(A,g,I)=>g===nA?I:A.get(g),has:(A,g)=>g===nA||A.has(g),set:_A,deleteProperty:_A,getOwnPropertyDescriptor:(A,g)=>({configurable:!0,enumerable:!0,get:()=>A.get(g),set:_A,deleteProperty:_A}),ownKeys:A=>A.keys()};function Ag(A){return(A="function"==typeof A?A():A)?A:{}}function gg(A){const g="fallback"in A&&{fallback:()=>A.fallback};return uA(function(A,g,I={}){let B=[],Q=[],C=[],E=0,V=g.length>1?[]:null;return SA((()=>zA(C))),()=>{let e,i,t=A()||[];return t[rA],RA((()=>{let A,g,s,n,r,a,c,D,w,h=t.length;if(0===h)0!==E&&(zA(C),C=[],B=[],Q=[],E=0,V&&(V=[])),I.fallback&&(B=[XA],Q[0]=dA((A=>(C[0]=A,I.fallback()))),E=1);else if(0===E){for(Q=new Array(h),i=0;i=a&&D>=a&&B[c]===t[D];c--,D--)s[D]=Q[c],n[D]=C[c],V&&(r[D]=V[c]);for(A=new Map,g=new Array(D+1),i=D;i>=a;i--)w=t[i],e=A.get(w),g[i]=void 0===e?-1:e,A.set(w,i);for(e=a;e<=c;e++)w=B[e],i=A.get(w),void 0!==i&&-1!==i?(s[i]=Q[e],n[i]=C[e],V&&(r[i]=V[e]),i=g[i],A.set(w,i)):C[e]();for(i=a;iA.each),A.children,g||void 0))}function Ig(A){const g="fallback"in A&&{fallback:()=>A.fallback};return uA(function(A,g,I={}){let B,Q=[],C=[],E=[],V=[],e=0;return SA((()=>zA(E))),()=>{const i=A()||[];return i[rA],RA((()=>{if(0===i.length)return 0!==e&&(zA(E),E=[],Q=[],C=[],e=0,V=[]),I.fallback&&(Q=[XA],C[0]=dA((A=>(E[0]=A,I.fallback()))),e=1),C;for(Q[0]===XA&&(E[0](),E=[],Q=[],C=[],e=0),B=0;Bi[B])):B>=Q.length&&(C[B]=dA(t));for(;BA.each),A.children,g||void 0))}function Bg(A){let g=!1;const I=A.keyed,B=uA((()=>A.when),void 0,{equals:(A,I)=>g?A===I:!A==!I});return uA((()=>{const Q=B();if(Q){const B=A.children,C="function"==typeof B&&B.length>0;return g=I||C,C?RA((()=>B(Q))):B}return A.fallback}),void 0,void 0)}function Qg(A){let g=!1,I=!1;const B=UA((()=>A.children)),Q=uA((()=>{let A=B();Array.isArray(A)||(A=[A]);for(let g=0;gA[0]===I[0]&&(g?A[1]===I[1]:!A[1]==!I[1])&&A[2]===I[2]});return uA((()=>{const[B,C,E]=Q();if(B<0)return A.fallback;const V=E.children,e="function"==typeof V&&V.length>0;return g=I||e,e?RA((()=>V(C))):V}),void 0,void 0)}function Cg(A){return A}const Eg="_$DX_DELEGATE";function Vg(A,g,I,B={}){let Q;return dA((B=>{Q=B,g===document?A():rg(g,A(),g.firstChild?null:void 0,I)}),B.owner),()=>{Q(),g.textContent=""}}function eg(A,g,I){const B=document.createElement("template");B.innerHTML=A;let Q=B.content.firstChild;return I&&(Q=Q.firstChild),Q}function ig(A,g=window.document){const I=g[Eg]||(g[Eg]=new Set);for(let B=0,Q=A.length;BB.call(A,I[1],g))}else A.addEventListener(g,I)}function sg(A,g,I){if(!g)return I?function(A,g,I){null==I?A.removeAttribute(g):A.setAttribute(g,I)}(A,"style"):g;const B=A.style;if("string"==typeof g)return B.cssText=g;let Q,C;for(C in"string"==typeof I&&(B.cssText=I=void 0),I||(I={}),g||(g={}),I)null==g[C]&&B.removeProperty(C),delete I[C];for(C in g)Q=g[C],Q!==I[C]&&(B.setProperty(C,Q),I[C]=Q);return I}function ng(A,g,I){return RA((()=>A(g,I)))}function rg(A,g,I,B){if(void 0===I||B||(B=[]),"function"!=typeof g)return cg(A,g,B,I);MA((B=>cg(A,g(),B,I)),B)}function ag(A){const g=`$$${A.type}`;let I=A.composedPath&&A.composedPath()[0]||A.target;for(A.target!==I&&Object.defineProperty(A,"target",{configurable:!0,value:I}),Object.defineProperty(A,"currentTarget",{configurable:!0,get:()=>I||document}),sA.registry&&!sA.done&&(sA.done=!0,document.querySelectorAll("[id^=pl-]").forEach((g=>{for(;g&&8!==g.nodeType&&g.nodeValue!=="pl-"+A;){let A=g.nextSibling;g.remove(),g=A}g&&g.remove()})));I;){const B=I[g];if(B&&!I.disabled){const Q=I[`${g}Data`];if(void 0!==Q?B.call(I,Q,A):B.call(I,A),A.cancelBubble)return}I=I._$host||I.parentNode||I.host}}function cg(A,g,I,B,Q){for(sA.context&&!I&&(I=[...A.childNodes]);"function"==typeof I;)I=I();if(g===I)return I;const C=typeof g,E=void 0!==B;if(A=E&&I[0]&&I[0].parentNode||A,"string"===C||"number"===C){if(sA.context)return I;if("number"===C&&(g=g.toString()),E){let Q=I[0];Q&&3===Q.nodeType?Q.data=g:Q=document.createTextNode(g),I=hg(A,I,B,Q)}else I=""!==I&&"string"==typeof I?A.firstChild.data=g:A.textContent=g}else if(null==g||"boolean"===C){if(sA.context)return I;I=hg(A,I,B)}else{if("function"===C)return MA((()=>{let Q=g();for(;"function"==typeof Q;)Q=Q();I=cg(A,Q,I,B)})),()=>I;if(Array.isArray(g)){const C=[],V=I&&Array.isArray(I);if(Dg(C,g,I,Q))return MA((()=>I=cg(A,C,I,B,!0))),()=>I;if(sA.context){if(!C.length)return I;for(let A=0;AB-V){const Q=g[E];for(;V=0;C--){const E=g[C];if(Q!==E){const g=E.parentNode===A;B||C?g&&E.remove():g?A.replaceChild(Q,E):A.insertBefore(Q,I)}else B=!0}}else A.insertBefore(Q,I);return[Q]}const lg=Symbol("store-raw"),yg=Symbol("store-node"),kg=Symbol("store-name");function Gg(A,g){let I=A[nA];if(!I&&(Object.defineProperty(A,nA,{value:I=new Proxy(A,fg)}),!Array.isArray(A))){const g=Object.keys(A),B=Object.getOwnPropertyDescriptors(A);for(let Q=0,C=g.length;Q!0,deleteProperty:()=>!0,ownKeys:function(A){return Mg(A),Reflect.ownKeys(A)},getOwnPropertyDescriptor:function(A,g){const I=Reflect.getOwnPropertyDescriptor(A,g);return I&&!I.get&&I.configurable&&g!==nA&&g!==yg&&g!==kg?(delete I.value,delete I.writable,I.get=()=>A[nA][g],I):I}};function Rg(A,g,I,B=!1){if(!B&&A[g]===I)return;const Q=A[g],C=A.length;void 0===I?delete A[g]:A[g]=I;let E,V=dg(A);(E=Ng(V,g,Q))&&E.$((()=>I)),Array.isArray(A)&&A.length!==C&&(E=Ng(V,"length",C))&&E.$(A.length),(E=V._)&&E.$()}function Jg(A,g){const I=Object.keys(g);for(let B=0;B1){B=g.shift();const C=typeof B,E=Array.isArray(A);if(Array.isArray(B)){for(let Q=0;Q1)return void Sg(A[B],g,[B].concat(I));Q=A[B],I=[B].concat(I)}let C=g[0];"function"==typeof C&&(C=C(Q,I),C===Q)||void 0===B&&null==C||(C=qg(C),void 0===B||Fg(Q)&&Fg(C)&&!Array.isArray(C)?Jg(Q,C):Rg(A,B,C))}function Yg(...[A,g]){const I=qg(A||{}),B=Array.isArray(I);return[Gg(I),function(...A){fA((()=>{B&&1===A.length?function(A,g){if("function"==typeof g&&(g=g(A)),g=qg(g),Array.isArray(g)){if(A===g)return;let I=0,B=g.length;for(;I=E&&e>=E&&(C[V]===A[e]||Q&&C[E]&&A[E]&&C[V][Q]===A[e][Q]);V--,e--)s[e]=C[V];if(E>e||E>V){for(I=E;I<=e;I++)Rg(C,I,A[I]);for(;IA.length&&Rg(C,"length",A.length))}for(t=new Array(e+1),I=e;I>=E;I--)i=A[I],o=Q&&i?i[Q]:i,g=n.get(o),t[I]=void 0===g?-1:g,n.set(o,I);for(g=E;g<=V;g++)i=C[g],o=Q&&i?i[Q]:i,I=n.get(o),void 0!==I&&-1!==I&&(s[I]=C[g],I=t[I],n.set(o,I));for(I=E;IA.length&&Rg(C,"length",A.length))}const E=Object.keys(A);for(let g=0,I=E.length;g{if(!Fg(A)||!Fg(Q))return Q;const g=pg(Q,{[Ug]:A},Ug,I,B);return void 0===g?A:g}}const mg=eg("");var Kg=A=>{const g=uA((()=>{if(1==A.text.length){const g=A.text.codePointAt(0);if(g>=9600&&g<=9631||57520==g||57522==g)return g}})),I=uA((()=>g()?" ":A.text)),B=uA((()=>function(A,g,I){const B=A.get("fg"),Q=A.get("bg");let C={"--offset":g,width:`${I+.01}ch`};"string"==typeof B&&(C["--fg"]=B);"string"==typeof Q&&(C["--bg"]=Q);return C}(A.pen,A.offset,A.width))),Q=uA((()=>function(A,g,I){const B=bg(A.get("fg"),A.get("bold"),"fg-"),Q=bg(A.get("bg"),!1,"bg-");let C=I??"";void 0!==g&&(C+=` cp-${g.toString(16)}`);B&&(C+=" "+B);Q&&(C+=" "+Q);A.has("bold")&&(C+=" ap-bright");A.has("faint")&&(C+=" ap-faint");A.has("italic")&&(C+=" ap-italic");A.has("underline")&&(C+=" ap-underline");A.has("blink")&&(C+=" ap-blink");A.get("inverse")&&(C+=" ap-inverse");return C}(A.pen,g(),A.extraClass)));return(()=>{const A=mg.cloneNode(!0);return rg(A,I),MA((g=>{const I=Q(),C=B();return I!==g._v$&&tg(A,g._v$=I),g._v$2=sg(A,C,g._v$2),g}),{_v$:void 0,_v$2:void 0}),A})()};function bg(A,g,I){if("number"==typeof A)return g&&A<8&&(A+=8),`${I}${A}`}const Hg=eg('');var vg=A=>(()=>{const g=Hg.cloneNode(!0);return rg(g,PA(Ig,{get each(){return(()=>{if("number"==typeof A.cursor){const g=[];let I=0,B=0;for(;B0&&g.push({...Q,text:Q.text.substring(0,C)}),g.push({...Q,text:Q.text[C],offset:Q.offset+C,extraClass:"ap-cursor"}),CPA(Kg,function(...A){let g=!1;for(let I=0;I=0;I--){const B=Ag(A[I])[g];if(void 0!==B)return B}},has(g){for(let I=A.length-1;I>=0;I--)if(g in Ag(A[I]))return!0;return!1},keys(){const g=[];for(let I=0;I=0;g--)if(A[g]){const B=Object.getOwnPropertyDescriptors(A[g]);for(const g in B)g in I||Object.defineProperty(I,g,{enumerable:!0,get(){for(let I=A.length-1;I>=0;I--){const B=(A[I]||{})[g];if(void 0!==B)return B}}})}return I}(A))})),g})();const Tg=eg('
');var Og=A=>{const g=()=>A.lineHeight??1.3333333333,I=uA((()=>({width:`${A.cols}ch`,height:g()*A.rows+"em","font-size":100*(A.scale||1)+"%","font-family":A.fontFamily,"--term-line-height":`${g()}em`,"--term-cols":A.cols}))),B=uA((()=>A.cursor?.[0])),Q=uA((()=>A.cursor?.[1]));return(()=>{const g=Tg.cloneNode(!0),C=A.ref;return"function"==typeof C?ng(C,g):A.ref=g,rg(g,PA(gg,{get each(){return A.lines},children:(A,g)=>PA(vg,{get segments(){return A.segments},get cursor(){return uA((()=>g()===Q()))()?B():null}})})),MA((B=>{const Q=!(!A.blink&&!A.cursorHold),C=!!A.blink,E=I();return Q!==B._v$&&g.classList.toggle("ap-cursor-on",B._v$=Q),C!==B._v$2&&g.classList.toggle("ap-blink",B._v$2=C),B._v$3=sg(g,E,B._v$3),B}),{_v$:void 0,_v$2:void 0,_v$3:void 0}),g})()};const xg=eg(''),jg=eg(''),Zg=eg(''),Wg=eg(''),Xg=eg('
Keyboard shortcuts (?)Fullscreen (f)
'),zg=eg('');function Pg(A){let g=Math.floor(A);const I=Math.floor(g/86400);g%=86400;const B=Math.floor(g/3600);g%=3600;const Q=Math.floor(g/60);return g%=60,I>0?`${_g(I)}:${_g(B)}:${_g(Q)}:${_g(g)}`:B>0?`${_g(B)}:${_g(Q)}:${_g(g)}`:`${_g(Q)}:${_g(g)}`}function _g(A){return A<10?`0${A}`:A.toString()}var $g=A=>{const g=A=>g=>{g.preventDefault(),A(g)},I=()=>"number"==typeof A.currentTime?Pg(A.currentTime):"--:--",B=()=>"number"==typeof A.remainingTime?"-"+Pg(A.remainingTime):I(),Q=uA((()=>"number"==typeof A.duration?A.markers.filter((g=>g[0]{const g=A.currentTarget.offsetWidth,I=A.currentTarget.getBoundingClientRect(),B=A.clientX-I.left;return 100*Math.max(0,B/g)+"%"},[E,V]=NA(!1),e=function(A,g){let I=!0;return function(){if(I){I=!1;for(var B=arguments.length,Q=new Array(B),C=0;CI=!0),g)}}}(A.onSeekClick,50),i=g=>{g._marker||g.altKey||g.shiftKey||g.metaKey||g.ctrlKey||0!==g.button||(V(!0),A.onSeekClick(C(g)))},t=A=>{A.altKey||A.shiftKey||A.metaKey||A.ctrlKey||E()&&e(C(A))},o=()=>{V(!1)};return document.addEventListener("mouseup",o),SA((()=>{document.removeEventListener("mouseup",o)})),(()=>{const C=Xg.cloneNode(!0),E=C.firstChild,V=E.firstChild,e=V.nextSibling,o=E.nextSibling,s=o.nextSibling,n=s.nextSibling,r=A.ref;return"function"==typeof r?ng(r,C):A.ref=C,rg(C,PA(Bg,{get when(){return A.isPausable},get children(){const I=Zg.cloneNode(!0);return og(I,"click",g(A.onPlayClick),!0),rg(I,PA(Qg,{get children(){return[PA(Cg,{get when(){return A.isPlaying},get children(){return xg.cloneNode(!0)}}),PA(Cg,{get when(){return!A.isPlaying},get children(){return jg.cloneNode(!0)}})]}})),I}}),E),rg(V,I),rg(e,B),rg(o,PA(Bg,{get when(){return"number"==typeof A.progress||A.isSeekable},get children(){const I=Wg.cloneNode(!0),B=I.firstChild.nextSibling;return I.$$mousemove=t,I.$$mousedown=i,rg(I,PA(gg,{get each(){return Q()},children:(I,B)=>(()=>{const Q=zg.cloneNode(!0),C=Q.firstChild,E=C.nextSibling;var V;return Q.$$mousedown=A=>{A._marker=!0},og(Q,"click",(V=B(),g((()=>{A.onSeekClick({marker:V})}))),!0),rg(E,(()=>(A=>""===A[1]?Pg(A[0]):`${Pg(A[0])} - ${A[1]}`)(I))),MA((g=>{const B=(g=>g[0]/A.duration*100+"%")(I),E=!!(g=>"number"==typeof A.currentTime&&g[0]<=A.currentTime)(I);return B!==g._v$&&Q.style.setProperty("left",g._v$=B),E!==g._v$2&&C.classList.toggle("ap-marker-past",g._v$2=E),g}),{_v$:void 0,_v$2:void 0}),Q})()}),null),MA((g=>sg(B,{transform:`scaleX(${A.progress||0}`},g))),I}})),og(s,"click",g(A.onHelpClick),!0),og(n,"click",g(A.onFullscreenClick),!0),MA((()=>C.classList.toggle("ap-seekable",!!A.isSeekable))),C})()};ig(["click","mousedown","mousemove"]);const AI=eg('
💥
');var gI=A=>AI.cloneNode(!0);const II=eg('
');var BI=A=>II.cloneNode(!0);const QI=eg('
');var CI=A=>(()=>{const g=QI.cloneNode(!0),I=g.firstChild;return rg(I,(()=>A.message)),MA((g=>sg(I,{"font-family":A.fontFamily},g))),g})();const EI=eg('
');var VI=A=>(()=>{const g=EI.cloneNode(!0);var I;return og(g,"click",(I=A.onClick,A=>{A.preventDefault(),I(A)}),!0),g})();ig(["click"]);const eI=eg("
  • space - pause / resume
  • "),iI=eg("
  • / - rewind / fast-forward by 5 seconds
  • "),tI=eg("
  • Shift + / - rewind / fast-forward by 10%
  • "),oI=eg("
  • [ / ] - jump to the previous / next marker
  • "),sI=eg("
  • 0, 1, 2 ... 9 - jump to 0%, 10%, 20% ... 90%
  • "),nI=eg("
  • , / . - step back / forward, a frame at a time (when paused)
  • "),rI=eg('

    Keyboard shortcuts

    • f - toggle fullscreen mode
    • ? - toggle this help popup
    ');var aI=A=>(()=>{const g=rI.cloneNode(!0),I=g.firstChild,B=I.firstChild.firstChild.nextSibling,Q=B.firstChild;var C;return og(g,"click",(C=A.onClose,A=>{A.preventDefault(),C(A)}),!0),I.$$click=A=>{A.stopPropagation()},rg(B,PA(Bg,{get when(){return A.isPausable},get children(){return eI.cloneNode(!0)}}),Q),rg(B,PA(Bg,{get when(){return A.isSeekable},get children(){return[iI.cloneNode(!0),tI.cloneNode(!0),oI.cloneNode(!0),sI.cloneNode(!0),nI.cloneNode(!0)]}}),Q),MA((I=>sg(g,{"font-family":A.fontFamily},I))),g})();ig(["click"]);const cI=eg('
    ');var DI=A=>{const g=A.logger,I=A.core,B=A.autoPlay,[Q,C]=Yg({lines:[],cursor:void 0,charW:A.charW,charH:A.charH,bordersW:A.bordersW,bordersH:A.bordersH,containerW:0,containerH:0,isPausable:!0,isSeekable:!0,isFullscreen:!1,currentTime:null,remainingTime:null,progress:null,blink:!0,cursorHold:!1}),[E,V]=NA(!1),[e,i]=NA(B?null:"start"),[t,o]=NA(null),[s,n]=NA({cols:A.cols,rows:A.rows},{equals:(A,g)=>A.cols===g.cols&&A.rows===g.rows}),[r,a]=NA(void 0),[c,D]=Yg([]),[w,h]=NA(!1),[l,y]=NA(!1),[k,G]=NA(void 0),F=uA((()=>s().cols||80)),q=uA((()=>s().rows||24)),d=()=>!1===A.controls?0:32;let N,M,u,f,R,J,S,Y,U,p;function L(){gA(),_(),$()}function m(A){fA((()=>{A.rows{p=A}));I.addEventListener("ready",(A=>{let{isPausable:g,isSeekable:I,poster:B}=A;C({isPausable:g,isSeekable:I}),K(B),p()})),I.addEventListener("metadata",(A=>{let{cols:g,rows:I,duration:B,theme:Q,poster:C,markers:E}=A;fA((()=>{m({cols:g,rows:I}),a(B),G(Q),D(E),K(C)}))})),I.addEventListener("play",(()=>{i(null)})),I.addEventListener("playing",(()=>{fA((()=>{V(!0),i(null),T(),AA(),P()}))})),I.addEventListener("idle",(()=>{fA((()=>{V(!1),L()}))})),I.addEventListener("loading",(()=>{fA((()=>{V(!1),L(),i("loader")}))})),I.addEventListener("offline",(A=>{let{message:g}=A;fA((()=>{V(!1),L(),void 0!==g&&(o(g),i("info"))}))}));let H=0;I.addEventListener("ended",(A=>{let{message:I}=A;fA((()=>{V(!1),L(),void 0!==I&&(o(I),i("info"))})),g.debug(`view: render count: ${H}`)})),I.addEventListener("errored",(()=>{i("error")})),I.addEventListener("resize",m),I.addEventListener("reset",(A=>{let{cols:g,rows:I,theme:B}=A;fA((()=>{m({cols:g,rows:I}),G(B),T()}))})),I.addEventListener("seeked",(()=>{$()})),I.addEventListener("terminalUpdate",(()=>{void 0===N&&(N=requestAnimationFrame(T))}));const v=()=>{U=new ResizeObserver(function(A,g){let I;return function(){for(var B=arguments.length,Q=new Array(B),C=0;CA.apply(this,Q)),g)}}((A=>{C({containerW:R.offsetWidth,containerH:R.offsetHeight}),R.dispatchEvent(new CustomEvent("resize",{detail:{el:J}}))}),10)),U.observe(R)};JA((async()=>{g.info("view: mounted"),g.debug("view: font measurements",{charW:Q.charW,charH:Q.charH}),v(),C({containerW:R.offsetWidth,containerH:R.offsetHeight})})),SA((()=>{I.stop(),gA(),_(),U.disconnect()}));const T=async()=>{const A=await I.getChanges();fA((()=>{void 0!==A.lines&&A.lines.forEach(((A,g)=>{C("lines",g,Lg(A))})),void 0!==A.cursor&&C("cursor",Lg(A.cursor)),C("cursorHold",!0)})),N=void 0,H+=1},O=uA((()=>{const g=Q.charW*F()+Q.bordersW,I=Q.charH*q()+Q.bordersH;let B=A.fit??"width";if("both"===B||Q.isFullscreen){B=Q.containerW/(Q.containerH-d())>g/I?"height":"width"}if(!1===B||"none"===B)return{};if("width"===B){const A=Q.containerW/g;return{scale:A,width:Q.containerW,height:I*A+d()}}if("height"===B){const A=(Q.containerH-d())/I;return{scale:A,width:g*A,height:Q.containerH}}throw`unsupported fit mode: ${B}`})),x=()=>{C("isFullscreen",document.fullscreenElement??document.webkitFullscreenElement)},j=()=>{Q.isFullscreen?(document.exitFullscreen??document.webkitExitFullscreen??(()=>{})).apply(document):(R.requestFullscreen??R.webkitRequestFullscreen??(()=>{})).apply(R)},Z=()=>{l()?y(!1):(I.pause(),y(!0))},W=A=>{if(!(A.altKey||A.metaKey||A.ctrlKey)){if(" "==A.key)I.togglePlay();else if(","==A.key)I.step(-1),$();else if("."==A.key)I.step(),$();else if("f"==A.key)j();else if("["==A.key)I.seek({marker:"prev"});else if("]"==A.key)I.seek({marker:"next"});else if(A.key.charCodeAt(0)>=48&&A.key.charCodeAt(0)<=57){const g=(A.key.charCodeAt(0)-48)/10;I.seek(100*g+"%")}else if("?"==A.key)Z();else if("ArrowLeft"==A.key)A.shiftKey?I.seek("<<<"):I.seek("<<");else if("ArrowRight"==A.key)A.shiftKey?I.seek(">>>"):I.seek(">>");else{if("Escape"!=A.key)return;y(!1)}A.stopPropagation(),A.preventDefault()}},X=()=>{Q.isFullscreen&&IA(!0)},z=()=>{Q.isFullscreen||IA(!1)},P=()=>{u=setInterval($,100)},_=()=>{clearInterval(u)},$=async()=>{const A=await I.getCurrentTime(),g=await I.getRemainingTime(),B=await I.getProgress();C({currentTime:A,remainingTime:g,progress:B})},AA=()=>{f=setInterval((()=>{C((A=>{const g={blink:!A.blink};return g.blink&&(g.cursorHold=!1),g}))}),500)},gA=()=>{clearInterval(f),C("blink",!0)},IA=A=>{clearTimeout(M),A&&(M=setTimeout((()=>IA(!1)),2e3)),h(A)},BA=uA((()=>{const g=A.theme||"auto/asciinema";return"auto/"===g.slice(0,5)?{name:g.slice(5),colors:k()}:{name:g}})),QA=()=>{b.then((()=>I.play()))},CA=()=>{b.then((()=>I.togglePlay()))},EA=A=>{b.then((()=>I.seek(A)))},VA=(()=>{const g=cI.cloneNode(!0),I=g.firstChild;"function"==typeof R?ng(R,g):R=g,g.addEventListener("webkitfullscreenchange",x),g.addEventListener("fullscreenchange",x),g.$$mousemove=X,g.$$keydown=W;return"function"==typeof J?ng(J,I):J=I,I.$$mousemove=()=>IA(!0),I.addEventListener("mouseleave",z),rg(I,PA(Og,{get cols(){return F()},get rows(){return q()},get scale(){return O()?.scale},get blink(){return Q.blink},get lines(){return Q.lines},get cursor(){return Q.cursor},get cursorHold(){return Q.cursorHold},get fontFamily(){return A.terminalFontFamily},get lineHeight(){return A.terminalLineHeight},ref(A){"function"==typeof S?S(A):S=A}}),null),rg(I,PA(Bg,{get when(){return!1!==A.controls},get children(){return PA($g,{get duration(){return r()},get currentTime(){return Q.currentTime},get remainingTime(){return Q.remainingTime},get progress(){return Q.progress},markers:c,get isPlaying(){return E()},get isPausable(){return Q.isPausable},get isSeekable(){return Q.isSeekable},onPlayClick:CA,onFullscreenClick:j,onHelpClick:Z,onSeekClick:EA,ref(A){"function"==typeof Y?Y(A):Y=A}})}}),null),rg(I,PA(Qg,{get children(){return[PA(Cg,{get when(){return"start"==e()},get children(){return PA(VI,{onClick:QA})}}),PA(Cg,{get when(){return"loader"==e()},get children(){return PA(BI,{})}}),PA(Cg,{get when(){return"info"==e()},get children(){return PA(CI,{get message(){return t()},get fontFamily(){return A.terminalFontFamily}})}}),PA(Cg,{get when(){return"error"==e()},get children(){return PA(gI,{})}})]}}),null),rg(I,PA(Bg,{get when(){return l()},get children(){return PA(aI,{get fontFamily(){return A.terminalFontFamily},onClose:()=>y(!1),get isPausable(){return Q.isPausable},get isSeekable(){return Q.isSeekable}})}}),null),MA((B=>{const Q=!!(!0===A.controls||"auto"===A.controls&&w()),C=`ap-player asciinema-player-theme-${BA().name}`,E=(()=>{const g={};!1!==A.fit&&"none"!==A.fit||void 0===A.terminalFontSize||("small"===A.terminalFontSize?g["font-size"]="12px":"medium"===A.terminalFontSize?g["font-size"]="18px":"big"===A.terminalFontSize?g["font-size"]="24px":g["font-size"]=A.terminalFontSize);const I=O();void 0!==I.width&&(g.width=`${I.width}px`,g.height=`${I.height}px`);const B=BA().colors;return B&&(g["--term-color-foreground"]=B.foreground,g["--term-color-background"]=B.background,B.palette.forEach(((A,I)=>{g[`--term-color-${I}`]=A}))),g})();return Q!==B._v$&&g.classList.toggle("ap-hud",B._v$=Q),C!==B._v$2&&tg(I,B._v$2=C),B._v$3=sg(I,E,B._v$3),B}),{_v$:void 0,_v$2:void 0,_v$3:void 0}),g})();return VA};function wI(A,g){let I=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const B=function(A,g){const I=80,B=24,Q=document.createElement("div");let C;Q.style.height="0px",Q.style.overflow="hidden",Q.style.fontSize="15px",document.body.appendChild(Q);const E=Vg((()=>(C=PA(Og,{cols:I,rows:B,lineHeight:g,fontFamily:A,lines:[]}),C)),Q),V={charW:C.clientWidth/I,charH:C.clientHeight/B,bordersW:C.offsetWidth-C.clientWidth,bordersH:C.offsetHeight-C.clientHeight};return E(),document.body.removeChild(Q),V}(I.terminalFontFamily,I.terminalLineHeight),Q={core:A,logger:I.logger,cols:I.cols,rows:I.rows,fit:I.fit,controls:I.controls,autoPlay:I.autoPlay,terminalFontSize:I.terminalFontSize,terminalFontFamily:I.terminalFontFamily,terminalLineHeight:I.terminalLineHeight,theme:I.theme,...B};let C;const E=Vg((()=>(C=PA(DI,Q),C)),g);return{el:C,dispose:E}}ig(["keydown","mousemove"]);const hI=["autoPlay","autoplay","cols","idleTimeLimit","loop","markers","pauseOnMarkers","poster","preload","rows","speed","startAt"],lI=["autoPlay","autoplay","cols","controls","fit","rows","terminalFontFamily","terminalFontSize","terminalLineHeight","theme"];return A.create=function(A,g){let B=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const Q=B.logger??new I,C=new iA(A,function(A){let g=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const I=Object.fromEntries(Object.entries(A).filter((A=>{let[g]=A;return hI.includes(g)})));return I.autoPlay??=I.autoplay,I.speed??=1,{...I,...g}}(B,{logger:Q})),{el:E,dispose:V}=wI(C,g,function(A){let g=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const I=Object.fromEntries(Object.entries(A).filter((A=>{let[g]=A;return lI.includes(g)})));return I.autoPlay??=I.autoplay,I.controls??="auto",{...I,...g}}(B,{logger:Q})),e=C.init(),i={el:E,dispose:V,getCurrentTime:()=>e.then(C.getCurrentTime.bind(C)),getDuration:()=>e.then(C.getDuration.bind(C)),play:()=>e.then(C.play.bind(C)),pause:()=>e.then(C.pause.bind(C)),seek:A=>e.then((()=>C.seek(A))),addEventListener:(A,g)=>C.addEventListener(A,g.bind(i))};return i},A}({}); diff --git a/aider/website/assets/audio/auto-accept-architect/00-01.mp3 b/aider/website/assets/audio/auto-accept-architect/00-01.mp3 new file mode 100644 index 000000000..a3f2cb496 Binary files /dev/null and b/aider/website/assets/audio/auto-accept-architect/00-01.mp3 differ diff --git a/aider/website/assets/audio/auto-accept-architect/00-11.mp3 b/aider/website/assets/audio/auto-accept-architect/00-11.mp3 new file mode 100644 index 000000000..75b3724f0 Binary files /dev/null and b/aider/website/assets/audio/auto-accept-architect/00-11.mp3 differ diff --git a/aider/website/assets/audio/auto-accept-architect/00-40.mp3 b/aider/website/assets/audio/auto-accept-architect/00-40.mp3 new file mode 100644 index 000000000..3c2f3e7d6 Binary files /dev/null and b/aider/website/assets/audio/auto-accept-architect/00-40.mp3 differ diff --git a/aider/website/assets/audio/auto-accept-architect/00-48.mp3 b/aider/website/assets/audio/auto-accept-architect/00-48.mp3 new file mode 100644 index 000000000..80ba920a9 Binary files /dev/null and b/aider/website/assets/audio/auto-accept-architect/00-48.mp3 differ diff --git a/aider/website/assets/audio/auto-accept-architect/01-00.mp3 b/aider/website/assets/audio/auto-accept-architect/01-00.mp3 new file mode 100644 index 000000000..719ade695 Binary files /dev/null and b/aider/website/assets/audio/auto-accept-architect/01-00.mp3 differ diff --git a/aider/website/assets/audio/auto-accept-architect/01-28.mp3 b/aider/website/assets/audio/auto-accept-architect/01-28.mp3 new file mode 100644 index 000000000..e23d70786 Binary files /dev/null and b/aider/website/assets/audio/auto-accept-architect/01-28.mp3 differ diff --git a/aider/website/assets/audio/auto-accept-architect/01-42.mp3 b/aider/website/assets/audio/auto-accept-architect/01-42.mp3 new file mode 100644 index 000000000..19804c26b Binary files /dev/null and b/aider/website/assets/audio/auto-accept-architect/01-42.mp3 differ diff --git a/aider/website/assets/audio/auto-accept-architect/02-00.mp3 b/aider/website/assets/audio/auto-accept-architect/02-00.mp3 new file mode 100644 index 000000000..a2bab171c Binary files /dev/null and b/aider/website/assets/audio/auto-accept-architect/02-00.mp3 differ diff --git a/aider/website/assets/audio/auto-accept-architect/02-05.mp3 b/aider/website/assets/audio/auto-accept-architect/02-05.mp3 new file mode 100644 index 000000000..752b3f86c Binary files /dev/null and b/aider/website/assets/audio/auto-accept-architect/02-05.mp3 differ diff --git a/aider/website/assets/audio/auto-accept-architect/metadata.json b/aider/website/assets/audio/auto-accept-architect/metadata.json new file mode 100644 index 000000000..d3185544b --- /dev/null +++ b/aider/website/assets/audio/auto-accept-architect/metadata.json @@ -0,0 +1,11 @@ +{ + "00-01": "We're going to add a new feature to automatically accept edits proposed by the architect model.", + "00-11": "First, let's add the new switch.", + "00-40": "Aider figured out that it should be passed to the Coder class.", + "00-48": "Now we need to implement the functionality.", + "01-00": "Let's do some manual testing.", + "01-28": "That worked. Let's make sure we can turn it off too.", + "02-00": "Let's quickly tidy up the changes to HISTORY.", + "02-05": "All done!", + "01-42": "That worked too. Let's have aider update the HISTORY file to document the new feature." +} \ No newline at end of file diff --git a/aider/website/assets/audio/dont-drop-original-read-files/00-01.mp3 b/aider/website/assets/audio/dont-drop-original-read-files/00-01.mp3 new file mode 100644 index 000000000..30a9138cf Binary files /dev/null and b/aider/website/assets/audio/dont-drop-original-read-files/00-01.mp3 differ diff --git a/aider/website/assets/audio/dont-drop-original-read-files/00-10.mp3 b/aider/website/assets/audio/dont-drop-original-read-files/00-10.mp3 new file mode 100644 index 000000000..61fd0d612 Binary files /dev/null and b/aider/website/assets/audio/dont-drop-original-read-files/00-10.mp3 differ diff --git a/aider/website/assets/audio/dont-drop-original-read-files/00-20.mp3 b/aider/website/assets/audio/dont-drop-original-read-files/00-20.mp3 new file mode 100644 index 000000000..0d08c1664 Binary files /dev/null and b/aider/website/assets/audio/dont-drop-original-read-files/00-20.mp3 differ diff --git a/aider/website/assets/audio/dont-drop-original-read-files/01-20.mp3 b/aider/website/assets/audio/dont-drop-original-read-files/01-20.mp3 new file mode 100644 index 000000000..f60c9cf01 Binary files /dev/null and b/aider/website/assets/audio/dont-drop-original-read-files/01-20.mp3 differ diff --git a/aider/website/assets/audio/dont-drop-original-read-files/01-30.mp3 b/aider/website/assets/audio/dont-drop-original-read-files/01-30.mp3 new file mode 100644 index 000000000..62e123446 Binary files /dev/null and b/aider/website/assets/audio/dont-drop-original-read-files/01-30.mp3 differ diff --git a/aider/website/assets/audio/dont-drop-original-read-files/01-45.mp3 b/aider/website/assets/audio/dont-drop-original-read-files/01-45.mp3 new file mode 100644 index 000000000..ea4c98253 Binary files /dev/null and b/aider/website/assets/audio/dont-drop-original-read-files/01-45.mp3 differ diff --git a/aider/website/assets/audio/dont-drop-original-read-files/02-10.mp3 b/aider/website/assets/audio/dont-drop-original-read-files/02-10.mp3 new file mode 100644 index 000000000..63527e6e8 Binary files /dev/null and b/aider/website/assets/audio/dont-drop-original-read-files/02-10.mp3 differ diff --git a/aider/website/assets/audio/dont-drop-original-read-files/02-19.mp3 b/aider/website/assets/audio/dont-drop-original-read-files/02-19.mp3 new file mode 100644 index 000000000..3c26a9589 Binary files /dev/null and b/aider/website/assets/audio/dont-drop-original-read-files/02-19.mp3 differ diff --git a/aider/website/assets/audio/dont-drop-original-read-files/02-50.mp3 b/aider/website/assets/audio/dont-drop-original-read-files/02-50.mp3 new file mode 100644 index 000000000..b168823ce Binary files /dev/null and b/aider/website/assets/audio/dont-drop-original-read-files/02-50.mp3 differ diff --git a/aider/website/assets/audio/dont-drop-original-read-files/metadata.json b/aider/website/assets/audio/dont-drop-original-read-files/metadata.json new file mode 100644 index 000000000..9c7b354f7 --- /dev/null +++ b/aider/website/assets/audio/dont-drop-original-read-files/metadata.json @@ -0,0 +1,11 @@ +{ + "00-10": "We've added files that handle the main CLI and in-chat slash commands like /drop.", + "00-20": "Let's explain the needed change to aider.", + "01-20": "Ok, let's look at the code.", + "01-30": "I'd prefer not to use \"hasattr()\", let's ask for improvements.", + "01-45": "Let's try some manual testing.", + "02-10": "Looks good. Let's check the existing test suite to ensure we didn't break anything.", + "02-19": "Let's ask aider to add tests for this.", + "02-50": "Tests look reasonable, we're done!", + "00-01": "We're going to update the /drop command to keep any read only files that were originally specified at launch." +} \ No newline at end of file diff --git a/aider/website/assets/audio/model-accepts-settings/00-01.mp3 b/aider/website/assets/audio/model-accepts-settings/00-01.mp3 new file mode 100644 index 000000000..ae766a784 Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/00-01.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/00-25.mp3 b/aider/website/assets/audio/model-accepts-settings/00-25.mp3 new file mode 100644 index 000000000..03288fa39 Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/00-25.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/01-30.mp3 b/aider/website/assets/audio/model-accepts-settings/01-30.mp3 new file mode 100644 index 000000000..9c7d66f3e Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/01-30.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/01-45.mp3 b/aider/website/assets/audio/model-accepts-settings/01-45.mp3 new file mode 100644 index 000000000..f2837b7ec Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/01-45.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/02-00.mp3 b/aider/website/assets/audio/model-accepts-settings/02-00.mp3 new file mode 100644 index 000000000..fcbfb04e9 Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/02-00.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/03-00.mp3 b/aider/website/assets/audio/model-accepts-settings/03-00.mp3 new file mode 100644 index 000000000..49a28b7e2 Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/03-00.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/03-45.mp3 b/aider/website/assets/audio/model-accepts-settings/03-45.mp3 new file mode 100644 index 000000000..4e3cf5953 Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/03-45.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/04-45.mp3 b/aider/website/assets/audio/model-accepts-settings/04-45.mp3 new file mode 100644 index 000000000..a0a149b8d Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/04-45.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/05-00.mp3 b/aider/website/assets/audio/model-accepts-settings/05-00.mp3 new file mode 100644 index 000000000..712c73656 Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/05-00.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/05-10.mp3 b/aider/website/assets/audio/model-accepts-settings/05-10.mp3 new file mode 100644 index 000000000..c7720262c Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/05-10.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/06-00.mp3 b/aider/website/assets/audio/model-accepts-settings/06-00.mp3 new file mode 100644 index 000000000..d90f4993e Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/06-00.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/07-43.mp3 b/aider/website/assets/audio/model-accepts-settings/07-43.mp3 new file mode 100644 index 000000000..12e56dc28 Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/07-43.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/09-20.mp3 b/aider/website/assets/audio/model-accepts-settings/09-20.mp3 new file mode 100644 index 000000000..cc3bb03da Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/09-20.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/10-20.mp3 b/aider/website/assets/audio/model-accepts-settings/10-20.mp3 new file mode 100644 index 000000000..16a60047b Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/10-20.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/10-41.mp3 b/aider/website/assets/audio/model-accepts-settings/10-41.mp3 new file mode 100644 index 000000000..131650279 Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/10-41.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/10-55.mp3 b/aider/website/assets/audio/model-accepts-settings/10-55.mp3 new file mode 100644 index 000000000..9a95cda50 Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/10-55.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/11-28.mp3 b/aider/website/assets/audio/model-accepts-settings/11-28.mp3 new file mode 100644 index 000000000..57335a1ea Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/11-28.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/12-00.mp3 b/aider/website/assets/audio/model-accepts-settings/12-00.mp3 new file mode 100644 index 000000000..a87d8c9dc Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/12-00.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/12-32.mp3 b/aider/website/assets/audio/model-accepts-settings/12-32.mp3 new file mode 100644 index 000000000..ba1b34b91 Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/12-32.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/12-48.mp3 b/aider/website/assets/audio/model-accepts-settings/12-48.mp3 new file mode 100644 index 000000000..2515c6499 Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/12-48.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/13-00.mp3 b/aider/website/assets/audio/model-accepts-settings/13-00.mp3 new file mode 100644 index 000000000..db16d1e11 Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/13-00.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/14-30.mp3 b/aider/website/assets/audio/model-accepts-settings/14-30.mp3 new file mode 100644 index 000000000..563231f17 Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/14-30.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/14-45.mp3 b/aider/website/assets/audio/model-accepts-settings/14-45.mp3 new file mode 100644 index 000000000..0f870f836 Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/14-45.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/14-59.mp3 b/aider/website/assets/audio/model-accepts-settings/14-59.mp3 new file mode 100644 index 000000000..65f2247d2 Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/14-59.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/15-09.mp3 b/aider/website/assets/audio/model-accepts-settings/15-09.mp3 new file mode 100644 index 000000000..fd831dd86 Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/15-09.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/15-34.mp3 b/aider/website/assets/audio/model-accepts-settings/15-34.mp3 new file mode 100644 index 000000000..fb6bffe6b Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/15-34.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/15-44.mp3 b/aider/website/assets/audio/model-accepts-settings/15-44.mp3 new file mode 100644 index 000000000..0822147c9 Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/15-44.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/16-04.mp3 b/aider/website/assets/audio/model-accepts-settings/16-04.mp3 new file mode 100644 index 000000000..26231d85c Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/16-04.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/16-14.mp3 b/aider/website/assets/audio/model-accepts-settings/16-14.mp3 new file mode 100644 index 000000000..d431c03d4 Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/16-14.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/16-29.mp3 b/aider/website/assets/audio/model-accepts-settings/16-29.mp3 new file mode 100644 index 000000000..f3f4ad358 Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/16-29.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/16-47.mp3 b/aider/website/assets/audio/model-accepts-settings/16-47.mp3 new file mode 100644 index 000000000..7e770950c Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/16-47.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/16-55.mp3 b/aider/website/assets/audio/model-accepts-settings/16-55.mp3 new file mode 100644 index 000000000..62b20bf9f Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/16-55.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/17-59.mp3 b/aider/website/assets/audio/model-accepts-settings/17-59.mp3 new file mode 100644 index 000000000..cd1fbd8f6 Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/17-59.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/18-35.mp3 b/aider/website/assets/audio/model-accepts-settings/18-35.mp3 new file mode 100644 index 000000000..deb37d2ad Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/18-35.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/19-44.mp3 b/aider/website/assets/audio/model-accepts-settings/19-44.mp3 new file mode 100644 index 000000000..9b70789f5 Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/19-44.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/19-54.mp3 b/aider/website/assets/audio/model-accepts-settings/19-54.mp3 new file mode 100644 index 000000000..195a77385 Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/19-54.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/20-25.mp3 b/aider/website/assets/audio/model-accepts-settings/20-25.mp3 new file mode 100644 index 000000000..f0e80535a Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/20-25.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/20-55.mp3 b/aider/website/assets/audio/model-accepts-settings/20-55.mp3 new file mode 100644 index 000000000..22d5e0b61 Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/20-55.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/21-10.mp3 b/aider/website/assets/audio/model-accepts-settings/21-10.mp3 new file mode 100644 index 000000000..5bc319d9c Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/21-10.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/22-32.mp3 b/aider/website/assets/audio/model-accepts-settings/22-32.mp3 new file mode 100644 index 000000000..79861e041 Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/22-32.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/24-25.mp3 b/aider/website/assets/audio/model-accepts-settings/24-25.mp3 new file mode 100644 index 000000000..c46021a0c Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/24-25.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/24-56.mp3 b/aider/website/assets/audio/model-accepts-settings/24-56.mp3 new file mode 100644 index 000000000..95436c938 Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/24-56.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/25-35.mp3 b/aider/website/assets/audio/model-accepts-settings/25-35.mp3 new file mode 100644 index 000000000..942e2db22 Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/25-35.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/26-20.mp3 b/aider/website/assets/audio/model-accepts-settings/26-20.mp3 new file mode 100644 index 000000000..3f4f8ff83 Binary files /dev/null and b/aider/website/assets/audio/model-accepts-settings/26-20.mp3 differ diff --git a/aider/website/assets/audio/model-accepts-settings/metadata.json b/aider/website/assets/audio/model-accepts-settings/metadata.json new file mode 100644 index 000000000..b9ce5c335 --- /dev/null +++ b/aider/website/assets/audio/model-accepts-settings/metadata.json @@ -0,0 +1,46 @@ +{ + "00-01": "Users sometimes run aider with \"reasoning\" settings that aren't supported by the model they're using. This can cause LLM API calls to completely fail, with non-specific error messages from the API provider. We're going to warn users up front to prevent this.", + "01-30": "Looks like it's including some extra changes we don't want.", + "01-45": "Let's have a look at the models code and clean up some stray lines.", + "02-00": "It also made the warning logic too conservative. We want to warn unless the setting is explicitly known to be supported.", + "03-00": "Ok, good. Now lets add a setting to silence these warnings for power users who are doing something intentional.", + "03-45": "Now we need to update the database of model settings to annotate which models support which reasoning settings. We'll start with the code that handles \"fallback\" settings for known models on unknown providers.", + "04-45": "Oh, we forgot to give aider the actual file with that code! Aider asks to see it.", + "05-00": "Ok, we've confused aider by asking it to change code it couldn't see.", + "05-10": "Let's clear the chat and refine the prompt and try again.", + "06-00": "Ok, looks good. Let's move on and update the full model settings database YAML file. Each main model like \"o1\" appears here from many providers, like OpenAI, OpenRouter, etc. We want to update them all.", + "09-20": "Looks good. Let's review the YAML file and eyeball all the relevant models.", + "10-20": "Now let's do some manual testing.", + "10-55": "Let's see if aider can spot the problem?", + "11-28": "That doesn't sound like a promising solution. Let's add more of the relevant code, clear history and try again.", + "12-00": "Ok, let's try aider's proposed solution.", + "12-48": "Time for some manual print debugging.", + "13-00": "It seems like the \"accept_settings\" value is not being set?", + "14-30": "Aha! I have a local model settings file for Sonnet which overrides aider's built in settings. And we did not update it. Let's add \"accepts_settings\" there.", + "14-45": "That was the problem, it wasn't a bug.", + "14-59": "Ok, let's add test coverage for all this stuff.", + "15-09": "And while aider writes tests, let's use \"git diff\" to review all the changes we've made.", + "15-34": "Aider is done writing tests, let's try them.", + "15-44": "One passed, one failed. Let's eyeball the passing test first.", + "16-04": "And let's see if aider can fix the failing test.", + "16-14": "Aider needs to see another file, which makes sense.", + "16-29": "It's found the problem, but is trying to \"fix\" the code. We want it to fix the test.", + "16-47": "Ok, tests are passing.", + "16-55": "We should stop and ask the user \"are you sure?\", not just flash a warning if they're about to break their API calls.", + "17-59": "Ok, that confirmation dialog looks good.", + "18-35": "This code is a little bit repetitive. Let's do a bit of refactoring.", + "20-25": "Are tests still passing after the refactor?", + "20-55": "Tests passed, good. Let's tweak the warning text.", + "21-10": "And now let's have aider update the docs to explain these changes.", + "22-32": "Let's proofread and edit the updated docs.", + "24-25": "And a \"git diff\" of all the docs changes to do a final check.", + "24-56": "Let's have aider update the project's HISTORY file.", + "26-20": "All done!", + "00-25": "Ok, let's ask aider to add a new model setting where we can note which reasoning settings it supports. And then print a warning if the user tries to apply an unsupported setting.", + "07-43": "Let's interrupt and refine the prompt to be more clear about which models to update.", + "10-41": "Ok, it should not be warning us about using \"thinking tokens\" with Sonnet 3.7.", + "12-32": "And see if it worked... Nope! Still getting the unneeded warning. Undo that change!", + "19-44": "Sonnet is messing up the code editing instructions, so aider is retrying.", + "19-54": "Let's clear the chat history and try again.", + "25-35": "We can refine the HISTORY entries a bit." +} \ No newline at end of file diff --git a/aider/website/assets/audio/tree-sitter-language-pack/00-01.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/00-01.mp3 new file mode 100644 index 000000000..8fb957b00 Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/00-01.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/00-10.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/00-10.mp3 new file mode 100644 index 000000000..1cfa695a3 Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/00-10.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/01-00.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/01-00.mp3 new file mode 100644 index 000000000..b101c22e9 Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/01-00.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/01-10.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/01-10.mp3 new file mode 100644 index 000000000..69d768aa9 Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/01-10.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/01-29.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/01-29.mp3 new file mode 100644 index 000000000..057ddde63 Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/01-29.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/01-45.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/01-45.mp3 new file mode 100644 index 000000000..12171999d Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/01-45.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/02-05.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/02-05.mp3 new file mode 100644 index 000000000..073e5253a Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/02-05.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/03-37.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/03-37.mp3 new file mode 100644 index 000000000..5e00df9ed Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/03-37.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/04-19.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/04-19.mp3 new file mode 100644 index 000000000..225844442 Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/04-19.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/05-02.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/05-02.mp3 new file mode 100644 index 000000000..674b9f1d2 Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/05-02.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/05-55.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/05-55.mp3 new file mode 100644 index 000000000..d304a6aba Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/05-55.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/06-12.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/06-12.mp3 new file mode 100644 index 000000000..977347c9b Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/06-12.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/06-30.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/06-30.mp3 new file mode 100644 index 000000000..5b698f78d Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/06-30.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/09-02.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/09-02.mp3 new file mode 100644 index 000000000..882ad92ed Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/09-02.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/09-45.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/09-45.mp3 new file mode 100644 index 000000000..a932d475f Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/09-45.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/10-15.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/10-15.mp3 new file mode 100644 index 000000000..1b09a4c65 Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/10-15.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/11-15.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/11-15.mp3 new file mode 100644 index 000000000..70a82b8f2 Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/11-15.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/12-00.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/12-00.mp3 new file mode 100644 index 000000000..056d7837a Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/12-00.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/13-00.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/13-00.mp3 new file mode 100644 index 000000000..10ab3895d Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/13-00.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/14-00.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/14-00.mp3 new file mode 100644 index 000000000..af62e280d Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/14-00.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/16-07.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/16-07.mp3 new file mode 100644 index 000000000..e66fcffcf Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/16-07.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/16-16.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/16-16.mp3 new file mode 100644 index 000000000..430adead8 Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/16-16.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/16-33.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/16-33.mp3 new file mode 100644 index 000000000..0a3abb2aa Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/16-33.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/17-01.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/17-01.mp3 new file mode 100644 index 000000000..88aec8d6b Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/17-01.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/17-12.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/17-12.mp3 new file mode 100644 index 000000000..a45e86f93 Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/17-12.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/19-04.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/19-04.mp3 new file mode 100644 index 000000000..68573f57e Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/19-04.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/19-28.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/19-28.mp3 new file mode 100644 index 000000000..ac4368128 Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/19-28.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/20-20.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/20-20.mp3 new file mode 100644 index 000000000..9fcdfbf76 Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/20-20.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/20-50.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/20-50.mp3 new file mode 100644 index 000000000..e8442e10a Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/20-50.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/21-30.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/21-30.mp3 new file mode 100644 index 000000000..58793d46e Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/21-30.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/24-39.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/24-39.mp3 new file mode 100644 index 000000000..4bd9b922c Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/24-39.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/26-55.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/26-55.mp3 new file mode 100644 index 000000000..004daa8eb Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/26-55.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/27-10.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/27-10.mp3 new file mode 100644 index 000000000..8d30466f0 Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/27-10.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/27-19.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/27-19.mp3 new file mode 100644 index 000000000..1d0acac46 Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/27-19.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/27-50.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/27-50.mp3 new file mode 100644 index 000000000..a4e353f22 Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/27-50.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/28-12.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/28-12.mp3 new file mode 100644 index 000000000..ef3fa8435 Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/28-12.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/28-52.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/28-52.mp3 new file mode 100644 index 000000000..d5c3749e7 Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/28-52.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/29-27.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/29-27.mp3 new file mode 100644 index 000000000..f19f776a9 Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/29-27.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/30-25.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/30-25.mp3 new file mode 100644 index 000000000..63805e87d Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/30-25.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/30-37.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/30-37.mp3 new file mode 100644 index 000000000..67ca0999a Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/30-37.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/31-52.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/31-52.mp3 new file mode 100644 index 000000000..9aa50b655 Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/31-52.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/32-27.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/32-27.mp3 new file mode 100644 index 000000000..593369440 Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/32-27.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/32-36.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/32-36.mp3 new file mode 100644 index 000000000..2311eae15 Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/32-36.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/32-42.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/32-42.mp3 new file mode 100644 index 000000000..74b78ca83 Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/32-42.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/32-54.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/32-54.mp3 new file mode 100644 index 000000000..2e364c58e Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/32-54.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/33-05.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/33-05.mp3 new file mode 100644 index 000000000..87ef361e3 Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/33-05.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/33-20.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/33-20.mp3 new file mode 100644 index 000000000..8156566d3 Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/33-20.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/34-10.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/34-10.mp3 new file mode 100644 index 000000000..dc21d3064 Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/34-10.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/35-00.mp3 b/aider/website/assets/audio/tree-sitter-language-pack/35-00.mp3 new file mode 100644 index 000000000..aba4436e6 Binary files /dev/null and b/aider/website/assets/audio/tree-sitter-language-pack/35-00.mp3 differ diff --git a/aider/website/assets/audio/tree-sitter-language-pack/metadata.json b/aider/website/assets/audio/tree-sitter-language-pack/metadata.json new file mode 100644 index 000000000..87eb83df8 --- /dev/null +++ b/aider/website/assets/audio/tree-sitter-language-pack/metadata.json @@ -0,0 +1,51 @@ +{ + "00-01": "We're going to add a ton of new languages to aider via tree-sitter-language-pack.", + "00-10": "First, lets try and find which languages it supports.", + "01-00": "Ok, there's a language definitions json file", + "01-10": "Does it have the github repos for each language?", + "01-29": "Ok, this is what we need.", + "01-45": "We need to get all the tags files from each repository for aider's repo-map. Let's have aider write a script to fetch them all.", + "02-05": "We'll show aider the language definitions json file.", + "03-37": "Looks like it can't find most of the tags.scm files.", + "04-19": "Maybe we should have it try other branches besides master?", + "05-02": "Ok, it seems to be downloading them now.", + "05-55": "Let's make it so we can re-run the script and only download files we haven't fetched yet.", + "06-12": "I see lots of tags files, so it's working.", + "06-30": "Ok, restart to run with latest code. This will take awhile to fetch them all.", + "09-02": "The Grep-AST module needs to know about all the new languages.", + "09-45": "Let's have aider add them all, and register each using their commonly used file extensions.", + "10-15": "Some of the languages need to be recognized by their base name, not by their extension.", + "11-15": "Let's sanity check if Grep-AST can handle PowerShell, one of the new languages.", + "12-00": "Looks like it's parsing PowerShell fine.", + "13-00": "Ok, let's download all the tags files into the right spot in the aider repo.", + "14-00": "This will take a minute...", + "16-07": "Delete some no-op or empty tags files.", + "16-16": "Let's commit all the unmodified tags files.", + "16-33": "We need to update each tag file, so that aider can identify names of functions, classes, etc in all these languages.", + "17-01": "Let's use a bash loop to script aider to modify each tags file.", + "17-12": "I'm giving aider a read-only example of an already modified tags file, as an example to follow.", + "19-04": "Looks like it correctly updated the first couple of tags files.", + "19-28": "Let's grep to watch aider's progress working through the list of files.", + "21-30": "This is going to take a little while...", + "24-39": "Let's add a README file with attribution for these tags files.", + "27-10": "Let's add test coverage to be sure these languages work with the repo-map.", + "27-19": "Each language needs a \"fixture\" with some sample code to parse during the test. Let's show aider the layout of the fixtures directory.", + "27-50": "We can use a bash loop to ask aider to add test coverage for each new tags file.", + "28-12": "We'll pass the fixtures directory listing to aider.", + "28-52": "Just need to fix the bash to correctly iterate through the list of tags files.", + "29-27": "I forgot to ask aider to actually generate a sample code fixture for each language.", + "30-25": "Lets run the repo-map tests to see if the first new test works.", + "30-37": "Tests for the Arduino language failed, with an empty repo-map? That's not good.", + "31-52": "Can aider figure out what's wrong?", + "32-42": "Oh! I'm not using the updated Grep-AST that knows about all the new languages.", + "32-54": "Ok, now we're parsing Arduino code properly. Undo aider's bogus test fix.", + "33-05": "Ok, arduino passes now but there seems to be a regression with tsx?", + "33-20": "Can aider figure out why?", + "34-10": "Let's check the parsers map.", + "35-00": "Well, that's all for this recording. The tsx problem was due to a bad mapping from \".tsx\" to \"typescript\" in the map that aider generated earlier.", + "20-20": "It's working on the Dart language now...", + "20-50": "E-lisp is up next...", + "26-55": "Ok, all the files are updated with tags for definitions and references to named code objects.", + "32-36": "Let me see if I can use Grep-AST on the new Arduino fixture code.", + "32-27": "Well, aider made the test pass by basically skipping Arduino." +} \ No newline at end of file diff --git a/aider/website/assets/home.css b/aider/website/assets/home.css new file mode 100644 index 000000000..b46efaa23 --- /dev/null +++ b/aider/website/assets/home.css @@ -0,0 +1,937 @@ +@font-face { + font-family: GlassTTYVT220; + src: local("Glass TTY VT220"), local("Glass TTY VT220 Medium"), url(/assets/Glass_TTY_VT220.ttf) format("truetype"); +} + +:root { + --primary: #4C6EF5; + --primary-dark: #3b5bdb; + --secondary: #12B886; + --dark: #212529; + --light: #F8F9FA; + --gray: #ADB5BD; + --code-bg: #282a36; + --terminal-green: #14b014; + + /* Typography variables */ + --heading-line-height: 1.2; + --body-line-height: 1.7; + --paragraph-spacing: 1.6rem; + --heading-spacing: 1.8rem; + + /* Typographic scale */ + --text-xs: 0.75rem; /* 12px */ + --text-sm: 0.875rem; /* 14px */ + --text-base: 1rem; /* 16px */ + --text-md: 1.125rem; /* 18px */ + --text-lg: 1.25rem; /* 20px */ + --text-xl: 1.5rem; /* 24px */ + --text-2xl: 1.875rem; /* 30px */ + --text-3xl: 2.25rem; /* 36px */ + --text-4xl: 3rem; /* 48px */ + + /* Spacing rhythm values */ + --space-1: 0.25rem; + --space-2: 0.5rem; + --space-3: 0.75rem; + --space-4: 1rem; + --space-6: 1.5rem; + --space-8: 2rem; + --space-12: 3rem; + --space-16: 4rem; +} + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +html { + scroll-behavior: smooth; +} + +h1, h2, h3, h4, h5, h6 { + letter-spacing: -0.025em; + font-weight: 700; +} + +h1 { + font-size: var(--text-4xl); + line-height: 1.1; + font-weight: 800; +} + +h2 { + font-size: var(--text-2xl); + line-height: 1.2; +} + +h3 { + font-size: var(--text-xl); + line-height: 1.3; +} + +body { + font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; + font-size: 16px; + line-height: var(--body-line-height); + color: var(--dark); + background-color: var(--light); + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.container { + width: 100%; + max-width: 1200px; + margin: 0 auto; + padding: 0 20px; +} + +header { + background-color: white; + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); + position: sticky; + top: 0; + z-index: 100; +} + +nav { + display: flex; + justify-content: space-between; + align-items: center; + padding: 20px 0; +} + +.logo { + font-size: 1.8rem; + font-weight: 600; + font-family: 'GlassTTYVT220', monospace; + color: var(--terminal-green); + text-decoration: none; + letter-spacing: 0.5px; +} + +.nav-links { + display: flex; + gap: 30px; +} + +.nav-links a { + color: var(--dark); + text-decoration: none; + font-weight: 500; + transition: color 0.3s; + font-size: var(--text-sm); + letter-spacing: 0.01em; + text-transform: uppercase; +} + +.nav-links a:hover { + color: var(--primary); +} + +.hero { + padding: 80px 0; + background: linear-gradient(135deg, rgba(20, 176, 20, 0.15) 0%, rgba(20, 176, 20, 0.1) 25%, rgba(201, 214, 255, 0.7) 50%, rgba(179, 198, 255, 0.8) 75%, rgba(163, 189, 255, 0.9) 100%); + position: relative; + overflow: hidden; +} + +.hero::before { + content: ""; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-image: url("data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%234c6ef5' fill-opacity='0.07'%3E%3Cpath d='M36 34v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zm0-30V0h-2v4h-4v2h4v4h2V6h4V4h-4zM6 34v-4H4v4H0v2h4v4h2v-4h4v-2H6zM6 4V0H4v4H0v2h4v4h2V6h4V4H6z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E"); + opacity: 0.6; + z-index: 0; +} + +.hero::after { + content: ""; + position: absolute; + top: -50%; + left: -50%; + right: -50%; + bottom: -50%; + background: radial-gradient(circle, rgba(76, 110, 245, 0.2) 0%, rgba(20, 176, 20, 0.05) 50%, rgba(76, 110, 245, 0) 80%); + opacity: 0.7; + z-index: 0; + transform: rotate(30deg); + pointer-events: none; +} + +.hero .container { + position: relative; + z-index: 1; +} + +.hero-grid { + display: grid; + grid-template-columns: 40% 60%; + gap: 40px; + align-items: center; +} + +.hero-content { + text-align: left; + max-width: 90%; + padding-left: 0; +} + +.hero-video { + display: flex; + justify-content: center; + align-items: center; + margin-right: 40px; +} + +.hero h1 { + font-size: 2.5rem; + margin-bottom: var(--heading-spacing); + color: var(--dark); + text-align: left; + line-height: var(--heading-line-height); + font-weight: 800; + letter-spacing: -0.75px; +} + +.hero p { + font-size: 1.25rem; + max-width: 90%; + margin: 0 0 var(--paragraph-spacing); + color: #495057; + line-height: var(--body-line-height); + font-weight: 400; +} + +.buttons { + display: flex; + gap: 20px; + justify-content: flex-start; + margin-top: 10px; + margin-bottom: 0; +} + +.btn-primary { + padding: 14px 28px; + font-size: 1.1rem; +} + +.btn { + display: inline-block; + padding: 12px 24px; + border-radius: 6px; + font-weight: 600; + text-decoration: none; + transition: all 0.3s; +} + +.btn-primary { + background-color: var(--primary); + color: white; +} + +.btn-primary:hover { + background-color: var(--primary-dark); + transform: translateY(-2px); +} + +.btn-secondary { + background-color: white; + color: var(--primary); + border: 1px solid var(--primary); +} + +.btn-secondary:hover { + background-color: #f8f9fa; + transform: translateY(-2px); +} + +.video-container { + max-width: 800px; + width: 100%; + margin: 0 auto; + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15); + border-radius: 8px; + overflow: hidden; + position: relative; + height: 0; + /* Calculate exact padding-bottom based on aspect ratio: (2160/2656) × 100% */ + padding-bottom: calc(2160 / 2656 * 100%); + background-color: rgba(180, 200, 255, 0.3); /* Semi-transparent blue that matches the gradient */ +} + +.video-container video { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + display: block; +} + +.features { + padding: 80px 0; +} + +.section-title { + text-align: center; + margin-bottom: var(--heading-spacing); + font-size: 2.5rem; + color: var(--dark); + font-weight: 700; + line-height: var(--heading-line-height); + letter-spacing: -0.5px; +} + +.feature-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + gap: 40px; +} + +.feature-card { + background-color: white; + border-radius: 8px; + padding: 30px; + box-shadow: 0 4px 10px rgba(0, 0, 0, 0.05); + transition: transform 0.3s, box-shadow 0.3s, background-color 0.3s; + border-left: 3px solid var(--primary); + display: block; + color: inherit; + text-decoration: none; + cursor: pointer; +} + +.feature-card:hover { + transform: translateY(-5px); + box-shadow: 0 8px 20px rgba(0, 0, 0, 0.12); + background-color: rgba(76, 110, 245, 0.03); +} + +.feature-card p { + font-size: var(--text-base); + line-height: 1.6; + color: rgba(33, 37, 41, 0.9); +} + +.feature-card-header { + display: flex; + align-items: center; + margin-bottom: 20px; + padding: 0 0 12px 0; +} + +.feature-icon { + font-size: 28px; + width: 48px; + height: 48px; + display: flex; + align-items: center; + justify-content: center; + border-radius: 10px; + background: rgba(18, 184, 134, 0.1); + color: var(--secondary); + margin-right: 14px; + flex-shrink: 0; + transition: transform 0.3s, background 0.3s; + transform: scale(1.1); +} + +.feature-card:hover .feature-icon { + transform: scale(1.25); + background: rgba(18, 184, 134, 0.2); + color: var(--secondary); +} + +.feature-card:hover .feature-icon { + transform: scale(1.15); + background: rgba(18, 184, 134, 0.2); + color: var(--secondary); +} + +.feature-title { + font-size: var(--text-lg); + color: var(--dark); + margin: 0; + position: relative; + padding-bottom: var(--space-3); + font-weight: 600; + letter-spacing: -0.01em; + line-height: 1.3; +} + +.feature-title::after { + content: ""; + position: absolute; + bottom: 0; + left: 0; + width: 60px; + height: 3px; + background-color: var(--primary); +} + +.models { + padding: 80px 0; + background-color: #f8f9fb; +} + +code, pre, .code-block { + font-family: 'Fira Code', 'JetBrains Mono', 'SF Mono', Consolas, Monaco, 'Andale Mono', monospace; + font-feature-settings: "liga" 1, "calt" 1; /* Enable ligatures */ + letter-spacing: -0.025em; + font-size: 0.95em; +} + +.code-block { + background-color: var(--code-bg); + border-radius: 8px; + padding: 1.5rem; + color: white; + font-size: 1.1rem; + line-height: 1.5; + margin: 1.5rem 0; + overflow-x: auto; + box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1); + tab-size: 2; +} + +.testimonials { + padding: 80px 0; +} + +.testimonial-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + gap: 30px; +} + +.testimonial-card { + background: linear-gradient(135deg, rgba(20, 176, 20, 0.05) 0%, rgba(76, 110, 245, 0.15) 100%); + border-radius: 8px; + padding: 30px; + box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); + transition: transform 0.6s, box-shadow 0.3s; + transform-style: preserve-3d; + perspective: 1000px; + backface-visibility: hidden; + border-left: 3px solid var(--primary); +} + +.testimonial-text { + margin-bottom: 1.5rem; + font-style: italic; + color: #495057; + position: relative; + z-index: 1; + padding: 0 10px; + font-size: 1.1rem; + line-height: var(--body-line-height); + text-wrap: balance; + hanging-punctuation: first; +} + +.testimonial-text::before, +.testimonial-text::after { + font-family: Georgia, serif; + font-size: 1.6em; + line-height: 0.1; + position: relative; +} + +.testimonial-text::before { + content: "\201C"; /* Opening fancy quote */ + color: var(--primary); + margin-right: 4px; + vertical-align: -0.3em; +} + +.testimonial-text::after { + content: "\201D"; /* Closing fancy quote */ + color: var(--primary); + margin-left: 4px; + vertical-align: -0.3em; +} + +.testimonial-card:hover { + box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15); + background: linear-gradient(135deg, rgba(76, 110, 245, 0.12) 0%, rgba(20, 176, 20, 0.08) 50%, rgba(76, 110, 245, 0.2) 100%); +} + +.testimonial-author { + font-weight: 600; + color: var(--dark); + font-size: 0.95rem; +} + +.testimonial-author a { + color: var(--primary); + text-decoration: none; + transition: color 0.3s; +} + +.testimonial-author a:hover { + text-decoration: underline; +} + +.info-section { + padding: 80px 0; + background-color: #f8f9fb; +} + +.info-columns { + display: flex; + gap: 40px; + max-width: 1000px; + margin: 0 auto; +} + +.info-column { + flex: 1; + background-color: white; + border-radius: 8px; + padding: 30px; + box-shadow: 0 4px 10px rgba(0, 0, 0, 0.05); + transition: transform 0.3s, box-shadow 0.3s; + border-left: 3px solid var(--primary); +} + +.info-column:hover { + transform: translateY(-5px); + box-shadow: 0 8px 20px rgba(0, 0, 0, 0.1); +} + +.info-column-title { + font-size: 1.5rem; + margin-bottom: 1.2rem; + color: var(--dark); + position: relative; + padding-bottom: 12px; + font-weight: 600; + letter-spacing: -0.25px; + line-height: var(--heading-line-height); +} + +.info-column-title::after { + content: ""; + position: absolute; + bottom: 0; + left: 0; + width: 60px; + height: 3px; + background-color: var(--primary); +} + +.info-column-desc { + color: #495057; + margin-bottom: 1.4rem; + font-size: 1.05rem; + line-height: var(--body-line-height); +} + +.info-list { + list-style-type: none; + padding: 0; + margin: 0; +} + +.info-list li { + margin-bottom: 12px; + padding-left: 24px; + position: relative; +} + +.info-list li::before { + content: "→"; + position: absolute; + left: 0; + color: var(--primary); + font-weight: bold; +} + +.info-list a { + color: var(--primary); + text-decoration: none; + transition: color 0.2s, transform 0.2s; + display: inline-block; +} + +.info-list a:hover { + color: var(--primary-dark); + transform: translateX(3px); +} + +footer { + background-color: var(--dark); + color: white; + padding: 40px 0; + text-align: center; +} + +.footer-links { + margin-bottom: 20px; +} + +.footer-links a { + color: white; + text-decoration: none; + margin: 0 10px; + transition: color 0.3s; +} + +.footer-links a:hover { + color: var(--primary); +} + +.copyright { + color: var(--gray); + font-size: 0.9rem; +} + +.cta-container { + text-align: center; + margin: 30px 0; +} + +.cta-text { + font-size: 1.2rem; + font-weight: 500; + margin-bottom: 20px; +} + +.cta-buttons { + display: flex; + gap: 15px; + justify-content: center; +} + +.stats-container { + margin-top: 70px; + display: flex; + justify-content: center; + align-items: center; + gap: 12px; + flex-wrap: wrap; + max-width: 1000px; + margin-left: auto; + margin-right: auto; +} + +.github-badge { + display: inline-flex; + height: 28px; + border-radius: 4px; + overflow: hidden; + font-size: var(--text-xs); + font-weight: 600; + line-height: 1; + text-decoration: none; + transition: transform 0.2s; + box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12); + font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; + letter-spacing: 0.02em; + text-transform: uppercase; +} + +.github-badge:hover { + transform: translateY(-2px); + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); +} + +.badge-label { + display: flex; + align-items: center; + padding: 0 10px; + background-color: #555; + color: white; + height: 100%; +} + +.badge-value { + display: flex; + align-items: center; + padding: 0 10px; + background-color: var(--primary); + color: white; + height: 100%; +} + +.badge-stars .badge-value { + background-color: #f1c40f; + color: #333; +} + +.badge-installs .badge-value { + background-color: #2ecc71; +} + +.badge-router .badge-value { + background-color: #9b59b6; +} + +.badge-tokens .badge-value { + background-color: #3498db; +} + +.badge-coded .badge-value { + background-color: #e74c3c; +} + +@media (max-width: 992px) { + :root { + --heading-line-height: 1.25; + --body-line-height: 1.65; + --paragraph-spacing: 1.4rem; + --heading-spacing: 1.6rem; + } + + body { + font-size: 15px; + } + + nav { + padding: 12px 0; + } + + .hero { + padding: 50px 0; + } + + .hero-grid { + grid-template-columns: 1fr; + } + + .hero-content { + text-align: center; + order: 1; + max-width: 100%; + padding-left: 0; + margin-left: auto; + margin-right: auto; + } + + .hero-video { + order: 2; + margin: 0; + } + + .stats-container { + margin-top: 40px; + } + + .hero h1 { + font-size: 2.4rem; + text-align: center; + margin-bottom: var(--heading-spacing); + width: 100%; + } + + .hero p { + font-size: 1.15rem; + margin-left: auto; + margin-right: auto; + max-width: 100%; + text-align: center; + margin-bottom: var(--paragraph-spacing); + } + + .buttons { + flex-direction: row; + flex-wrap: wrap; + align-items: center; + justify-content: center; + gap: 10px; + margin-left: auto; + margin-right: auto; + width: 100%; + } + + .btn { + min-width: 120px; + text-align: center; + } + + .stats-container { + justify-content: center; + } + + .section-title { + font-size: 1.8rem; + } + + .feature-title { + font-size: 1.1rem; + } + + .feature-card { + padding: 20px; + } + + .feature-card-header { + padding: 10px 12px; + margin-bottom: 15px; + } + + .feature-card p { + font-size: 0.9rem; + } + + .feature-icon { + font-size: 1.5rem; + } + + .testimonial-text { + font-size: 0.9rem; + } + + .testimonial-author { + font-size: 0.8rem; + } + + .code-block { + font-size: 0.8rem; + } + + .info-columns { + flex-direction: column; + } + + .info-column { + margin-bottom: 20px; + } + + .nav-links { + display: none; + } + + .btn { + padding: 10px 20px; + font-size: 0.95rem; + } + + .btn-primary { + padding: 12px 24px; + font-size: 1rem; + } + + .github-badge { + font-size: 0.75rem; + } +} + +@media (max-width: 768px) { + :root { + /* Adjust scale for mobile */ + --text-4xl: 2.5rem; + --text-2xl: 1.75rem; + --text-xl: 1.25rem; + } + + body { + line-height: 1.5; + } + + .feature-card p { + font-size: 0.9375rem; + } + + /* Optimize testimonial display on mobile */ + .testimonial-text { + font-size: 1rem; + line-height: 1.6; + text-wrap: pretty; /* Modern browsers will balance text */ + } +} + +@media (max-width: 576px) { + :root { + --heading-line-height: 1.3; + --body-line-height: 1.6; + --paragraph-spacing: 1.2rem; + --heading-spacing: 1.4rem; + } + + body { + font-size: 14px; + } + + .hero { + padding: 30px 0; + } + + .stats-container { + margin-top: 25px; + } + + .buttons { + gap: 8px; + } + + .btn { + min-width: 100px; + padding: 8px 12px; + } + + nav { + padding: 8px 0; + } + + .logo { + font-size: 1.4rem; + } + + .hero h1 { + font-size: 1.8rem; + } + + .section-title { + font-size: 1.6rem; + margin-bottom: 40px; + } + + .feature-title { + font-size: 1rem; + } + + .feature-card { + padding: 15px; + } + + .feature-card-header { + padding: 8px 10px; + margin-bottom: 12px; + } + + .code-block { + font-size: 0.8rem; + padding: 15px; + } + + .info-column-title { + font-size: 1.3rem; + } + + .info-column { + padding: 20px; + } + + .btn { + padding: 8px 16px; + font-size: 0.9rem; + } + + .btn-primary { + padding: 10px 20px; + font-size: 0.95rem; + } + + .logo { + font-size: 1.5rem; + } +} diff --git a/aider/website/assets/icons/brain.svg b/aider/website/assets/icons/brain.svg new file mode 100644 index 000000000..e0d3894cf --- /dev/null +++ b/aider/website/assets/icons/brain.svg @@ -0,0 +1 @@ + diff --git a/aider/website/assets/icons/check-all.svg b/aider/website/assets/icons/check-all.svg new file mode 100644 index 000000000..ec5888f9b --- /dev/null +++ b/aider/website/assets/icons/check-all.svg @@ -0,0 +1 @@ + diff --git a/aider/website/assets/icons/code-tags.svg b/aider/website/assets/icons/code-tags.svg new file mode 100644 index 000000000..18b317173 --- /dev/null +++ b/aider/website/assets/icons/code-tags.svg @@ -0,0 +1 @@ + diff --git a/aider/website/assets/icons/content-copy.svg b/aider/website/assets/icons/content-copy.svg new file mode 100644 index 000000000..ff0c6ab8a --- /dev/null +++ b/aider/website/assets/icons/content-copy.svg @@ -0,0 +1 @@ + diff --git a/aider/website/assets/icons/image-multiple.svg b/aider/website/assets/icons/image-multiple.svg new file mode 100644 index 000000000..dc09bec21 --- /dev/null +++ b/aider/website/assets/icons/image-multiple.svg @@ -0,0 +1 @@ + diff --git a/aider/website/assets/icons/map-outline.svg b/aider/website/assets/icons/map-outline.svg new file mode 100644 index 000000000..2bb9e994d --- /dev/null +++ b/aider/website/assets/icons/map-outline.svg @@ -0,0 +1 @@ + diff --git a/aider/website/assets/icons/microphone.svg b/aider/website/assets/icons/microphone.svg new file mode 100644 index 000000000..97068d53f --- /dev/null +++ b/aider/website/assets/icons/microphone.svg @@ -0,0 +1 @@ + diff --git a/aider/website/assets/icons/monitor.svg b/aider/website/assets/icons/monitor.svg new file mode 100644 index 000000000..39ee355f1 --- /dev/null +++ b/aider/website/assets/icons/monitor.svg @@ -0,0 +1 @@ + diff --git a/aider/website/assets/icons/source-branch.svg b/aider/website/assets/icons/source-branch.svg new file mode 100644 index 000000000..db7da8b2b --- /dev/null +++ b/aider/website/assets/icons/source-branch.svg @@ -0,0 +1 @@ + diff --git a/aider/website/assets/logo.svg b/aider/website/assets/logo.svg new file mode 100644 index 000000000..462a045b7 --- /dev/null +++ b/aider/website/assets/logo.svg @@ -0,0 +1,27 @@ + + + + + + + + + + + aider + \ No newline at end of file diff --git a/aider/website/assets/recordings.jpg b/aider/website/assets/recordings.jpg new file mode 100644 index 000000000..00abd68a2 Binary files /dev/null and b/aider/website/assets/recordings.jpg differ diff --git a/aider/website/assets/sample-analytics.jsonl b/aider/website/assets/sample-analytics.jsonl index 9971e9330..c3edac38b 100644 --- a/aider/website/assets/sample-analytics.jsonl +++ b/aider/website/assets/sample-analytics.jsonl @@ -1,1000 +1,1000 @@ -{"event": "exit", "properties": {"reason": "/exit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741311089} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741311092} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741311092} -{"event": "cli session", "properties": {"main_model": "deepseek/deepseek-reasoner", "weak_model": "deepseek/deepseek-chat", "editor_model": "deepseek/deepseek-chat", "edit_format": "diff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741311092} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741311093} -{"event": "message_send_exception", "properties": {"exception": "name 'REASONING_CONTENT' is not defined"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741311115} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741311149} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741311149} -{"event": "cli session", "properties": {"main_model": "deepseek/deepseek-reasoner", "weak_model": "deepseek/deepseek-chat", "editor_model": "deepseek/deepseek-chat", "edit_format": "diff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741311149} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741311149} -{"event": "message_send", "properties": {"main_model": "deepseek/deepseek-reasoner", "weak_model": "deepseek/deepseek-chat", "editor_model": "deepseek/deepseek-chat", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 556, "total_tokens": 635, "cost": 0.001261089999923, "total_cost": 0.001261089999923}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741311192} -{"event": "command_exit", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741312437} -{"event": "exit", "properties": {"reason": "/exit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741312437} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741312443} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741312443} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741312443} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741312518} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741312521} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741312521} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741312521} -{"event": "message_send", "properties": {"main_model": "deepseek/deepseek-reasoner", "weak_model": "deepseek/deepseek-chat", "editor_model": "deepseek/deepseek-chat", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 486, "total_tokens": 565, "cost": 0.0011077899999230002, "total_cost": 0.0011077899999230002}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741312555} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741312555} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741312632} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741312632} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741312632} -{"event": "message_send", "properties": {"main_model": "deepseek/deepseek-reasoner", "weak_model": "deepseek/deepseek-chat", "editor_model": "deepseek/deepseek-chat", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 263, "total_tokens": 342, "cost": 0.000619419999923, "total_cost": 0.000619419999923}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741312664} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741312664} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741312702} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741312703} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741312703} -{"event": "message_send", "properties": {"main_model": "deepseek/deepseek-reasoner", "weak_model": "deepseek/deepseek-chat", "editor_model": "deepseek/deepseek-chat", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 374, "total_tokens": 453, "cost": 0.000862509999923, "total_cost": 0.000862509999923}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741312781} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741312781} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741312985} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741312985} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741312985} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741312995} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741312995} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741312995} -{"event": "message_send", "properties": {"main_model": "deepseek/deepseek-reasoner", "weak_model": "deepseek/deepseek-chat", "editor_model": "deepseek/deepseek-chat", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 281, "total_tokens": 360, "cost": 0.000658839999923, "total_cost": 0.000658839999923}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313027} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313027} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313405} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313405} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313405} -{"event": "message_send", "properties": {"main_model": "deepseek/deepseek-reasoner", "weak_model": "deepseek/deepseek-chat", "editor_model": "deepseek/deepseek-chat", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 192, "total_tokens": 271, "cost": 0.00046392999992300005, "total_cost": 0.00046392999992300005}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313431} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313431} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313439} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313440} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313440} -{"event": "message_send", "properties": {"main_model": "deepseek/deepseek-reasoner", "weak_model": "deepseek/deepseek-chat", "editor_model": "deepseek/deepseek-chat", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 297, "total_tokens": 376, "cost": 0.000693879999923, "total_cost": 0.000693879999923}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313473} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313473} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313483} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313483} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313483} -{"event": "message_send", "properties": {"main_model": "deepseek/deepseek-reasoner", "weak_model": "deepseek/deepseek-chat", "editor_model": "deepseek/deepseek-chat", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 209, "total_tokens": 288, "cost": 0.000501159999923, "total_cost": 0.000501159999923}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313512} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313512} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313537} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313537} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313538} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 14, "total_tokens": 93, "cost": 0.000447, "total_cost": 0.000447}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313540} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313540} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313550} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313552} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313552} -{"event": "message_send", "properties": {"main_model": "claude-3-7-sonnet-20250219", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 14, "total_tokens": 93, "cost": 0.000447, "total_cost": 0.000447}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313553} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313553} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313627} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313628} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313628} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 14, "total_tokens": 93, "cost": 0.000447, "total_cost": 0.000447}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313630} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313630} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313644} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313644} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313644} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 14, "total_tokens": 93, "cost": 0.000447, "total_cost": 0.000447}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313647} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313647} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313665} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313665} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313665} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 14, "total_tokens": 93, "cost": 0.000447, "total_cost": 0.000447}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313668} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313668} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313707} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313707} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313707} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 14, "total_tokens": 93, "cost": 0.000447, "total_cost": 0.000447}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313710} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313710} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313730} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313730} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313730} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 14, "total_tokens": 93, "cost": 0.000447, "total_cost": 0.000447}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313733} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313733} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313746} -{"event": "repo", "properties": {"num_files": 402}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313746} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313799} -{"event": "repo", "properties": {"num_files": 402}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313799} -{"event": "exit", "properties": {"reason": "Completed lint/test/commit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313804} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313817} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313817} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313817} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 14, "total_tokens": 93, "cost": 0.000447, "total_cost": 0.000447}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313820} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313820} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313857} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313858} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313858} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 118, "total_tokens": 197, "cost": 0.002007, "total_cost": 0.002007}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313862} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313862} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313931} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313931} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313931} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 134, "total_tokens": 213, "cost": 0.002247, "total_cost": 0.002247}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313936} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741313936} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314038} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314038} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314038} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 141, "total_tokens": 220, "cost": 0.002352, "total_cost": 0.002352}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314043} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314043} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314085} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314085} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314085} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 82, "total_tokens": 161, "cost": 0.001467, "total_cost": 0.001467}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314089} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314089} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314100} -{"event": "repo", "properties": {"num_files": 402}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314100} -{"event": "exit", "properties": {"reason": "Completed lint/test/commit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314105} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314112} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314112} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314112} -{"event": "message_send", "properties": {"main_model": "deepseek/deepseek-reasoner", "weak_model": "deepseek/deepseek-chat", "editor_model": "deepseek/deepseek-chat", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 208, "total_tokens": 287, "cost": 0.000498969999923, "total_cost": 0.000498969999923}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314151} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314151} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314167} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314167} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314167} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314175} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314175} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314175} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 153, "total_tokens": 232, "cost": 0.0025320000000000004, "total_cost": 0.0025320000000000004}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314183} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314183} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314188} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314188} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314188} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314208} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314210} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314210} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314210} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314236} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314238} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314238} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314238} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 137, "total_tokens": 216, "cost": 0.0022919999999999998, "total_cost": 0.0022919999999999998}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314253} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314253} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314262} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314262} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314262} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314271} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314273} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314273} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314273} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 162, "total_tokens": 241, "cost": 0.002667, "total_cost": 0.002667}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314281} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314281} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314289} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314289} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314289} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 135, "total_tokens": 214, "cost": 0.002262, "total_cost": 0.002262}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314296} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314296} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314434} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314434} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314434} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 132, "total_tokens": 211, "cost": 0.0022170000000000002, "total_cost": 0.0022170000000000002}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314456} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314456} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314491} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314491} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314491} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314523} -{"event": "repo", "properties": {"num_files": 402}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314523} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 148, "total_tokens": 227, "cost": 0.002457, "total_cost": 0.002457}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314524} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314524} -{"event": "exit", "properties": {"reason": "Completed lint/test/commit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314527} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314678} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314678} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314678} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 122, "total_tokens": 201, "cost": 0.0020670000000000003, "total_cost": 0.0020670000000000003}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314682} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314682} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314686} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314687} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314687} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 135, "total_tokens": 214, "cost": 0.002262, "total_cost": 0.002262}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314691} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741314691} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741315472} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741315472} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741315472} -{"event": "message_send", "properties": {"main_model": "o3-mini", "weak_model": "gpt-4o-mini", "editor_model": "gpt-4o", "edit_format": "ask", "prompt_tokens": 82, "completion_tokens": 15, "total_tokens": 97, "cost": 0.0001562, "total_cost": 0.0001562}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741315477} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741315477} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741315591} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741315591} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741315591} -{"event": "message_send", "properties": {"main_model": "fireworks_ai/accounts/fireworks/models/deepseek-r1", "weak_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "editor_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 176, "total_tokens": 255, "cost": 0.00204, "total_cost": 0.00204}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741315596} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741315596} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741315618} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741315618} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741315618} -{"event": "message_send", "properties": {"main_model": "fireworks_ai/accounts/fireworks/models/deepseek-r1", "weak_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "editor_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 132, "total_tokens": 211, "cost": 0.0016879999999999998, "total_cost": 0.0016879999999999998}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741315623} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741315623} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741315631} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741315631} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741315631} -{"event": "message_send", "properties": {"main_model": "fireworks_ai/accounts/fireworks/models/deepseek-r1", "weak_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "editor_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 233, "total_tokens": 312, "cost": 0.002496, "total_cost": 0.002496}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741315636} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741315636} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741315655} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741315655} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741315655} -{"event": "message_send", "properties": {"main_model": "fireworks_ai/accounts/fireworks/models/deepseek-r1", "weak_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "editor_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 150, "total_tokens": 229, "cost": 0.0018319999999999999, "total_cost": 0.0018319999999999999}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741315660} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741315660} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741315686} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741315686} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741315686} -{"event": "message_send", "properties": {"main_model": "deepseek/deepseek-reasoner", "weak_model": "deepseek/deepseek-chat", "editor_model": "deepseek/deepseek-chat", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 223, "total_tokens": 302, "cost": 0.000531819999923, "total_cost": 0.000531819999923}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741315707} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741315707} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316003} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316003} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316003} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316027} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316031} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316031} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316031} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 98, "total_tokens": 177, "cost": 0.001707, "total_cost": 0.001707}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316036} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316036} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316043} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316043} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316043} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 132, "total_tokens": 211, "cost": 0.0022170000000000002, "total_cost": 0.0022170000000000002}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316047} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316047} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316065} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316065} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316065} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 93, "total_tokens": 172, "cost": 0.001632, "total_cost": 0.001632}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316069} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316069} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316091} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316091} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316091} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 116, "total_tokens": 195, "cost": 0.001977, "total_cost": 0.001977}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316095} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316095} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316111} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316111} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316111} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 126, "total_tokens": 205, "cost": 0.002127, "total_cost": 0.002127}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316116} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316116} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316124} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316124} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316124} -{"event": "message_send_exception", "properties": {"exception": "No active exception to reraise"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316128} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316128} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316137} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316137} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316137} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 107, "completion_tokens": 92, "total_tokens": 199, "cost": 0.0017009999999999998, "total_cost": 0.0017009999999999998}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316141} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316141} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316146} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316146} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316146} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 107, "completion_tokens": 93, "total_tokens": 200, "cost": 0.001716, "total_cost": 0.001716}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316150} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316150} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316158} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316158} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316158} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 107, "completion_tokens": 80, "total_tokens": 187, "cost": 0.0015210000000000002, "total_cost": 0.0015210000000000002}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316162} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316162} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316169} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316169} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316169} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 107, "completion_tokens": 107, "total_tokens": 214, "cost": 0.0019260000000000002, "total_cost": 0.0019260000000000002}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316173} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316173} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316177} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316177} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316177} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 107, "completion_tokens": 165, "total_tokens": 272, "cost": 0.0027960000000000003, "total_cost": 0.0027960000000000003}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316183} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316183} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316202} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316202} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316202} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 107, "total_tokens": 186, "cost": 0.001842, "total_cost": 0.001842}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316206} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316206} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316236} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316236} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316236} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 139, "total_tokens": 218, "cost": 0.0023220000000000003, "total_cost": 0.0023220000000000003}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316241} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316241} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316281} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316281} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316281} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 118, "total_tokens": 197, "cost": 0.002007, "total_cost": 0.002007}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316285} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316285} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316293} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316293} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316293} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 140, "total_tokens": 219, "cost": 0.0023369999999999997, "total_cost": 0.0023369999999999997}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316298} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316298} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316355} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316355} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316355} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 134, "total_tokens": 213, "cost": 0.002247, "total_cost": 0.002247}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316359} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316359} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316390} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316390} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316390} -{"event": "message_send_exception", "properties": {"exception": "unsupported operand type(s) for +=: 'NoneType' and 'str'"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316393} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316393} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316520} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316521} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316521} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316528} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316530} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316530} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316530} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 120, "total_tokens": 199, "cost": 0.0020369999999999997, "total_cost": 0.0020369999999999997}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316535} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316535} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316581} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316581} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316581} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 147, "total_tokens": 226, "cost": 0.0024419999999999997, "total_cost": 0.0024419999999999997}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316589} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316589} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316592} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316592} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316592} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 136, "total_tokens": 215, "cost": 0.0022770000000000004, "total_cost": 0.0022770000000000004}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316597} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316597} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316603} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316603} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316603} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 107, "completion_tokens": 95, "total_tokens": 202, "cost": 0.0017460000000000002, "total_cost": 0.0017460000000000002}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316614} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316614} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316623} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316623} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316623} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 118, "total_tokens": 197, "cost": 0.002007, "total_cost": 0.002007}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316628} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316628} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316692} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316692} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316692} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 127, "total_tokens": 206, "cost": 0.002142, "total_cost": 0.002142}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316698} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316698} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316731} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316731} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316731} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 101, "total_tokens": 180, "cost": 0.001752, "total_cost": 0.001752}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316735} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316735} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316749} -{"event": "repo", "properties": {"num_files": 402}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316750} -{"event": "exit", "properties": {"reason": "Completed lint/test/commit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316757} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316780} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316780} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316780} -{"event": "message_send", "properties": {"main_model": "fireworks_ai/accounts/fireworks/models/deepseek-r1", "weak_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "editor_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 244, "total_tokens": 323, "cost": 0.002584, "total_cost": 0.002584}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316785} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316785} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316941} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316941} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316941} -{"event": "message_send", "properties": {"main_model": "fireworks_ai/accounts/fireworks/models/deepseek-r1", "weak_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "editor_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 300, "total_tokens": 379, "cost": 0.003032, "total_cost": 0.003032}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316948} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741316948} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317022} -{"event": "repo", "properties": {"num_files": 402}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317023} -{"event": "cli session", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317023} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317039} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 8547, "completion_tokens": 747, "total_tokens": 9294, "cost": 0.036846000000000004, "total_cost": 0.036846000000000004}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317055} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317094} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317094} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317094} -{"event": "message_send", "properties": {"main_model": "fireworks_ai/accounts/fireworks/models/deepseek-r1", "weak_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "editor_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 103, "total_tokens": 182, "cost": 0.0014559999999999998, "total_cost": 0.0014559999999999998}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317098} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317098} -{"event": "command_undo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317132} -{"event": "command_undo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317135} -{"event": "command_ask", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317141} -{"event": "command_editor", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317155} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317166} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 6306, "completion_tokens": 572, "total_tokens": 6878, "cost": 0.027498, "total_cost": 0.06434400000000001}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317177} -{"event": "command_code", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317181} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317181} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 9037, "completion_tokens": 552, "total_tokens": 9589, "cost": 0.035391, "total_cost": 0.09973500000000002}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317195} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317200} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317200} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317200} -{"event": "message_send", "properties": {"main_model": "fireworks_ai/accounts/fireworks/models/deepseek-r1", "weak_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "editor_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 147, "total_tokens": 226, "cost": 0.001808, "total_cost": 0.001808}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317205} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317205} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317213} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317213} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317213} -{"event": "message_send", "properties": {"main_model": "fireworks_ai/accounts/fireworks/models/deepseek-r1", "weak_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "editor_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 137, "total_tokens": 216, "cost": 0.001728, "total_cost": 0.001728}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317217} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317217} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317296} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317296} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317296} -{"event": "message_send", "properties": {"main_model": "fireworks_ai/accounts/fireworks/models/deepseek-r1", "weak_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "editor_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 142, "total_tokens": 221, "cost": 0.0017679999999999998, "total_cost": 0.0017679999999999998}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317301} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317301} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317318} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 7331, "completion_tokens": 673, "total_tokens": 8004, "cost": 0.032088000000000005, "total_cost": 0.13182300000000002}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317333} -{"event": "command_code", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317346} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317346} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 10117, "completion_tokens": 700, "total_tokens": 10817, "cost": 0.040851, "total_cost": 0.17267400000000002}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317361} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317366} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317366} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317366} -{"event": "message_send", "properties": {"main_model": "fireworks_ai/accounts/fireworks/models/deepseek-r1", "weak_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "editor_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 132, "total_tokens": 211, "cost": 0.0016879999999999998, "total_cost": 0.0016879999999999998}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317375} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317375} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317410} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317410} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317410} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 125, "total_tokens": 204, "cost": 0.002112, "total_cost": 0.002112}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317415} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317415} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317419} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317419} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317419} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 95, "total_tokens": 174, "cost": 0.001662, "total_cost": 0.001662}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317423} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317423} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317509} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317509} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317509} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 134, "total_tokens": 213, "cost": 0.002247, "total_cost": 0.002247}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317518} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317518} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317718} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317718} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317718} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 106, "total_tokens": 185, "cost": 0.001827, "total_cost": 0.001827}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317726} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741317726} -{"event": "exit", "properties": {"reason": "Control-C"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741360794} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741360939} -{"event": "repo", "properties": {"num_files": 402}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741360939} -{"event": "cli session", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741360939} -{"event": "command_run", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741360946} -{"event": "exit", "properties": {"reason": "Control-C"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741365323} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741368387} -{"event": "repo", "properties": {"num_files": 402}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741368388} -{"event": "exit", "properties": {"reason": "Completed lint/test/commit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741368392} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741372233} -{"event": "repo", "properties": {"num_files": 402}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741372234} -{"event": "cli session", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741372234} -{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741372239} -{"event": "command_run", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741372242} -{"event": "command_ask", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741372248} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741372261} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 29317, "completion_tokens": 1461, "total_tokens": 30778, "cost": 0.109866, "total_cost": 0.109866}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741372296} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741372397} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 30349, "completion_tokens": 1563, "total_tokens": 31912, "cost": 0.11449200000000001, "total_cost": 0.224358}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741372427} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741372551} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 31827, "completion_tokens": 1649, "total_tokens": 33476, "cost": 0.12021599999999999, "total_cost": 0.344574}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741372583} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741372641} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 33322, "completion_tokens": 1511, "total_tokens": 34833, "cost": 0.122631, "total_cost": 0.467205}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741372674} -{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741389760} -{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741389765} -{"event": "command_code", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741389777} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741389777} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 36365, "completion_tokens": 6548, "total_tokens": 42913, "cost": 0.207315, "total_cost": 0.67452}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741389895} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741389924} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 43114, "completion_tokens": 826, "total_tokens": 43940, "cost": 0.14173200000000002, "total_cost": 0.816252}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741389945} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741389975} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741389975} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741389975} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 102, "total_tokens": 181, "cost": 0.0017670000000000001, "total_cost": 0.0017670000000000001}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741389981} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741389981} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741389992} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741389993} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741389993} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 98, "total_tokens": 177, "cost": 0.001707, "total_cost": 0.001707}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741389997} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741389997} -{"event": "command_editor", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390015} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390083} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 40926, "completion_tokens": 1048, "total_tokens": 41974, "cost": 0.138498, "total_cost": 0.95475}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390107} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390132} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390139} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390139} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390139} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 107, "completion_tokens": 97, "total_tokens": 204, "cost": 0.0017760000000000002, "total_cost": 0.0017760000000000002}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390144} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390144} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390150} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390150} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390150} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 107, "completion_tokens": 127, "total_tokens": 234, "cost": 0.002226, "total_cost": 0.002226}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390155} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390155} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 41293, "completion_tokens": 1176, "total_tokens": 42469, "cost": 0.141519, "total_cost": 1.096269}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390155} -{"event": "command_code", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390167} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390167} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 44192, "completion_tokens": 2601, "total_tokens": 46793, "cost": 0.171591, "total_cost": 1.26786}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390213} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390220} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390220} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390220} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 107, "completion_tokens": 112, "total_tokens": 219, "cost": 0.002001, "total_cost": 0.002001}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390224} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390224} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390250} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390250} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390250} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 107, "completion_tokens": 82, "total_tokens": 189, "cost": 0.0015509999999999999, "total_cost": 0.0015509999999999999}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390253} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390253} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390271} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390271} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390271} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 107, "completion_tokens": 120, "total_tokens": 227, "cost": 0.002121, "total_cost": 0.002121}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390275} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390275} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390282} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390282} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390282} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 121, "total_tokens": 200, "cost": 0.002052, "total_cost": 0.002052}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390286} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390286} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390293} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390293} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390293} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 106, "total_tokens": 185, "cost": 0.001827, "total_cost": 0.001827}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390298} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390298} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390317} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390317} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390317} -{"event": "command_editor", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390320} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 135, "total_tokens": 214, "cost": 0.002262, "total_cost": 0.002262}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390322} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390322} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390377} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 44337, "completion_tokens": 1146, "total_tokens": 45483, "cost": 0.150201, "total_cost": 1.418061}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390406} -{"event": "command_code", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390418} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390418} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 46075, "completion_tokens": 1090, "total_tokens": 47165, "cost": 0.15457500000000002, "total_cost": 1.5726360000000001}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390443} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390464} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390464} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390464} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 50, "total_tokens": 129, "cost": 0.000987, "total_cost": 0.000987}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390468} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390468} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390603} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390604} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390604} -{"event": "message_send", "properties": {"main_model": "fireworks_ai/accounts/fireworks/models/deepseek-r1", "weak_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "editor_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 151, "total_tokens": 230, "cost": 0.0018399999999999998, "total_cost": 0.0018399999999999998}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390608} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390608} -{"event": "command_clear", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741390656} -{"event": "command_clear", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391002} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391090} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391090} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391090} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 119, "total_tokens": 198, "cost": 0.0020220000000000004, "total_cost": 0.0020220000000000004}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391095} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391095} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391141} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391141} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391141} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 107, "completion_tokens": 91, "total_tokens": 198, "cost": 0.001686, "total_cost": 0.001686}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391145} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391145} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391242} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391242} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391242} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 107, "completion_tokens": 116, "total_tokens": 223, "cost": 0.002061, "total_cost": 0.002061}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391246} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391246} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391296} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391296} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391297} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 107, "completion_tokens": 85, "total_tokens": 192, "cost": 0.0015960000000000002, "total_cost": 0.0015960000000000002}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391300} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391300} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391334} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391334} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391334} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 139, "total_tokens": 218, "cost": 0.0023220000000000003, "total_cost": 0.0023220000000000003}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391339} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391339} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391347} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391347} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391347} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 144, "total_tokens": 223, "cost": 0.002397, "total_cost": 0.002397}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391351} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391351} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391477} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391477} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391477} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 143, "total_tokens": 222, "cost": 0.0023820000000000004, "total_cost": 0.0023820000000000004}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391485} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391485} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391501} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391501} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391501} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 131, "total_tokens": 210, "cost": 0.002202, "total_cost": 0.002202}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391509} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391509} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391526} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391526} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391526} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 107, "completion_tokens": 117, "total_tokens": 224, "cost": 0.002076, "total_cost": 0.002076}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391535} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391535} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391583} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 27799, "completion_tokens": 705, "total_tokens": 28504, "cost": 0.093972, "total_cost": 1.666608}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391599} -{"event": "command_code", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391603} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391603} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 30338, "completion_tokens": 1166, "total_tokens": 31504, "cost": 0.108504, "total_cost": 1.775112}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391628} -{"event": "command_diff", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391663} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391681} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391681} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391681} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 107, "completion_tokens": 103, "total_tokens": 210, "cost": 0.001866, "total_cost": 0.001866}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391686} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391686} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391701} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391701} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391701} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 107, "completion_tokens": 122, "total_tokens": 229, "cost": 0.002151, "total_cost": 0.002151}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391706} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391706} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391717} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391717} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391717} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 94, "total_tokens": 173, "cost": 0.001647, "total_cost": 0.001647}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391721} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391721} -{"event": "command_code", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391756} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391756} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 31652, "completion_tokens": 635, "total_tokens": 32287, "cost": 0.104481, "total_cost": 1.879593}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391770} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391780} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391780} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391780} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 163, "total_tokens": 242, "cost": 0.0026820000000000004, "total_cost": 0.0026820000000000004}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391785} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391785} -{"event": "command_code", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391801} -{"event": "ai-comments execute", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391810} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391811} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 29419, "completion_tokens": 850, "total_tokens": 30269, "cost": 0.101007, "total_cost": 1.9806000000000001}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391832} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391842} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391842} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391842} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 143, "total_tokens": 222, "cost": 0.0023820000000000004, "total_cost": 0.0023820000000000004}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391846} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391846} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391856} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391856} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391856} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 159, "total_tokens": 238, "cost": 0.002622, "total_cost": 0.002622}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391861} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391861} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391886} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391886} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391886} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 157, "total_tokens": 236, "cost": 0.0025919999999999997, "total_cost": 0.0025919999999999997}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391891} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391891} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391915} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 29883, "completion_tokens": 1134, "total_tokens": 31017, "cost": 0.106659, "total_cost": 2.087259}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391940} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391948} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391948} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391948} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 135, "total_tokens": 214, "cost": 0.002262, "total_cost": 0.002262}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391953} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741391953} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392019} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 30276, "completion_tokens": 832, "total_tokens": 31108, "cost": 0.10330800000000001, "total_cost": 2.190567}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392035} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392044} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392044} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392044} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 144, "total_tokens": 223, "cost": 0.002397, "total_cost": 0.002397}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392049} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392049} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392086} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392086} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392086} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 154, "total_tokens": 233, "cost": 0.002547, "total_cost": 0.002547}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392091} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392091} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392096} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392096} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392097} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 149, "total_tokens": 228, "cost": 0.0024720000000000002, "total_cost": 0.0024720000000000002}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392101} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392101} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392172} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 31027, "completion_tokens": 3878, "total_tokens": 34905, "cost": 0.151251, "total_cost": 2.341818}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392233} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392238} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 33371, "completion_tokens": 857, "total_tokens": 34228, "cost": 0.11296800000000001, "total_cost": 2.454786}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392256} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392259} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 34012, "completion_tokens": 305, "total_tokens": 34317, "cost": 0.106611, "total_cost": 2.561397}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392268} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392297} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392297} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392297} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 147, "total_tokens": 226, "cost": 0.0024419999999999997, "total_cost": 0.0024419999999999997}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392302} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392302} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392308} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392308} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392308} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 107, "completion_tokens": 94, "total_tokens": 201, "cost": 0.001731, "total_cost": 0.001731}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392312} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392312} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392319} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392319} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392319} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 107, "completion_tokens": 100, "total_tokens": 207, "cost": 0.0018210000000000001, "total_cost": 0.0018210000000000001}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392323} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392323} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392330} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392330} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392330} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 130, "total_tokens": 209, "cost": 0.002187, "total_cost": 0.002187}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392334} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392334} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392344} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392345} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392345} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 107, "completion_tokens": 123, "total_tokens": 230, "cost": 0.002166, "total_cost": 0.002166}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392351} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392351} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392382} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392382} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392382} -{"event": "message_send", "properties": {"main_model": "fireworks_ai/accounts/fireworks/models/deepseek-r1", "weak_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "editor_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 142, "total_tokens": 221, "cost": 0.0017679999999999998, "total_cost": 0.0017679999999999998}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392386} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392386} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392399} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392399} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392399} -{"event": "message_send", "properties": {"main_model": "fireworks_ai/accounts/fireworks/models/deepseek-r1", "weak_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "editor_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 135, "total_tokens": 214, "cost": 0.001712, "total_cost": 0.001712}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392403} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392403} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392420} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392420} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392420} -{"event": "message_send", "properties": {"main_model": "fireworks_ai/accounts/fireworks/models/deepseek-r1", "weak_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "editor_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 113, "total_tokens": 192, "cost": 0.001536, "total_cost": 0.001536}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392424} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392424} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392431} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392431} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392431} -{"event": "message_send", "properties": {"main_model": "fireworks_ai/accounts/fireworks/models/deepseek-r1", "weak_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "editor_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 149, "total_tokens": 228, "cost": 0.0018239999999999999, "total_cost": 0.0018239999999999999}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392436} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392436} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392457} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392457} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392457} -{"event": "message_send", "properties": {"main_model": "deepseek/deepseek-reasoner", "weak_model": "deepseek/deepseek-chat", "editor_model": "deepseek/deepseek-chat", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 224, "total_tokens": 303, "cost": 0.000534009999923, "total_cost": 0.000534009999923}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392468} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392468} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392483} -{"event": "repo", "properties": {"num_files": 402}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392484} -{"event": "exit", "properties": {"reason": "Completed lint/test/commit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392491} -{"event": "command_ask", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392497} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392512} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 33105, "completion_tokens": 2298, "total_tokens": 35403, "cost": 0.133785, "total_cost": 2.695182}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392554} -{"event": "command_code", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392574} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392574} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 35179, "completion_tokens": 1663, "total_tokens": 36842, "cost": 0.13048200000000001, "total_cost": 2.825664}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392607} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392621} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 37323, "completion_tokens": 698, "total_tokens": 38021, "cost": 0.12243899999999999, "total_cost": 2.948103}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392646} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392658} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 37898, "completion_tokens": 483, "total_tokens": 38381, "cost": 0.120939, "total_cost": 3.069042}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392671} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392672} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 38191, "completion_tokens": 507, "total_tokens": 38698, "cost": 0.12217800000000001, "total_cost": 3.19122}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392692} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392722} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392722} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392722} -{"event": "message_send", "properties": {"main_model": "deepseek/deepseek-reasoner", "weak_model": "deepseek/deepseek-chat", "editor_model": "deepseek/deepseek-chat", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 169, "total_tokens": 248, "cost": 0.00041355999992300006, "total_cost": 0.00041355999992300006}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392733} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392733} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392743} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392743} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392743} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 107, "completion_tokens": 96, "total_tokens": 203, "cost": 0.001761, "total_cost": 0.001761}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392747} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392747} -{"event": "command_clear", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392765} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392782} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 27956, "completion_tokens": 957, "total_tokens": 28913, "cost": 0.098223, "total_cost": 3.289443}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392807} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392864} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 28268, "completion_tokens": 849, "total_tokens": 29117, "cost": 0.097539, "total_cost": 3.3869819999999997}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392882} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392919} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392919} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392919} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 107, "completion_tokens": 68, "total_tokens": 175, "cost": 0.0013410000000000002, "total_cost": 0.0013410000000000002}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392922} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392922} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392949} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392949} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392949} -{"event": "message_send_exception", "properties": {"exception": "name 'dump' is not defined"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392953} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392953} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392962} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392962} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392962} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 107, "completion_tokens": 116, "total_tokens": 223, "cost": 0.002061, "total_cost": 0.002061}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392967} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741392967} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741393124} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741393124} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741393124} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 107, "completion_tokens": 113, "total_tokens": 220, "cost": 0.002016, "total_cost": 0.002016}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741393128} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741393128} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741393530} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741393530} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741393530} -{"event": "message_send_exception", "properties": {"exception": "name 'tag_name' is not defined"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741393536} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741393536} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741393551} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741393551} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741393551} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 107, "completion_tokens": 126, "total_tokens": 233, "cost": 0.002211, "total_cost": 0.002211}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741393556} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741393556} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741393596} -{"event": "repo", "properties": {"num_files": 403}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741393597} -{"event": "exit", "properties": {"reason": "Completed lint/test/commit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741393607} -{"event": "command_drop", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741393665} -{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741393684} -{"event": "command_editor", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741393709} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741393829} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741393844} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 21123, "completion_tokens": 2175, "total_tokens": 23298, "cost": 0.095994, "total_cost": 3.482976}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741393882} -{"event": "command_code", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741393885} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741393885} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 25498, "completion_tokens": 2511, "total_tokens": 28009, "cost": 0.11415900000000001, "total_cost": 3.5971349999999997}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741393937} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741393983} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 30622, "completion_tokens": 528, "total_tokens": 31150, "cost": 0.099786, "total_cost": 3.6969209999999997}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741393998} -{"event": "command_code", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394012} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394016} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 25020, "completion_tokens": 441, "total_tokens": 25461, "cost": 0.081675, "total_cost": 3.778596}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394035} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394048} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394048} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394048} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 107, "completion_tokens": 110, "total_tokens": 217, "cost": 0.001971, "total_cost": 0.001971}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394053} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394053} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394053} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 25570, "completion_tokens": 343, "total_tokens": 25913, "cost": 0.081855, "total_cost": 3.860451}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394064} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394079} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 26226, "completion_tokens": 504, "total_tokens": 26730, "cost": 0.086238, "total_cost": 3.9466889999999997}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394091} -{"event": "command_clear", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394257} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394263} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394263} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394263} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 107, "completion_tokens": 102, "total_tokens": 209, "cost": 0.0018510000000000002, "total_cost": 0.0018510000000000002}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394268} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394268} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394280} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394280} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394280} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 125, "total_tokens": 204, "cost": 0.002112, "total_cost": 0.002112}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394284} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394284} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394357} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394357} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394357} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 158, "total_tokens": 237, "cost": 0.002607, "total_cost": 0.002607}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394366} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394366} -{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394377} -{"event": "command_ask", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394393} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394393} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 29224, "completion_tokens": 622, "total_tokens": 29846, "cost": 0.097002, "total_cost": 4.043691}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394411} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394597} -{"event": "repo", "properties": {"num_files": 403}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394597} -{"event": "exit", "properties": {"reason": "Completed lint/test/commit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394601} -{"event": "command_drop", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394776} -{"event": "command_clear", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394777} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394850} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 14859, "completion_tokens": 3013, "total_tokens": 17872, "cost": 0.08977199999999999, "total_cost": 4.133463}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394902} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394917} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 16170, "completion_tokens": 265, "total_tokens": 16435, "cost": 0.052485000000000004, "total_cost": 4.185948}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394927} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394938} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 16450, "completion_tokens": 461, "total_tokens": 16911, "cost": 0.056264999999999996, "total_cost": 4.242213}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394955} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394970} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 16811, "completion_tokens": 1122, "total_tokens": 17933, "cost": 0.067263, "total_cost": 4.309475999999999}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394995} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741394995} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 17659, "completion_tokens": 761, "total_tokens": 18420, "cost": 0.064392, "total_cost": 4.373867999999999}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741395012} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741395024} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 18457, "completion_tokens": 303, "total_tokens": 18760, "cost": 0.059916000000000004, "total_cost": 4.433783999999999}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741395031} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741395152} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 19025, "completion_tokens": 632, "total_tokens": 19657, "cost": 0.066555, "total_cost": 4.500338999999999}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741395167} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741395187} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 19654, "completion_tokens": 482, "total_tokens": 20136, "cost": 0.066192, "total_cost": 4.5665309999999995}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741395205} -{"event": "command_run", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741395245} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741395250} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 20358, "completion_tokens": 416, "total_tokens": 20774, "cost": 0.067314, "total_cost": 4.633844999999999}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741395260} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741395293} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 20662, "completion_tokens": 576, "total_tokens": 21238, "cost": 0.070626, "total_cost": 4.704470999999999}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741395306} -{"event": "command_clear", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741395513} -{"event": "command_drop", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741395518} -{"event": "command_editor", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741395552} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741395580} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 6862, "completion_tokens": 2187, "total_tokens": 9049, "cost": 0.053391, "total_cost": 4.757861999999999}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741395614} -{"event": "command_clear", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741395638} -{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741395659} -{"event": "command_editor", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741395663} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741395726} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 23277, "completion_tokens": 4188, "total_tokens": 27465, "cost": 0.13265100000000002, "total_cost": 4.890512999999999}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741395793} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741395828} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 25548, "completion_tokens": 502, "total_tokens": 26050, "cost": 0.084174, "total_cost": 4.974686999999999}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741395840} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741395867} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 26217, "completion_tokens": 838, "total_tokens": 27055, "cost": 0.091221, "total_cost": 5.065907999999999}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741395886} -{"event": "command_undo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741395908} -{"event": "command_read-only", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741395920} -{"event": "command_read-only", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741395927} -{"event": "command_run", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741395934} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741395944} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 27075, "completion_tokens": 861, "total_tokens": 27936, "cost": 0.09414, "total_cost": 5.160048}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741395965} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741396533} -{"event": "repo", "properties": {"num_files": 404}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741396533} -{"event": "command_clear", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741396539} -{"event": "exit", "properties": {"reason": "Completed lint/test/commit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741396544} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741396556} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 24113, "completion_tokens": 2994, "total_tokens": 27107, "cost": 0.11724899999999999, "total_cost": 5.277297}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741396607} -{"event": "command_run", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741396673} -{"event": "command_run", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741396679} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741396685} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 30914, "completion_tokens": 1287, "total_tokens": 32201, "cost": 0.11204700000000001, "total_cost": 5.3893439999999995}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741396710} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741396775} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 32097, "completion_tokens": 1492, "total_tokens": 33589, "cost": 0.118671, "total_cost": 5.508014999999999}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741396798} -{"event": "ai-comments file-add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397305} -{"event": "ai-comments execute", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397305} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397305} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 49682, "completion_tokens": 731, "total_tokens": 50413, "cost": 0.16001100000000001, "total_cost": 5.668025999999999}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397327} -{"event": "command_undo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397352} -{"event": "command_undo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397361} -{"event": "ai-comments execute", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397374} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397374} -{"event": "exit", "properties": {"reason": "Control-C"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397378} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397387} -{"event": "repo", "properties": {"num_files": 404}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397388} -{"event": "cli session", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397388} -{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397391} -{"event": "ai-comments execute", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397394} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397394} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 22092, "completion_tokens": 780, "total_tokens": 22872, "cost": 0.077976, "total_cost": 0.077976}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397410} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397571} -{"event": "repo", "properties": {"num_files": 404}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397572} -{"event": "exit", "properties": {"reason": "Completed lint/test/commit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397577} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397658} -{"event": "repo", "properties": {"num_files": 404}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397658} -{"event": "exit", "properties": {"reason": "Exit flag set"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397658} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397658} -{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397658} -{"event": "repo", "properties": {"num_files": 404}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397658} -{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397658} -{"event": "command_exit", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397668} -{"event": "exit", "properties": {"reason": "/exit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397668} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397702} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397702} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397702} -{"event": "message_send", "properties": {"main_model": "fireworks_ai/accounts/fireworks/models/deepseek-r1", "weak_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "editor_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 173, "total_tokens": 252, "cost": 0.002016, "total_cost": 0.002016}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397707} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397707} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397720} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397720} -{"event": "cli session", "properties": {"main_model": "fireworks_ai/accounts/fireworks/models/deepseek-r1", "weak_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "editor_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "edit_format": "diff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397720} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397722} -{"event": "message_send", "properties": {"main_model": "fireworks_ai/accounts/fireworks/models/deepseek-r1", "weak_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "editor_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "edit_format": "ask", "prompt_tokens": 79, "completion_tokens": 145, "total_tokens": 224, "cost": 0.001792, "total_cost": 0.001792}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397725} -{"event": "exit", "properties": {"reason": "Completed main CLI coder.run"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397736} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397743} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397743} -{"event": "cli session", "properties": {"main_model": "fireworks_ai/accounts/fireworks/models/deepseek-r1", "weak_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "editor_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "edit_format": "diff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397743} -{"event": "command_exit", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397752} -{"event": "exit", "properties": {"reason": "/exit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397752} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397765} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397765} -{"event": "cli session", "properties": {"main_model": "fireworks_ai/accounts/fireworks/models/deepseek-r1", "weak_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "editor_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "edit_format": "diff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397765} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397768} -{"event": "message_send", "properties": {"main_model": "fireworks_ai/accounts/fireworks/models/deepseek-r1", "weak_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "editor_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "edit_format": "diff", "prompt_tokens": 2374, "completion_tokens": 224, "total_tokens": 2598, "cost": 0.020783999999999997, "total_cost": 0.020783999999999997}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397772} -{"event": "exit", "properties": {"reason": "Control-C"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397805} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397808} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397808} -{"event": "cli session", "properties": {"main_model": "fireworks_ai/accounts/fireworks/models/deepseek-r1", "weak_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "editor_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "edit_format": "diff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397808} -{"event": "exit", "properties": {"reason": "Control-C"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397810} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397812} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397812} -{"event": "cli session", "properties": {"main_model": "fireworks_ai/accounts/fireworks/models/deepseek-r1", "weak_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "editor_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "edit_format": "diff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397812} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397816} -{"event": "message_send", "properties": {"main_model": "fireworks_ai/accounts/fireworks/models/deepseek-r1", "weak_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "editor_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "edit_format": "diff", "prompt_tokens": 2374, "completion_tokens": 270, "total_tokens": 2644, "cost": 0.021151999999999997, "total_cost": 0.021151999999999997}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741397821} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398069} -{"event": "repo", "properties": {"num_files": 404}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398071} -{"event": "cli session", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398071} -{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398082} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398097} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 29032, "completion_tokens": 2410, "total_tokens": 31442, "cost": 0.12324600000000001, "total_cost": 0.12324600000000001}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398139} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398183} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 30558, "completion_tokens": 312, "total_tokens": 30870, "cost": 0.09635400000000001, "total_cost": 0.21960000000000002}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398193} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398256} -{"event": "repo", "properties": {"num_files": 404}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398258} -{"event": "exit", "properties": {"reason": "Exit flag set"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398258} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398258} -{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398278} -{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398282} -{"event": "command_drop", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398285} -{"event": "command_drop", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398287} -{"event": "command_editor", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398301} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398312} -{"event": "command_clear", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398333} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398350} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 14683, "completion_tokens": 724, "total_tokens": 15407, "cost": 0.054909, "total_cost": 0.274509}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398364} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398399} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 15133, "completion_tokens": 1567, "total_tokens": 16700, "cost": 0.068904, "total_cost": 0.343413}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398426} -{"event": "exit", "properties": {"reason": "Control-C"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398440} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398543} -{"event": "repo", "properties": {"num_files": 404}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398543} -{"event": "cli session", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398543} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398554} -{"event": "repo", "properties": {"num_files": 404}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398555} -{"event": "exit", "properties": {"reason": "Exit flag set"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398555} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398555} -{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398555} -{"event": "repo", "properties": {"num_files": 404}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398555} -{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398555} -{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398560} -{"event": "command_editor", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398563} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398626} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 29809, "completion_tokens": 1402, "total_tokens": 31211, "cost": 0.110457, "total_cost": 0.110457}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398654} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398672} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 31040, "completion_tokens": 407, "total_tokens": 31447, "cost": 0.09922500000000001, "total_cost": 0.209682}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398682} -{"event": "command_read-only", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398746} -{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398749} -{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398805} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398815} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 39313, "completion_tokens": 3097, "total_tokens": 42410, "cost": 0.164394, "total_cost": 0.374076}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398865} -{"event": "exit", "properties": {"reason": "Control-C"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741398927} -{"event": "exit", "properties": {"reason": "Control-C"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741402971} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741402977} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741402977} -{"event": "cli session", "properties": {"main_model": "fireworks_ai/accounts/fireworks/models/deepseek-r1", "weak_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "editor_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "edit_format": "diff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741402977} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741402997} -{"event": "message_send", "properties": {"main_model": "fireworks_ai/accounts/fireworks/models/deepseek-r1", "weak_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "editor_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "edit_format": "diff", "prompt_tokens": 2374, "completion_tokens": 447, "total_tokens": 2821, "cost": 0.022567999999999998, "total_cost": 0.022567999999999998}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741403004} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741403012} -{"event": "repo", "properties": {"num_files": 404}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741403013} -{"event": "exit", "properties": {"reason": "Exit flag set"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741403013} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741403013} -{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741403013} -{"event": "repo", "properties": {"num_files": 404}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741403013} -{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741403013} -{"event": "exit", "properties": {"reason": "Control-C"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741403020} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741403039} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741403039} -{"event": "cli session", "properties": {"main_model": "fireworks_ai/accounts/fireworks/models/deepseek-r1", "weak_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "editor_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "edit_format": "diff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741403039} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741403077} -{"event": "message_send", "properties": {"main_model": "fireworks_ai/accounts/fireworks/models/deepseek-r1", "weak_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "editor_model": "fireworks_ai/accounts/fireworks/models/deepseek-v3", "edit_format": "diff", "prompt_tokens": 2374, "completion_tokens": 198, "total_tokens": 2572, "cost": 0.020575999999999997, "total_cost": 0.020575999999999997}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741403080} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741403108} -{"event": "gui session", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741403115} -{"event": "exit", "properties": {"reason": "GUI session ended"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741403115} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741403156} -{"event": "repo", "properties": {"num_files": 404}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741403156} -{"event": "exit", "properties": {"reason": "Completed lint/test/commit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741403175} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741403243} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741403244} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741403244} -{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "claude-3-5-sonnet-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 48073, "completion_tokens": 905, "total_tokens": 48978, "cost": 0.15779400000000002, "total_cost": 0.15779400000000002}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741403268} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741403292} -{"event": "ai-comments file-add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1741403293} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951066} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951066} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951066} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951066} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951067} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951067} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951067} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951067} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951067} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951067} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951067} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951067} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951068} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951068} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951068} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951068} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951068} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951068} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951068} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951068} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951068} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951068} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951068} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951069} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951069} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951069} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951069} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951069} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951069} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951069} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951069} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951069} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951070} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951070} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951070} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951070} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951070} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951070} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951070} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951070} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951070} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951070} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951070} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951070} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951071} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951071} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951071} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951113} +{"event": "repo", "properties": {"num_files": 581}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951114} +{"event": "exit", "properties": {"reason": "Exit flag set"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951114} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951114} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951114} +{"event": "repo", "properties": {"num_files": 581}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951114} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951114} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951142} +{"event": "gui session", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951142} +{"event": "exit", "properties": {"reason": "GUI session ended"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1742951142} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743006949} +{"event": "repo", "properties": {"num_files": 581}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743006949} +{"event": "cli session", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "deepseek/deepseek-chat", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "diff-fenced"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743006949} +{"event": "command_ask", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743006951} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743006985} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "deepseek/deepseek-chat", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "ask", "prompt_tokens": 15665, "completion_tokens": 1003, "total_tokens": 16668, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743007009} +{"event": "command_copy-context", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743007099} +{"event": "command_copy-context", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743007337} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743007431} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "deepseek/deepseek-chat", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "ask", "prompt_tokens": 16685, "completion_tokens": 1573, "total_tokens": 18258, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743007468} +{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743007478} +{"event": "command_code", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743007481} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743007482} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "deepseek/deepseek-chat", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "diff-fenced", "prompt_tokens": 20646, "completion_tokens": 1299, "total_tokens": 21945, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743007495} +{"event": "command_code", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743007547} +{"event": "command_drop", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743007562} +{"event": "command_read-only", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743007566} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743007589} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "deepseek/deepseek-chat", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "diff-fenced", "prompt_tokens": 23162, "completion_tokens": 2993, "total_tokens": 26155, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743007628} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743007641} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "deepseek/deepseek-chat", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "diff-fenced", "prompt_tokens": 27497, "completion_tokens": 796, "total_tokens": 28293, "cost": 0.0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743007654} +{"event": "command_clear", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743007680} +{"event": "command_paste", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743007698} +{"event": "command_ask", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743007704} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743007704} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "deepseek/deepseek-chat", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "ask", "prompt_tokens": 20805, "completion_tokens": 1359, "total_tokens": 22164, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743007734} +{"event": "command_clear", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743007751} +{"event": "command_read-only", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743007804} +{"event": "command_ask", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743007815} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743007815} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "deepseek/deepseek-chat", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "ask", "prompt_tokens": 21950, "completion_tokens": 968, "total_tokens": 22918, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743007847} +{"event": "command_code", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743007873} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743007873} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "deepseek/deepseek-chat", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "diff-fenced", "prompt_tokens": 24276, "completion_tokens": 1226, "total_tokens": 25502, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743007891} +{"event": "command_clear", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743007932} +{"event": "command_model", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743007936} +{"event": "command_chat-mode", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743007941} +{"event": "command_ask", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743007951} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743007951} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "ask", "prompt_tokens": 22198, "completion_tokens": 1305, "total_tokens": 23503, "cost": 0.086169, "total_cost": 0.086169}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743007989} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743008055} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "diff", "prompt_tokens": 25212, "completion_tokens": 2416, "total_tokens": 27628, "cost": 0.111876, "total_cost": 0.198045}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743008098} +{"event": "command_drop", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743008134} +{"event": "command_model", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743008144} +{"event": "command_read-only", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743008190} +{"event": "command_ask", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743008199} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743008199} +{"event": "command_code", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743008249} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743008250} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743008328} +{"event": "repo", "properties": {"num_files": 582}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743008328} +{"event": "cli session", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743008328} +{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743008330} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743008365} +{"event": "message_send", "properties": {"main_model": "deepseek/deepseek-chat", "weak_model": "deepseek/deepseek-chat", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "diff", "prompt_tokens": 27510, "completion_tokens": 2797, "total_tokens": 30307, "cost": 0.0105044, "total_cost": 0.2085494}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743008370} +{"event": "command_read-only", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743008375} +{"event": "command_clear", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743008377} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743008384} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 22337, "completion_tokens": 2867, "total_tokens": 25204, "cost": 0.110016, "total_cost": 0.110016}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743008435} +{"event": "exit", "properties": {"reason": "Control-C"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743008473} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743008493} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 27552, "completion_tokens": 475, "total_tokens": 28027, "cost": 0.08978100000000001, "total_cost": 0.199797}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743008505} +{"event": "command_clear", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743008666} +{"event": "command_ask", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743008672} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743008672} +{"event": "command_drop", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743008702} +{"event": "command_clear", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743008705} +{"event": "command_ask", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743008712} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743008712} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 10701, "completion_tokens": 826, "total_tokens": 11527, "cost": 0.044493, "total_cost": 0.24429}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743008731} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743008782} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 12809, "completion_tokens": 1828, "total_tokens": 14637, "cost": 0.065847, "total_cost": 0.310137}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743008831} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743008843} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 15712, "completion_tokens": 1010, "total_tokens": 16722, "cost": 0.06228600000000001, "total_cost": 0.372423}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743008858} +{"event": "command_undo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743008878} +{"event": "command_undo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743008885} +{"event": "command_clear", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743008925} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743008939} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 12452, "completion_tokens": 791, "total_tokens": 13243, "cost": 0.049221, "total_cost": 0.421644}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743008954} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743009016} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 13288, "completion_tokens": 692, "total_tokens": 13980, "cost": 0.050244000000000004, "total_cost": 0.47188800000000003}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743009028} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743009050} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 13428, "completion_tokens": 985, "total_tokens": 14413, "cost": 0.055059, "total_cost": 0.526947}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743009070} +{"event": "command_clear", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743009091} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743009099} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 12486, "completion_tokens": 777, "total_tokens": 13263, "cost": 0.049113, "total_cost": 0.57606}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743009113} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743009119} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 13386, "completion_tokens": 639, "total_tokens": 14025, "cost": 0.049742999999999996, "total_cost": 0.625803}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743009130} +{"event": "command_undo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743009151} +{"event": "command_undo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743009153} +{"event": "command_clear", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743009158} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743009171} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 12489, "completion_tokens": 579, "total_tokens": 13068, "cost": 0.046152, "total_cost": 0.671955}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743009182} +{"event": "command_undo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743009192} +{"event": "command_clear", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743010342} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743010402} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 12505, "completion_tokens": 2316, "total_tokens": 14821, "cost": 0.072255, "total_cost": 0.7442099999999999}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743010440} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743010488} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 28267, "completion_tokens": 2159, "total_tokens": 30426, "cost": 0.11718600000000001, "total_cost": 0.8613959999999999}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743010524} +{"event": "command_undo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743010636} +{"event": "command_undo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743010639} +{"event": "command_undo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743010641} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743014264} +{"event": "repo", "properties": {"num_files": 582}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743014264} +{"event": "exit", "properties": {"reason": "Completed lint/test/commit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743014271} +{"event": "exit", "properties": {"reason": "Control-C"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743014285} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743014463} +{"event": "repo", "properties": {"num_files": 582}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743014464} +{"event": "cli session", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743014464} +{"event": "command_context", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743014479} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743014479} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "context", "prompt_tokens": 8950, "completion_tokens": 468, "total_tokens": 9418, "cost": 0.033870000000000004, "total_cost": 0.033870000000000004}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743014493} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743014493} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "context", "prompt_tokens": 17656, "completion_tokens": 649, "total_tokens": 18305, "cost": 0.06270300000000001, "total_cost": 0.09657300000000002}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743014508} +{"event": "command_reset", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743014516} +{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743014520} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743014529} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 10409, "completion_tokens": 654, "total_tokens": 11063, "cost": 0.041037000000000004, "total_cost": 0.13761}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743014543} +{"event": "command_diff", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743014570} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743039603} +{"event": "repo", "properties": {"num_files": 582}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743039608} +{"event": "cli session", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743039608} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743039677} +{"event": "command_context", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743039683} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743039683} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "context", "prompt_tokens": 9733, "completion_tokens": 610, "total_tokens": 10343, "cost": 0.038349, "total_cost": 0.038349}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743039699} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743039699} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "context", "prompt_tokens": 17193, "completion_tokens": 527, "total_tokens": 17720, "cost": 0.059484, "total_cost": 0.097833}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743039710} +{"event": "command_drop", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743094444} +{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743094447} +{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743094516} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743094560} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 32405, "completion_tokens": 882, "total_tokens": 33287, "cost": 0.110445, "total_cost": 0.20827800000000002}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743094583} +{"event": "exit", "properties": {"reason": "Control-C"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743094599} +{"event": "command_context", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743094661} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743094661} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "context", "prompt_tokens": 33995, "completion_tokens": 532, "total_tokens": 34527, "cost": 0.10996500000000001, "total_cost": 0.31824300000000005}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743094679} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743094679} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "context", "prompt_tokens": 9890, "completion_tokens": 423, "total_tokens": 10313, "cost": 0.036015000000000005, "total_cost": 0.3542580000000001}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743094688} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743094688} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "context", "prompt_tokens": 10415, "completion_tokens": 260, "total_tokens": 10675, "cost": 0.035145, "total_cost": 0.38940300000000005}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743094695} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743094698} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 8407, "completion_tokens": 766, "total_tokens": 9173, "cost": 0.036711, "total_cost": 0.42611400000000005}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743094714} +{"event": "command_context", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743094831} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743094831} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "context", "prompt_tokens": 11226, "completion_tokens": 464, "total_tokens": 11690, "cost": 0.040638, "total_cost": 0.46675200000000006}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743094843} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743094843} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "context", "prompt_tokens": 12015, "completion_tokens": 344, "total_tokens": 12359, "cost": 0.041205, "total_cost": 0.5079570000000001}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743094851} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743094853} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 10629, "completion_tokens": 443, "total_tokens": 11072, "cost": 0.038532, "total_cost": 0.5464890000000001}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743094865} +{"event": "command_models", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743094987} +{"event": "command_models", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743095002} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743095041} +{"event": "repo", "properties": {"num_files": 582}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743095042} +{"event": "cli session", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743095042} +{"event": "command_context", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743102095} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743102095} +{"event": "command_context", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743102105} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743102105} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "context", "prompt_tokens": 12528, "completion_tokens": 367, "total_tokens": 12895, "cost": 0.043089, "total_cost": 0.5895780000000002}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743102115} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743102115} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "context", "prompt_tokens": 18645, "completion_tokens": 536, "total_tokens": 19181, "cost": 0.063975, "total_cost": 0.6535530000000002}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743102127} +{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743102138} +{"event": "command_drop", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743102141} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743102146} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 21548, "completion_tokens": 1188, "total_tokens": 22736, "cost": 0.08246400000000001, "total_cost": 0.7360170000000001}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743102170} +{"event": "exit", "properties": {"reason": "Control-C"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743102175} +{"event": "command_exit", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103485} +{"event": "exit", "properties": {"reason": "/exit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103485} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103517} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103521} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103563} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 3736, "completion_tokens": 702, "total_tokens": 4438, "cost": 0.021738, "total_cost": 0.021738}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103581} +{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103581} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103638} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103638} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103639} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 5711, "completion_tokens": 870, "total_tokens": 6581, "cost": 0.030183, "total_cost": 0.030183}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103659} +{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103659} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103802} +{"event": "repo", "properties": {"num_files": 582}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103802} +{"event": "cli session", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103802} +{"event": "command_context", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103805} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103808} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "context", "prompt_tokens": 12627, "completion_tokens": 489, "total_tokens": 13116, "cost": 0.045216, "total_cost": 0.045216}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103821} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103821} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "context", "prompt_tokens": 13715, "completion_tokens": 313, "total_tokens": 14028, "cost": 0.04584, "total_cost": 0.091056}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103828} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103970} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103971} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103971} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103971} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103971} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103971} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103971} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103971} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103971} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103972} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103972} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103972} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103972} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103972} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103972} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103972} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103972} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103972} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103972} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103972} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103972} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103973} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103973} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103973} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103973} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103973} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103973} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103973} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103973} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103974} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103974} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103974} +{"event": "exit", "properties": {"reason": "Control-C"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103974} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103974} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103974} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103974} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103974} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103974} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103975} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103975} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103975} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103975} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103975} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103975} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103975} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103975} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103975} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103975} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103975} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103975} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103976} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103976} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103976} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103976} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103976} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103976} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103976} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103976} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103977} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103977} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103977} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103977} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103977} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103977} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743103977} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743104021} +{"event": "repo", "properties": {"num_files": 582}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743104021} +{"event": "exit", "properties": {"reason": "Exit flag set"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743104021} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743104021} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743104022} +{"event": "repo", "properties": {"num_files": 582}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743104022} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743104022} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743104064} +{"event": "gui session", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743104064} +{"event": "exit", "properties": {"reason": "GUI session ended"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743104064} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743211859} +{"event": "repo", "properties": {"num_files": 582}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743211862} +{"event": "cli session", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743211863} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743211973} +{"event": "repo", "properties": {"num_files": 582}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743211973} +{"event": "cli session", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743211973} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743211974} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 11780, "completion_tokens": 2303, "total_tokens": 14083, "cost": 0.069885, "total_cost": 0.069885}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743212021} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743212039} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 8706, "completion_tokens": 553, "total_tokens": 9259, "cost": 0.034413, "total_cost": 0.034413}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743212053} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743212088} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 9058, "completion_tokens": 315, "total_tokens": 9373, "cost": 0.031899, "total_cost": 0.066312}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743212095} +{"event": "command_diff", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743212095} +{"event": "exit", "properties": {"reason": "Control-C"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743212170} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743212175} +{"event": "repo", "properties": {"num_files": 582}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743212176} +{"event": "exit", "properties": {"reason": "Completed lint/test/commit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743212185} +{"event": "command_ask", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743212196} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743212196} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 12041, "completion_tokens": 856, "total_tokens": 12897, "cost": 0.048963000000000007, "total_cost": 0.11884800000000001}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743212216} +{"event": "command_edit", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743212260} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743212507} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 14977, "completion_tokens": 2915, "total_tokens": 17892, "cost": 0.088656, "total_cost": 0.20750400000000002}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743212563} +{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743212722} +{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743212730} +{"event": "command_clear", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743212737} +{"event": "command_context", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743212793} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743212793} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "context", "prompt_tokens": 23088, "completion_tokens": 661, "total_tokens": 23749, "cost": 0.079179, "total_cost": 0.286683}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743212811} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743212826} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 19924, "completion_tokens": 4993, "total_tokens": 24917, "cost": 0.134667, "total_cost": 0.42135}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743212914} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743212930} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 25544, "completion_tokens": 589, "total_tokens": 26133, "cost": 0.085467, "total_cost": 0.506817}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743212949} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743213039} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 26349, "completion_tokens": 835, "total_tokens": 27184, "cost": 0.091572, "total_cost": 0.598389}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743213066} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743213189} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 26600, "completion_tokens": 2019, "total_tokens": 28619, "cost": 0.11008499999999999, "total_cost": 0.7084739999999999}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743213221} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743213441} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 27920, "completion_tokens": 1392, "total_tokens": 29312, "cost": 0.10464, "total_cost": 0.8131139999999999}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743213468} +{"event": "command_undo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743213482} +{"event": "command_ask", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743213555} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743213555} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "ask", "prompt_tokens": 26372, "completion_tokens": 1723, "total_tokens": 28095, "cost": 0.104961, "total_cost": 0.9180749999999999}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743213592} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743213597} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743213610} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 29397, "completion_tokens": 1492, "total_tokens": 30889, "cost": 0.110571, "total_cost": 1.028646}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743213637} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743213643} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 31255, "completion_tokens": 489, "total_tokens": 31744, "cost": 0.1011, "total_cost": 1.129746}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743213667} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743213744} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 31603, "completion_tokens": 1204, "total_tokens": 32807, "cost": 0.112869, "total_cost": 1.2426149999999998}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743213769} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743213868} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 32819, "completion_tokens": 890, "total_tokens": 33709, "cost": 0.111807, "total_cost": 1.3544219999999998}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743213888} +{"event": "command_context", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743213933} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743213933} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "context", "prompt_tokens": 34477, "completion_tokens": 547, "total_tokens": 35024, "cost": 0.11163600000000001, "total_cost": 1.4660579999999999}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743213950} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743213950} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "context", "prompt_tokens": 34541, "completion_tokens": 575, "total_tokens": 35116, "cost": 0.11224800000000001, "total_cost": 1.578306}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743213966} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743213966} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "context", "prompt_tokens": 29321, "completion_tokens": 393, "total_tokens": 29714, "cost": 0.093858, "total_cost": 1.672164}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743213977} +{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214001} +{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214011} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214016} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214053} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 45825, "completion_tokens": 743, "total_tokens": 46568, "cost": 0.14862, "total_cost": 1.820784}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214069} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214174} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 46312, "completion_tokens": 804, "total_tokens": 47116, "cost": 0.150996, "total_cost": 1.9717799999999999}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214194} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214210} +{"event": "repo", "properties": {"num_files": 582}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214210} +{"event": "exit", "properties": {"reason": "Completed lint/test/commit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214219} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214245} +{"event": "command_context", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214248} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214248} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "context", "prompt_tokens": 47920, "completion_tokens": 729, "total_tokens": 48649, "cost": 0.154695, "total_cost": 2.1264749999999997}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214269} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214269} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "context", "prompt_tokens": 34566, "completion_tokens": 591, "total_tokens": 35157, "cost": 0.112563, "total_cost": 2.239038}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214286} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214292} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 33816, "completion_tokens": 1565, "total_tokens": 35381, "cost": 0.12492299999999999, "total_cost": 2.3639609999999998}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214327} +{"event": "command_diff", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214348} +{"event": "command_diff", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214357} +{"event": "command_undo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214379} +{"event": "command_undo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214383} +{"event": "command_clear", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214411} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214413} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 18738, "completion_tokens": 693, "total_tokens": 19431, "cost": 0.066609, "total_cost": 2.43057}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214429} +{"event": "command_undo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214440} +{"event": "command_clear", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214446} +{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214451} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214493} +{"event": "repo", "properties": {"num_files": 582}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214493} +{"event": "cli session", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214493} +{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214497} +{"event": "command_read-only", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214502} +{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214504} +{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214508} +{"event": "exit", "properties": {"reason": "Control-C"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214520} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214525} +{"event": "repo", "properties": {"num_files": 582}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214525} +{"event": "cli session", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214525} +{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214528} +{"event": "command_exit", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214536} +{"event": "exit", "properties": {"reason": "/exit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214536} +{"event": "exit", "properties": {"reason": "Control-C"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214538} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214557} +{"event": "repo", "properties": {"num_files": 582}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214558} +{"event": "cli session", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214558} +{"event": "command_read-only", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214563} +{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214568} +{"event": "command_exit", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214571} +{"event": "exit", "properties": {"reason": "/exit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214571} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214574} +{"event": "repo", "properties": {"num_files": 582}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214574} +{"event": "cli session", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214574} +{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214576} +{"event": "command_read-only", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214580} +{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214583} +{"event": "command_exit", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214602} +{"event": "exit", "properties": {"reason": "/exit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214602} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214606} +{"event": "repo", "properties": {"num_files": 582}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214606} +{"event": "cli session", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214606} +{"event": "command_read-only", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214616} +{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214621} +{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214626} +{"event": "command_exit", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214628} +{"event": "exit", "properties": {"reason": "/exit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214628} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214641} +{"event": "repo", "properties": {"num_files": 582}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214642} +{"event": "cli session", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214642} +{"event": "command_read-only", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214644} +{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214653} +{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214664} +{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214669} +{"event": "command_exit", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214671} +{"event": "exit", "properties": {"reason": "/exit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214671} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214695} +{"event": "repo", "properties": {"num_files": 582}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214696} +{"event": "cli session", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214696} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214739} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "deepseek/deepseek-chat", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 10986, "completion_tokens": 440, "total_tokens": 11426, "cost": 0.039558, "total_cost": 0.039558}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214751} +{"event": "command_clear", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214755} +{"event": "command_context", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214758} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214758} +{"event": "exit", "properties": {"reason": "Control-C"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214770} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214775} +{"event": "repo", "properties": {"num_files": 582}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214776} +{"event": "cli session", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "deepseek/deepseek-chat", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "diff-fenced"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214776} +{"event": "command_context", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214780} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214780} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "deepseek/deepseek-chat", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "context", "prompt_tokens": 9672, "completion_tokens": 205, "total_tokens": 9877, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214796} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214796} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "deepseek/deepseek-chat", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "context", "prompt_tokens": 33035, "completion_tokens": 162, "total_tokens": 33197, "cost": 0.0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214804} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214805} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "deepseek/deepseek-chat", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "diff-fenced", "prompt_tokens": 32432, "completion_tokens": 429, "total_tokens": 32861, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214816} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214853} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "deepseek/deepseek-chat", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "diff-fenced", "prompt_tokens": 32902, "completion_tokens": 149, "total_tokens": 33051, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214858} +{"event": "command_context", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214968} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214968} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "deepseek/deepseek-chat", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "context", "prompt_tokens": 34025, "completion_tokens": 235, "total_tokens": 34260, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214981} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214981} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "deepseek/deepseek-chat", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "context", "prompt_tokens": 14564, "completion_tokens": 198, "total_tokens": 14762, "cost": 0.0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214987} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743214990} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "deepseek/deepseek-chat", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "diff-fenced", "prompt_tokens": 14190, "completion_tokens": 426, "total_tokens": 14616, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215009} +{"event": "command_diff", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215026} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215148} +{"event": "repo", "properties": {"num_files": 582}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215148} +{"event": "cli session", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "diff-fenced"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215148} +{"event": "command_context", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215157} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215157} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "context", "prompt_tokens": 8214, "completion_tokens": 238, "total_tokens": 8452, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215174} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215174} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "context", "prompt_tokens": 45867, "completion_tokens": 495, "total_tokens": 46362, "cost": 0.0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215189} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215190} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "context", "prompt_tokens": 60890, "completion_tokens": 552, "total_tokens": 61442, "cost": 0.0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215199} +{"event": "command_exit", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215203} +{"event": "exit", "properties": {"reason": "/exit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215203} +{"event": "command_exit", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215216} +{"event": "exit", "properties": {"reason": "/exit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215216} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215222} +{"event": "repo", "properties": {"num_files": 582}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215222} +{"event": "cli session", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "diff-fenced"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215222} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215226} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215227} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215227} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215227} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215227} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215227} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215227} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215227} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215227} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215227} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215227} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215227} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215227} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215228} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215228} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215228} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215228} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215228} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215228} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215228} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215228} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215229} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215229} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215229} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215229} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215229} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215229} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215229} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215229} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215229} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215229} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215229} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215230} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215230} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215230} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215230} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215230} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215230} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215230} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215230} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215230} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215231} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215231} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215231} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215231} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215231} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215231} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215231} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215231} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215231} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215231} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215231} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215232} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215232} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215232} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215232} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215232} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215232} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215232} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215232} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215232} +{"event": "command_edit", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215232} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215233} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215233} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215233} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215272} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215277} +{"event": "repo", "properties": {"num_files": 582}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215277} +{"event": "exit", "properties": {"reason": "Exit flag set"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215277} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215277} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215278} +{"event": "repo", "properties": {"num_files": 582}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215278} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215278} +{"event": "command_context", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215280} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215280} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "context", "prompt_tokens": 8126, "completion_tokens": 125, "total_tokens": 8251, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215292} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215292} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "context", "prompt_tokens": 33766, "completion_tokens": 151, "total_tokens": 33917, "cost": 0.0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215302} +{"event": "command_reset", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215309} +{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215311} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215327} +{"event": "gui session", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215327} +{"event": "exit", "properties": {"reason": "GUI session ended"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215327} +{"event": "command_context", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215330} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215330} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215341} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "diff-fenced", "prompt_tokens": 15443, "completion_tokens": 303, "total_tokens": 15746, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215349} +{"event": "command_undo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215406} +{"event": "command_model", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215409} +{"event": "command_code", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215413} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215413} +{"event": "command_chat-mode", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215424} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215445} +{"event": "repo", "properties": {"num_files": 582}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215445} +{"event": "cli session", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215445} +{"event": "command_context", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215494} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215494} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "context", "prompt_tokens": 8199, "completion_tokens": 580, "total_tokens": 8779, "cost": 0.033297, "total_cost": 0.033297}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215508} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215508} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "context", "prompt_tokens": 34804, "completion_tokens": 438, "total_tokens": 35242, "cost": 0.11098200000000001, "total_cost": 0.14427900000000002}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215522} +{"event": "command_reset", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215526} +{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215529} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215534} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 15376, "completion_tokens": 1181, "total_tokens": 16557, "cost": 0.06384300000000001, "total_cost": 0.20812200000000003}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215560} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215581} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 15957, "completion_tokens": 486, "total_tokens": 16443, "cost": 0.055161, "total_cost": 0.26328300000000004}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215596} +{"event": "command_undo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215625} +{"event": "command_undo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215629} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215721} +{"event": "repo", "properties": {"num_files": 582}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215721} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215721} +{"event": "exit", "properties": {"reason": "Control-C"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215728} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215729} +{"event": "exit", "properties": {"reason": "Completed lint/test/commit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215730} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215784} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215836} +{"event": "auto_model_selection", "properties": {"api_key": "ANTHROPIC_API_KEY"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215837} +{"event": "repo", "properties": {"num_files": 582}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215837} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215837} +{"event": "cli session", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215837} +{"event": "exit", "properties": {"reason": "Control-C"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215889} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215891} +{"event": "auto_model_selection", "properties": {"api_key": "ANTHROPIC_API_KEY"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215891} +{"event": "repo", "properties": {"num_files": 582}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215891} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215891} +{"event": "cli session", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215891} +{"event": "exit", "properties": {"reason": "Control-C"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215911} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215914} +{"event": "auto_model_selection", "properties": {"api_key": "ANTHROPIC_API_KEY"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215914} +{"event": "repo", "properties": {"num_files": 582}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215915} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215915} +{"event": "cli session", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215915} +{"event": "exit", "properties": {"reason": "Control-C"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743215936} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216126} +{"event": "auto_model_selection", "properties": {"api_key": "ANTHROPIC_API_KEY"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216126} +{"event": "repo", "properties": {"num_files": 582}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216126} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216126} +{"event": "exit", "properties": {"reason": "Completed lint/test/commit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216132} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216189} +{"event": "repo", "properties": {"num_files": 582}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216190} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216190} +{"event": "cli session", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "diff-fenced"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216190} +{"event": "command_context", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216192} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216192} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "context", "prompt_tokens": 8968, "completion_tokens": 60, "total_tokens": 9028, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216199} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216199} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "context", "prompt_tokens": 19388, "completion_tokens": 59, "total_tokens": 19447, "cost": 0.0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216204} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216208} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "diff-fenced", "prompt_tokens": 17957, "completion_tokens": 225, "total_tokens": 18182, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216216} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216295} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216296} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216296} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216296} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "diff-fenced", "prompt_tokens": 7330, "completion_tokens": 253, "total_tokens": 7583, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216313} +{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216313} +{"event": "command_ask", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216384} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216384} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "ask", "prompt_tokens": 17595, "completion_tokens": 477, "total_tokens": 18072, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216395} +{"event": "exit", "properties": {"reason": "Control-C"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216475} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216542} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216542} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216542} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216542} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216542} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216542} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216543} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216543} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216543} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216543} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216543} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216543} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216543} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216543} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216543} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216543} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216543} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216543} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216543} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216543} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216543} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216544} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216544} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216544} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216544} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216544} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216544} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216544} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216544} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216544} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216544} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216545} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216545} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216545} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216545} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216545} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216545} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216545} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216545} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216545} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216545} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216545} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216545} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216545} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216545} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216546} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216546} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216546} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216546} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216546} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216546} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216546} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216546} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216546} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216546} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216546} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216547} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216547} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216547} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216547} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216547} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216547} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216547} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216547} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216547} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216547} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216547} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216547} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216547} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216547} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216547} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216548} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216548} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216548} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216548} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216548} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216548} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216548} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216548} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216548} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216579} +{"event": "repo", "properties": {"num_files": 582}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216579} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216579} +{"event": "cli session", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "diff-fenced"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216579} +{"event": "command_context", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216588} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216588} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216593} +{"event": "repo", "properties": {"num_files": 582}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216593} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216593} +{"event": "exit", "properties": {"reason": "Exit flag set"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216593} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216593} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216594} +{"event": "repo", "properties": {"num_files": 582}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216594} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216594} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216594} +{"event": "command_context", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216596} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216596} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "context", "prompt_tokens": 7511, "completion_tokens": 128, "total_tokens": 7639, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216619} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216619} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "context", "prompt_tokens": 14283, "completion_tokens": 54, "total_tokens": 14337, "cost": 0.0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216626} +{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216640} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216643} +{"event": "gui session", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216644} +{"event": "exit", "properties": {"reason": "GUI session ended"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216644} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216652} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "diff-fenced", "prompt_tokens": 18200, "completion_tokens": 337, "total_tokens": 18537, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216661} +{"event": "exit", "properties": {"reason": "Control-C"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216672} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216686} +{"event": "repo", "properties": {"num_files": 583}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216687} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216687} +{"event": "cli session", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "diff-fenced"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216687} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216697} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "diff-fenced", "prompt_tokens": 9428, "completion_tokens": 129, "total_tokens": 9557, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216702} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216734} +{"event": "repo", "properties": {"num_files": 582}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216734} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216734} +{"event": "cli session", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "diff-fenced"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216734} +{"event": "command_context", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216759} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216759} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "context", "prompt_tokens": 9323, "completion_tokens": 235, "total_tokens": 9558, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216780} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216780} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "context", "prompt_tokens": 18117, "completion_tokens": 189, "total_tokens": 18306, "cost": 0.0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216791} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216794} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "diff-fenced", "prompt_tokens": 15970, "completion_tokens": 1026, "total_tokens": 16996, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216808} +{"event": "exit", "properties": {"reason": "Control-C"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216857} +{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216894} +{"event": "command_drop", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216905} +{"event": "command_ask", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216949} +{"event": "command_drop", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216961} +{"event": "command_ask", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216963} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743216973} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "ask", "prompt_tokens": 9025, "completion_tokens": 2501, "total_tokens": 11526, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743217027} +{"event": "command_ask", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743217080} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743217080} +{"event": "command_clear", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743217093} +{"event": "command_ask", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743217140} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743217151} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "ask", "prompt_tokens": 7423, "completion_tokens": 3114, "total_tokens": 10537, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743217214} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743217446} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "diff-fenced", "prompt_tokens": 12335, "completion_tokens": 584, "total_tokens": 12919, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743217465} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743217971} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "diff-fenced", "prompt_tokens": 12947, "completion_tokens": 3052, "total_tokens": 15999, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743218014} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743218037} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "diff-fenced", "prompt_tokens": 19069, "completion_tokens": 638, "total_tokens": 19707, "cost": 0.0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743218050} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743218059} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "diff-fenced", "prompt_tokens": 20153, "completion_tokens": 149, "total_tokens": 20302, "cost": 0.0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743218076} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743218146} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "diff-fenced", "prompt_tokens": 20368, "completion_tokens": 513, "total_tokens": 20881, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743218157} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743218178} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "diff-fenced", "prompt_tokens": 21430, "completion_tokens": 58, "total_tokens": 21488, "cost": 0.0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743218185} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743218446} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "diff-fenced", "prompt_tokens": 21559, "completion_tokens": 329, "total_tokens": 21888, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743218459} +{"event": "command_undo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743218517} +{"event": "command_undo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743218521} +{"event": "command_clear", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743218562} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743218584} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "diff-fenced", "prompt_tokens": 9419, "completion_tokens": 322, "total_tokens": 9741, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743218592} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743218691} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "diff-fenced", "prompt_tokens": 9813, "completion_tokens": 221, "total_tokens": 10034, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743218699} +{"event": "command_clear", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743218746} +{"event": "command_ask", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743218757} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743218757} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "ask", "prompt_tokens": 6959, "completion_tokens": 494, "total_tokens": 7453, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743218770} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743218860} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "diff-fenced", "prompt_tokens": 10829, "completion_tokens": 501, "total_tokens": 11330, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743218869} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743218989} +{"event": "repo", "properties": {"num_files": 583}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743218989} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743218989} +{"event": "cli session", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "diff-fenced"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743218989} +{"event": "exit", "properties": {"reason": "Control-C"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743218993} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743218999} +{"event": "repo", "properties": {"num_files": 583}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743219000} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743219000} +{"event": "exit", "properties": {"reason": "Exit flag set"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743219000} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743219143} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "diff-fenced", "prompt_tokens": 11513, "completion_tokens": 516, "total_tokens": 12029, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743219153} +{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743219180} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743219194} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "diff-fenced", "prompt_tokens": 20300, "completion_tokens": 336, "total_tokens": 20636, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743219205} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743219314} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "diff-fenced", "prompt_tokens": 20800, "completion_tokens": 257, "total_tokens": 21057, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743219321} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743219465} +{"event": "repo", "properties": {"num_files": 583}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743219465} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743219465} +{"event": "cli session", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "diff-fenced"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743219465} +{"event": "command_run", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743219474} +{"event": "exit", "properties": {"reason": "Control-C"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743219481} +{"event": "command_drop", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743219618} +{"event": "command_clear", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743219620} +{"event": "command_ask", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743219670} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743219675} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "ask", "prompt_tokens": 7461, "completion_tokens": 715, "total_tokens": 8176, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743219700} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743219960} +{"event": "repo", "properties": {"num_files": 583}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743219960} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743219960} +{"event": "exit", "properties": {"reason": "Completed lint/test/commit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743219972} +{"event": "command_clear", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743219973} +{"event": "ai-comments execute", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743220304} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743220304} +{"event": "exit", "properties": {"reason": "Control-C"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743220324} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743220326} +{"event": "repo", "properties": {"num_files": 583}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743220326} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743220326} +{"event": "cli session", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "diff-fenced"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743220326} +{"event": "exit", "properties": {"reason": "Control-C"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743220327} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743220343} +{"event": "repo", "properties": {"num_files": 583}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743220343} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743220343} +{"event": "cli session", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743220343} +{"event": "ai-comments file-add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743220346} +{"event": "ai-comments execute", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743220346} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743220346} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 9251, "completion_tokens": 2382, "total_tokens": 11633, "cost": 0.063483, "total_cost": 0.063483}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743220391} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743220395} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 11800, "completion_tokens": 301, "total_tokens": 12101, "cost": 0.039915, "total_cost": 0.10339799999999999}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743220405} +{"event": "ai-comments execute", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743220631} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743220631} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 12113, "completion_tokens": 409, "total_tokens": 12522, "cost": 0.042474000000000005, "total_cost": 0.145872}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743220642} +{"event": "ai-comments execute", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743220972} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743220972} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 12534, "completion_tokens": 411, "total_tokens": 12945, "cost": 0.043767, "total_cost": 0.189639}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743220981} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743221813} +{"event": "repo", "properties": {"num_files": 583}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743221813} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743221813} +{"event": "command_edit", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743221862} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743222512} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 14283, "completion_tokens": 1901, "total_tokens": 16184, "cost": 0.071364, "total_cost": 0.261003}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743222543} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743222557} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 15931, "completion_tokens": 294, "total_tokens": 16225, "cost": 0.052203, "total_cost": 0.313206}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743222564} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223472} +{"event": "message_send", "properties": {"main_model": "anthropic/claude-3-7-sonnet-20250219", "weak_model": "anthropic/claude-3-5-haiku-20241022", "editor_model": "anthropic/claude-3-7-sonnet-20250219", "edit_format": "diff", "prompt_tokens": 16096, "completion_tokens": 556, "total_tokens": 16652, "cost": 0.056628000000000005, "total_cost": 0.369834}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223496} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223524} +{"event": "repo", "properties": {"num_files": 583}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223525} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223525} +{"event": "exit", "properties": {"reason": "Control-C"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223525} +{"event": "exit", "properties": {"reason": "Completed lint/test/commit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223531} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223589} +{"event": "repo", "properties": {"num_files": 583}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223590} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223590} +{"event": "exit", "properties": {"reason": "Completed lint/test/commit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223599} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223723} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223724} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223724} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223724} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223724} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223724} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223724} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223724} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223724} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223724} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223724} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223724} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223724} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223724} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223724} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223724} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223725} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223725} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223725} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223725} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223725} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223725} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223725} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223725} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223725} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223725} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223725} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223725} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223725} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223725} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223725} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223726} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223726} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223726} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223726} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223726} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223726} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223726} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223726} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223726} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223726} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223727} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223727} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223727} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223727} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223727} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223727} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223727} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223727} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223727} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223727} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223728} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223728} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223728} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223728} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223728} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223728} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223728} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223728} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223728} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223728} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223728} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223728} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223728} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223728} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223728} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223729} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223729} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223729} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223729} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223729} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223729} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223729} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223729} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223729} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223729} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223729} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223729} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223729} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223729} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223774} +{"event": "repo", "properties": {"num_files": 583}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223775} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223775} +{"event": "exit", "properties": {"reason": "Exit flag set"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223775} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223775} +{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223776} +{"event": "repo", "properties": {"num_files": 583}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223776} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223776} +{"event": "exit", "properties": {"reason": "Unknown edit format"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223776} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223814} +{"event": "gui session", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223815} +{"event": "exit", "properties": {"reason": "GUI session ended"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223815} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223885} +{"event": "repo", "properties": {"num_files": 583}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223886} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223886} +{"event": "exit", "properties": {"reason": "Completed lint/test/commit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223895} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223939} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223939} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223939} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223939} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.5-pro-exp-03-25", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "diff-fenced", "prompt_tokens": 16498, "completion_tokens": 564, "total_tokens": 17062, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223965} +{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1743223965} diff --git a/aider/website/assets/sample.aider.conf.yml b/aider/website/assets/sample.aider.conf.yml index d93b69669..5bfe10c23 100644 --- a/aider/website/assets/sample.aider.conf.yml +++ b/aider/website/assets/sample.aider.conf.yml @@ -20,39 +20,6 @@ ## Specify the model to use for the main chat #model: xxx -## Use claude-3-opus-20240229 model for the main chat -#opus: false - -## Use anthropic/claude-3-7-sonnet-20250219 model for the main chat -#sonnet: false - -## Use claude-3-5-haiku-20241022 model for the main chat -#haiku: false - -## Use gpt-4-0613 model for the main chat -#4: false - -## Use gpt-4o model for the main chat -#4o: false - -## Use gpt-4o-mini model for the main chat -#mini: false - -## Use gpt-4-1106-preview model for the main chat -#4-turbo: false - -## Use gpt-3.5-turbo model for the main chat -#35turbo: false - -## Use deepseek/deepseek-chat model for the main chat -#deepseek: false - -## Use o1-mini model for the main chat -#o1-mini: false - -## Use o1-preview model for the main chat -#o1-preview: false - ######################## # API Keys and settings: @@ -116,6 +83,9 @@ ## Set the reasoning_effort API parameter (default: not set) #reasoning-effort: xxx +## Set the thinking token budget for models that support it (default: not set) +#thinking-tokens: xxx + ## Verify the SSL cert when connecting to models (default: True) #verify-ssl: true @@ -128,6 +98,9 @@ ## Use architect edit format for the main chat #architect: false +## Enable/disable automatic acceptance of architect changes (default: True) +#auto-accept-architect: true + ## Specify the model to use for commit messages and chat history summarization (default depends on --model) #weak-model: xxx @@ -140,6 +113,9 @@ ## Only work with models that have meta-data available (default: True) #show-model-warnings: true +## Check if model accepts settings like reasoning_effort/thinking_tokens (default: True) +#check-model-accepts-settings: true + ## Soft limit on tokens for chat history, after which summarization begins. If unspecified, defaults to the model's max_chat_history_tokens. #max-chat-history-tokens: xxx @@ -260,6 +236,9 @@ ## Prefix all commit messages with 'aider: ' (default: False) #attribute-commit-message-committer: false +## Enable/disable git pre-commit hooks with --no-verify (default: False) +#git-commit-verify: false + ## Commit all pending changes with a suitable commit message, then exit #commit: false @@ -442,3 +421,39 @@ ## Specify which editor to use for the /editor command #editor: xxx + +############################ +# Deprecated model settings: + +## Use claude-3-opus-20240229 model for the main chat (deprecated, use --model) +#opus: false + +## Use anthropic/claude-3-7-sonnet-20250219 model for the main chat (deprecated, use --model) +#sonnet: false + +## Use claude-3-5-haiku-20241022 model for the main chat (deprecated, use --model) +#haiku: false + +## Use gpt-4-0613 model for the main chat (deprecated, use --model) +#4: false + +## Use gpt-4o model for the main chat (deprecated, use --model) +#4o: false + +## Use gpt-4o-mini model for the main chat (deprecated, use --model) +#mini: false + +## Use gpt-4-1106-preview model for the main chat (deprecated, use --model) +#4-turbo: false + +## Use gpt-3.5-turbo model for the main chat (deprecated, use --model) +#35turbo: false + +## Use deepseek/deepseek-chat model for the main chat (deprecated, use --model) +#deepseek: false + +## Use o1-mini model for the main chat (deprecated, use --model) +#o1-mini: false + +## Use o1-preview model for the main chat (deprecated, use --model) +#o1-preview: false diff --git a/aider/website/assets/sample.env b/aider/website/assets/sample.env index db4a24e35..439e637de 100644 --- a/aider/website/assets/sample.env +++ b/aider/website/assets/sample.env @@ -24,39 +24,6 @@ ## Specify the model to use for the main chat #AIDER_MODEL= -## Use claude-3-opus-20240229 model for the main chat -#AIDER_OPUS= - -## Use anthropic/claude-3-7-sonnet-20250219 model for the main chat -#AIDER_SONNET= - -## Use claude-3-5-haiku-20241022 model for the main chat -#AIDER_HAIKU= - -## Use gpt-4-0613 model for the main chat -#AIDER_4= - -## Use gpt-4o model for the main chat -#AIDER_4O= - -## Use gpt-4o-mini model for the main chat -#AIDER_MINI= - -## Use gpt-4-1106-preview model for the main chat -#AIDER_4_TURBO= - -## Use gpt-3.5-turbo model for the main chat -#AIDER_35TURBO= - -## Use deepseek/deepseek-chat model for the main chat -#AIDER_DEEPSEEK= - -## Use o1-mini model for the main chat -#AIDER_O1_MINI= - -## Use o1-preview model for the main chat -#AIDER_O1_PREVIEW= - ######################## # API Keys and settings: @@ -105,6 +72,9 @@ ## Set the reasoning_effort API parameter (default: not set) #AIDER_REASONING_EFFORT= +## Set the thinking token budget for models that support it (default: not set) +#AIDER_THINKING_TOKENS= + ## Verify the SSL cert when connecting to models (default: True) #AIDER_VERIFY_SSL=true @@ -117,6 +87,9 @@ ## Use architect edit format for the main chat #AIDER_ARCHITECT= +## Enable/disable automatic acceptance of architect changes (default: True) +#AIDER_AUTO_ACCEPT_ARCHITECT=true + ## Specify the model to use for commit messages and chat history summarization (default depends on --model) #AIDER_WEAK_MODEL= @@ -129,6 +102,9 @@ ## Only work with models that have meta-data available (default: True) #AIDER_SHOW_MODEL_WARNINGS=true +## Check if model accepts settings like reasoning_effort/thinking_tokens (default: True) +#AIDER_CHECK_MODEL_ACCEPTS_SETTINGS=true + ## Soft limit on tokens for chat history, after which summarization begins. If unspecified, defaults to the model's max_chat_history_tokens. #AIDER_MAX_CHAT_HISTORY_TOKENS= @@ -249,6 +225,9 @@ ## Prefix all commit messages with 'aider: ' (default: False) #AIDER_ATTRIBUTE_COMMIT_MESSAGE_COMMITTER=false +## Enable/disable git pre-commit hooks with --no-verify (default: False) +#AIDER_GIT_COMMIT_VERIFY=false + ## Commit all pending changes with a suitable commit message, then exit #AIDER_COMMIT=false @@ -410,3 +389,39 @@ ## Specify which editor to use for the /editor command #AIDER_EDITOR= + +############################ +# Deprecated model settings: + +## Use claude-3-opus-20240229 model for the main chat (deprecated, use --model) +#AIDER_OPUS=false + +## Use anthropic/claude-3-7-sonnet-20250219 model for the main chat (deprecated, use --model) +#AIDER_SONNET=false + +## Use claude-3-5-haiku-20241022 model for the main chat (deprecated, use --model) +#AIDER_HAIKU=false + +## Use gpt-4-0613 model for the main chat (deprecated, use --model) +#AIDER_4=false + +## Use gpt-4o model for the main chat (deprecated, use --model) +#AIDER_4O=false + +## Use gpt-4o-mini model for the main chat (deprecated, use --model) +#AIDER_MINI=false + +## Use gpt-4-1106-preview model for the main chat (deprecated, use --model) +#AIDER_4_TURBO=false + +## Use gpt-3.5-turbo model for the main chat (deprecated, use --model) +#AIDER_35TURBO=false + +## Use deepseek/deepseek-chat model for the main chat (deprecated, use --model) +#AIDER_DEEPSEEK=false + +## Use o1-mini model for the main chat (deprecated, use --model) +#AIDER_O1_MINI=false + +## Use o1-preview model for the main chat (deprecated, use --model) +#AIDER_O1_PREVIEW=false diff --git a/aider/website/assets/thinking.jpg b/aider/website/assets/thinking.jpg new file mode 100644 index 000000000..159c894f4 Binary files /dev/null and b/aider/website/assets/thinking.jpg differ diff --git a/aider/website/docs/config/adv-model-settings.md b/aider/website/docs/config/adv-model-settings.md index d4946b838..bcaf4f603 100644 --- a/aider/website/docs/config/adv-model-settings.md +++ b/aider/website/docs/config/adv-model-settings.md @@ -84,7 +84,21 @@ Files loaded last will take priority. The yaml file should be a list of dictionary objects for each model. -### Global extra params +### Passing extra params to litellm.completion + +The `extra_params` attribute of model settings is used to pass arbitrary +extra parameters to the `litellm.completion()` call when sending data +to the given model. + +For example: + +```yaml +- name: some-provider/my-special-model + extra_params: + extra_headers: + Custom-Header: value + max_tokens: 8192 +``` You can use the special model name `aider/extra_params` to define `extra_params` that will be passed to `litellm.completion()` for all models. @@ -162,6 +176,7 @@ cog.out("```\n") use_repo_map: false send_undo_reply: false lazy: false + overeager: false reminder: user examples_as_sys_msg: false extra_params: null @@ -172,8 +187,10 @@ cog.out("```\n") streaming: true editor_model_name: null editor_edit_format: null + reasoning_tag: null remove_reasoning: null system_prompt_prefix: null + accepts_settings: null - name: anthropic/claude-3-5-haiku-20241022 edit_format: diff @@ -227,6 +244,7 @@ cog.out("```\n") edit_format: diff weak_model_name: anthropic/claude-3-5-haiku-20241022 use_repo_map: true + overeager: true examples_as_sys_msg: true extra_params: extra_headers: @@ -235,11 +253,14 @@ cog.out("```\n") cache_control: true editor_model_name: anthropic/claude-3-7-sonnet-20250219 editor_edit_format: editor-diff + accepts_settings: + - thinking_tokens - name: anthropic/claude-3-7-sonnet-latest edit_format: diff weak_model_name: anthropic/claude-3-5-haiku-20241022 use_repo_map: true + overeager: true examples_as_sys_msg: true extra_params: extra_headers: @@ -248,6 +269,8 @@ cog.out("```\n") cache_control: true editor_model_name: anthropic/claude-3-7-sonnet-latest editor_edit_format: editor-diff + accepts_settings: + - thinking_tokens - name: anthropic/claude-3-haiku-20240307 weak_model_name: anthropic/claude-3-haiku-20240307 @@ -265,6 +288,8 @@ cog.out("```\n") streaming: false editor_model_name: azure/gpt-4o editor_edit_format: editor-diff + accepts_settings: + - reasoning_effort - name: azure/o1-mini weak_model_name: azure/gpt-4o-mini @@ -291,6 +316,8 @@ cog.out("```\n") editor_model_name: azure/gpt-4o editor_edit_format: editor-diff system_prompt_prefix: 'Formatting re-enabled. ' + accepts_settings: + - reasoning_effort - name: bedrock/anthropic.claude-3-5-haiku-20241022-v1:0 edit_format: diff @@ -318,6 +345,7 @@ cog.out("```\n") edit_format: diff weak_model_name: bedrock/anthropic.claude-3-5-haiku-20241022-v1:0 use_repo_map: true + overeager: true examples_as_sys_msg: true extra_params: extra_headers: @@ -326,11 +354,14 @@ cog.out("```\n") cache_control: true editor_model_name: bedrock/anthropic.claude-3-7-sonnet-20250219-v1:0 editor_edit_format: editor-diff + accepts_settings: + - thinking_tokens - name: bedrock/us.anthropic.claude-3-7-sonnet-20250219-v1:0 edit_format: diff weak_model_name: bedrock/us.anthropic.claude-3-5-haiku-20241022-v1:0 use_repo_map: true + overeager: true examples_as_sys_msg: true extra_params: extra_headers: @@ -339,11 +370,14 @@ cog.out("```\n") cache_control: true editor_model_name: bedrock/us.anthropic.claude-3-7-sonnet-20250219-v1:0 editor_edit_format: editor-diff + accepts_settings: + - thinking_tokens - name: bedrock_converse/anthropic.claude-3-7-sonnet-20250219-v1:0 edit_format: diff weak_model_name: bedrock_converse/anthropic.claude-3-5-haiku-20241022-v1:0 use_repo_map: true + overeager: true examples_as_sys_msg: true extra_params: extra_headers: @@ -352,11 +386,14 @@ cog.out("```\n") cache_control: true editor_model_name: bedrock_converse/anthropic.claude-3-7-sonnet-20250219-v1:0 editor_edit_format: editor-diff + accepts_settings: + - thinking_tokens - name: bedrock_converse/us.anthropic.claude-3-7-sonnet-20250219-v1:0 edit_format: diff weak_model_name: bedrock_converse/us.anthropic.claude-3-5-haiku-20241022-v1:0 use_repo_map: true + overeager: true examples_as_sys_msg: true extra_params: extra_headers: @@ -365,6 +402,8 @@ cog.out("```\n") cache_control: true editor_model_name: bedrock_converse/us.anthropic.claude-3-7-sonnet-20250219-v1:0 editor_edit_format: editor-diff + accepts_settings: + - thinking_tokens - name: claude-3-5-haiku-20241022 edit_format: diff @@ -414,11 +453,14 @@ cog.out("```\n") cache_control: true editor_model_name: claude-3-7-sonnet-20250219 editor_edit_format: editor-diff + accepts_settings: + - thinking_tokens - name: claude-3-7-sonnet-latest edit_format: diff weak_model_name: claude-3-5-haiku-20241022 use_repo_map: true + overeager: true examples_as_sys_msg: true extra_params: extra_headers: @@ -427,6 +469,8 @@ cog.out("```\n") cache_control: true editor_model_name: claude-3-7-sonnet-latest editor_edit_format: editor-diff + accepts_settings: + - thinking_tokens - name: claude-3-haiku-20240307 weak_model_name: claude-3-haiku-20240307 @@ -444,6 +488,9 @@ cog.out("```\n") - name: claude-3-sonnet-20240229 weak_model_name: claude-3-5-haiku-20241022 +- name: cohere_chat/command-a-03-2025 + examples_as_sys_msg: true + - name: command-r-08-2024 weak_model_name: command-r-08-2024 use_repo_map: true @@ -512,7 +559,7 @@ cog.out("```\n") use_temperature: false editor_model_name: fireworks_ai/accounts/fireworks/models/deepseek-v3 editor_edit_format: editor-diff - remove_reasoning: think + reasoning_tag: think - name: fireworks_ai/accounts/fireworks/models/deepseek-v3 edit_format: diff @@ -533,7 +580,7 @@ cog.out("```\n") use_temperature: 0.6 editor_model_name: fireworks_ai/accounts/fireworks/models/qwen2p5-coder-32b-instruct editor_edit_format: editor-diff - remove_reasoning: think + reasoning_tag: think - name: gemini/gemini-1.5-flash-002 @@ -563,6 +610,10 @@ cog.out("```\n") edit_format: diff use_repo_map: true +- name: gemini/gemini-2.5-pro-exp-03-25 + edit_format: diff-fenced + use_repo_map: true + - name: gemini/gemini-exp-1114 edit_format: diff use_repo_map: true @@ -575,6 +626,9 @@ cog.out("```\n") edit_format: diff use_repo_map: true +- name: gemini/gemma-3-27b-it + use_system_prompt: false + - name: gpt-3.5-turbo weak_model_name: gpt-4o-mini reminder: sys @@ -704,7 +758,7 @@ cog.out("```\n") use_temperature: 0.6 editor_model_name: groq/qwen-2.5-coder-32b editor_edit_format: editor-diff - remove_reasoning: think + reasoning_tag: think - name: o1 edit_format: diff @@ -715,6 +769,8 @@ cog.out("```\n") editor_model_name: gpt-4o editor_edit_format: editor-diff system_prompt_prefix: 'Formatting re-enabled. ' + accepts_settings: + - reasoning_effort - name: o1-mini weak_model_name: gpt-4o-mini @@ -741,6 +797,8 @@ cog.out("```\n") editor_model_name: gpt-4o editor_edit_format: editor-diff system_prompt_prefix: 'Formatting re-enabled. ' + accepts_settings: + - reasoning_effort - name: openai/gpt-4.5-preview edit_format: diff @@ -791,6 +849,8 @@ cog.out("```\n") editor_model_name: openai/gpt-4o editor_edit_format: editor-diff system_prompt_prefix: 'Formatting re-enabled. ' + accepts_settings: + - reasoning_effort - name: openai/o1-mini weak_model_name: openai/gpt-4o-mini @@ -817,6 +877,8 @@ cog.out("```\n") editor_model_name: gpt-4o editor_edit_format: editor-diff system_prompt_prefix: 'Formatting re-enabled. ' + accepts_settings: + - reasoning_effort - name: openrouter/anthropic/claude-3-opus edit_format: diff @@ -849,6 +911,7 @@ cog.out("```\n") edit_format: diff weak_model_name: openrouter/anthropic/claude-3-5-haiku use_repo_map: true + overeager: true examples_as_sys_msg: true extra_params: extra_headers: @@ -857,11 +920,14 @@ cog.out("```\n") cache_control: true editor_model_name: openrouter/anthropic/claude-3.7-sonnet editor_edit_format: editor-diff + accepts_settings: + - thinking_tokens - name: openrouter/anthropic/claude-3.7-sonnet:beta edit_format: diff weak_model_name: openrouter/anthropic/claude-3-5-haiku use_repo_map: true + overeager: true examples_as_sys_msg: true extra_params: extra_headers: @@ -870,6 +936,11 @@ cog.out("```\n") cache_control: true editor_model_name: openrouter/anthropic/claude-3.7-sonnet editor_edit_format: editor-diff + accepts_settings: + - thinking_tokens + +- name: openrouter/cohere/command-a-03-2025 + examples_as_sys_msg: true - name: openrouter/deepseek/deepseek-chat edit_format: diff @@ -877,6 +948,15 @@ cog.out("```\n") reminder: sys examples_as_sys_msg: true +- name: openrouter/deepseek/deepseek-chat-v3-0324 + edit_format: diff + use_repo_map: true + reminder: sys + examples_as_sys_msg: true + extra_params: + max_tokens: 8192 + caches_by_default: true + - name: openrouter/deepseek/deepseek-chat:free edit_format: diff weak_model_name: openrouter/deepseek/deepseek-chat:free @@ -902,8 +982,8 @@ cog.out("```\n") examples_as_sys_msg: true extra_params: max_tokens: 8192 + include_reasoning: true caches_by_default: true - use_temperature: false editor_model_name: openrouter/deepseek/deepseek-chat editor_edit_format: editor-diff @@ -931,6 +1011,16 @@ cog.out("```\n") editor_model_name: openrouter/deepseek/deepseek-r1:free editor_edit_format: editor-diff +- name: openrouter/google/gemini-2.5-pro-exp-03-25:free + edit_format: diff-fenced + use_repo_map: true + +- name: openrouter/google/gemma-3-27b-it + use_system_prompt: false + +- name: openrouter/google/gemma-3-27b-it:free + use_system_prompt: false + - name: openrouter/meta-llama/llama-3-70b-instruct edit_format: diff weak_model_name: openrouter/meta-llama/llama-3-70b-instruct @@ -954,6 +1044,8 @@ cog.out("```\n") editor_model_name: openrouter/openai/gpt-4o editor_edit_format: editor-diff system_prompt_prefix: 'Formatting re-enabled. ' + accepts_settings: + - reasoning_effort - name: openrouter/openai/o1-mini weak_model_name: openrouter/openai/gpt-4o-mini @@ -982,6 +1074,8 @@ cog.out("```\n") editor_model_name: openrouter/openai/gpt-4o editor_edit_format: editor-diff system_prompt_prefix: 'Formatting re-enabled. ' + accepts_settings: + - reasoning_effort - name: openrouter/openai/o3-mini-high edit_format: diff @@ -991,6 +1085,8 @@ cog.out("```\n") editor_model_name: openrouter/openai/gpt-4o editor_edit_format: editor-diff system_prompt_prefix: 'Formatting re-enabled. ' + accepts_settings: + - reasoning_effort - name: openrouter/qwen/qwen-2.5-coder-32b-instruct edit_format: diff @@ -1003,11 +1099,14 @@ cog.out("```\n") edit_format: diff weak_model_name: vertex_ai/claude-3-5-haiku@20241022 use_repo_map: true + overeager: true examples_as_sys_msg: true extra_params: max_tokens: 64000 editor_model_name: vertex_ai-anthropic_models/vertex_ai/claude-3-7-sonnet@20250219 editor_edit_format: editor-diff + accepts_settings: + - thinking_tokens - name: vertex_ai/claude-3-5-haiku@20241022 edit_format: diff @@ -1040,11 +1139,14 @@ cog.out("```\n") edit_format: diff weak_model_name: vertex_ai/claude-3-5-haiku@20241022 use_repo_map: true + overeager: true examples_as_sys_msg: true extra_params: max_tokens: 64000 editor_model_name: vertex_ai/claude-3-7-sonnet@20250219 editor_edit_format: editor-diff + accepts_settings: + - thinking_tokens - name: vertex_ai/claude-3-opus@20240229 edit_format: diff @@ -1054,6 +1156,10 @@ cog.out("```\n") - name: vertex_ai/claude-3-sonnet@20240229 weak_model_name: vertex_ai/claude-3-5-haiku@20241022 +- name: vertex_ai/gemini-2.5-pro-exp-03-25 + edit_format: diff-fenced + use_repo_map: true + - name: vertex_ai/gemini-pro-experimental edit_format: diff-fenced use_repo_map: true diff --git a/aider/website/docs/config/aider_conf.md b/aider/website/docs/config/aider_conf.md index 683de1f9d..c98f90329 100644 --- a/aider/website/docs/config/aider_conf.md +++ b/aider/website/docs/config/aider_conf.md @@ -74,39 +74,6 @@ cog.outl("```") ## Specify the model to use for the main chat #model: xxx -## Use claude-3-opus-20240229 model for the main chat -#opus: false - -## Use anthropic/claude-3-7-sonnet-20250219 model for the main chat -#sonnet: false - -## Use claude-3-5-haiku-20241022 model for the main chat -#haiku: false - -## Use gpt-4-0613 model for the main chat -#4: false - -## Use gpt-4o model for the main chat -#4o: false - -## Use gpt-4o-mini model for the main chat -#mini: false - -## Use gpt-4-1106-preview model for the main chat -#4-turbo: false - -## Use gpt-3.5-turbo model for the main chat -#35turbo: false - -## Use deepseek/deepseek-chat model for the main chat -#deepseek: false - -## Use o1-mini model for the main chat -#o1-mini: false - -## Use o1-preview model for the main chat -#o1-preview: false - ######################## # API Keys and settings: @@ -170,6 +137,9 @@ cog.outl("```") ## Set the reasoning_effort API parameter (default: not set) #reasoning-effort: xxx +## Set the thinking token budget for models that support it (default: not set) +#thinking-tokens: xxx + ## Verify the SSL cert when connecting to models (default: True) #verify-ssl: true @@ -182,6 +152,9 @@ cog.outl("```") ## Use architect edit format for the main chat #architect: false +## Enable/disable automatic acceptance of architect changes (default: True) +#auto-accept-architect: true + ## Specify the model to use for commit messages and chat history summarization (default depends on --model) #weak-model: xxx @@ -194,6 +167,9 @@ cog.outl("```") ## Only work with models that have meta-data available (default: True) #show-model-warnings: true +## Check if model accepts settings like reasoning_effort/thinking_tokens (default: True) +#check-model-accepts-settings: true + ## Soft limit on tokens for chat history, after which summarization begins. If unspecified, defaults to the model's max_chat_history_tokens. #max-chat-history-tokens: xxx @@ -314,6 +290,9 @@ cog.outl("```") ## Prefix all commit messages with 'aider: ' (default: False) #attribute-commit-message-committer: false +## Enable/disable git pre-commit hooks with --no-verify (default: False) +#git-commit-verify: false + ## Commit all pending changes with a suitable commit message, then exit #commit: false @@ -496,5 +475,41 @@ cog.outl("```") ## Specify which editor to use for the /editor command #editor: xxx + +############################ +# Deprecated model settings: + +## Use claude-3-opus-20240229 model for the main chat (deprecated, use --model) +#opus: false + +## Use anthropic/claude-3-7-sonnet-20250219 model for the main chat (deprecated, use --model) +#sonnet: false + +## Use claude-3-5-haiku-20241022 model for the main chat (deprecated, use --model) +#haiku: false + +## Use gpt-4-0613 model for the main chat (deprecated, use --model) +#4: false + +## Use gpt-4o model for the main chat (deprecated, use --model) +#4o: false + +## Use gpt-4o-mini model for the main chat (deprecated, use --model) +#mini: false + +## Use gpt-4-1106-preview model for the main chat (deprecated, use --model) +#4-turbo: false + +## Use gpt-3.5-turbo model for the main chat (deprecated, use --model) +#35turbo: false + +## Use deepseek/deepseek-chat model for the main chat (deprecated, use --model) +#deepseek: false + +## Use o1-mini model for the main chat (deprecated, use --model) +#o1-mini: false + +## Use o1-preview model for the main chat (deprecated, use --model) +#o1-preview: false ``` diff --git a/aider/website/docs/config/dotenv.md b/aider/website/docs/config/dotenv.md index bbfc1ed3d..5a1c616e8 100644 --- a/aider/website/docs/config/dotenv.md +++ b/aider/website/docs/config/dotenv.md @@ -64,39 +64,6 @@ cog.outl("```") ## Specify the model to use for the main chat #AIDER_MODEL= -## Use claude-3-opus-20240229 model for the main chat -#AIDER_OPUS= - -## Use anthropic/claude-3-7-sonnet-20250219 model for the main chat -#AIDER_SONNET= - -## Use claude-3-5-haiku-20241022 model for the main chat -#AIDER_HAIKU= - -## Use gpt-4-0613 model for the main chat -#AIDER_4= - -## Use gpt-4o model for the main chat -#AIDER_4O= - -## Use gpt-4o-mini model for the main chat -#AIDER_MINI= - -## Use gpt-4-1106-preview model for the main chat -#AIDER_4_TURBO= - -## Use gpt-3.5-turbo model for the main chat -#AIDER_35TURBO= - -## Use deepseek/deepseek-chat model for the main chat -#AIDER_DEEPSEEK= - -## Use o1-mini model for the main chat -#AIDER_O1_MINI= - -## Use o1-preview model for the main chat -#AIDER_O1_PREVIEW= - ######################## # API Keys and settings: @@ -145,6 +112,9 @@ cog.outl("```") ## Set the reasoning_effort API parameter (default: not set) #AIDER_REASONING_EFFORT= +## Set the thinking token budget for models that support it (default: not set) +#AIDER_THINKING_TOKENS= + ## Verify the SSL cert when connecting to models (default: True) #AIDER_VERIFY_SSL=true @@ -157,6 +127,9 @@ cog.outl("```") ## Use architect edit format for the main chat #AIDER_ARCHITECT= +## Enable/disable automatic acceptance of architect changes (default: True) +#AIDER_AUTO_ACCEPT_ARCHITECT=true + ## Specify the model to use for commit messages and chat history summarization (default depends on --model) #AIDER_WEAK_MODEL= @@ -169,6 +142,9 @@ cog.outl("```") ## Only work with models that have meta-data available (default: True) #AIDER_SHOW_MODEL_WARNINGS=true +## Check if model accepts settings like reasoning_effort/thinking_tokens (default: True) +#AIDER_CHECK_MODEL_ACCEPTS_SETTINGS=true + ## Soft limit on tokens for chat history, after which summarization begins. If unspecified, defaults to the model's max_chat_history_tokens. #AIDER_MAX_CHAT_HISTORY_TOKENS= @@ -289,6 +265,9 @@ cog.outl("```") ## Prefix all commit messages with 'aider: ' (default: False) #AIDER_ATTRIBUTE_COMMIT_MESSAGE_COMMITTER=false +## Enable/disable git pre-commit hooks with --no-verify (default: False) +#AIDER_GIT_COMMIT_VERIFY=false + ## Commit all pending changes with a suitable commit message, then exit #AIDER_COMMIT=false @@ -450,5 +429,41 @@ cog.outl("```") ## Specify which editor to use for the /editor command #AIDER_EDITOR= + +############################ +# Deprecated model settings: + +## Use claude-3-opus-20240229 model for the main chat (deprecated, use --model) +#AIDER_OPUS=false + +## Use anthropic/claude-3-7-sonnet-20250219 model for the main chat (deprecated, use --model) +#AIDER_SONNET=false + +## Use claude-3-5-haiku-20241022 model for the main chat (deprecated, use --model) +#AIDER_HAIKU=false + +## Use gpt-4-0613 model for the main chat (deprecated, use --model) +#AIDER_4=false + +## Use gpt-4o model for the main chat (deprecated, use --model) +#AIDER_4O=false + +## Use gpt-4o-mini model for the main chat (deprecated, use --model) +#AIDER_MINI=false + +## Use gpt-4-1106-preview model for the main chat (deprecated, use --model) +#AIDER_4_TURBO=false + +## Use gpt-3.5-turbo model for the main chat (deprecated, use --model) +#AIDER_35TURBO=false + +## Use deepseek/deepseek-chat model for the main chat (deprecated, use --model) +#AIDER_DEEPSEEK=false + +## Use o1-mini model for the main chat (deprecated, use --model) +#AIDER_O1_MINI=false + +## Use o1-preview model for the main chat (deprecated, use --model) +#AIDER_O1_PREVIEW=false ``` diff --git a/aider/website/docs/config/model-aliases.md b/aider/website/docs/config/model-aliases.md index abffe3f61..e80876155 100644 --- a/aider/website/docs/config/model-aliases.md +++ b/aider/website/docs/config/model-aliases.md @@ -20,7 +20,8 @@ Multiple aliases can be defined by using the `--alias` option multiple times. Ea ## Configuration File -You can also define aliases in your [`.aider.conf.yml` file](https://aider.chat/docs/config/aider_conf.html): +Of course, +you can also define aliases in your [`.aider.conf.yml` file](https://aider.chat/docs/config/aider_conf.html): ```yaml alias: @@ -31,13 +32,35 @@ alias: ## Using Aliases -Once defined, you can use the alias instead of the full model name: +Once defined, you can use the alias instead of the full model name from the command line: ```bash aider --model fast # Uses gpt-4o-mini aider --model smart # Uses o3-mini ``` +Or with the `/model` command in-chat: + +``` +Aider v0.75.3 +Main model: anthropic/claude-3-7-sonnet-20250219 with diff edit format, prompt cache, infinite output +Weak model: claude-3-5-sonnet-20241022 +Git repo: .git with 406 files +Repo-map: using 4096 tokens, files refresh +───────────────────────────────────────────────────────────────────────────────────────────────────── +> /model fast + +Aider v0.75.3 +Main model: gpt-4o-mini with diff edit format +───────────────────────────────────────────────────────────────────────────────────────────────────── +diff> /model smart + +Aider v0.75.3 +Main model: o3-mini with diff edit format +───────────────────────────────────────────────────────────────────────────────────────────────────── +> +``` + ## Built-in Aliases Aider includes some built-in aliases for convenience: @@ -57,6 +80,8 @@ for alias, model in sorted(MODEL_ALIASES.items()): - `4o`: gpt-4o - `deepseek`: deepseek/deepseek-chat - `flash`: gemini/gemini-2.0-flash-exp +- `gemini`: gemini/gemini-2.5-pro-exp-03-25 +- `gemini-2.5-pro`: gemini/gemini-2.5-pro-exp-03-25 - `haiku`: claude-3-5-haiku-20241022 - `opus`: claude-3-opus-20240229 - `r1`: deepseek/deepseek-reasoner diff --git a/aider/website/docs/config/options.md b/aider/website/docs/config/options.md index 977e8642f..d07234921 100644 --- a/aider/website/docs/config/options.md +++ b/aider/website/docs/config/options.md @@ -22,19 +22,18 @@ from aider.args import get_md_help cog.out(get_md_help()) ]]]--> ``` -usage: aider [-h] [--model] [--opus] [--sonnet] [--haiku] [--4] - [--4o] [--mini] [--4-turbo] [--35turbo] [--deepseek] - [--o1-mini] [--o1-preview] [--openai-api-key] - [--anthropic-api-key] [--openai-api-base] - [--openai-api-type] [--openai-api-version] - [--openai-api-deployment-id] [--openai-organization-id] - [--set-env] [--api-key] [--list-models] - [--model-settings-file] [--model-metadata-file] - [--alias] [--reasoning-effort] - [--verify-ssl | --no-verify-ssl] [--timeout] - [--edit-format] [--architect] [--weak-model] - [--editor-model] [--editor-edit-format] +usage: aider [-h] [--model] [--openai-api-key] [--anthropic-api-key] + [--openai-api-base] [--openai-api-type] + [--openai-api-version] [--openai-api-deployment-id] + [--openai-organization-id] [--set-env] [--api-key] + [--list-models] [--model-settings-file] + [--model-metadata-file] [--alias] [--reasoning-effort] + [--thinking-tokens] [--verify-ssl | --no-verify-ssl] + [--timeout] [--edit-format] [--architect] + [--auto-accept-architect | --no-auto-accept-architect] + [--weak-model] [--editor-model] [--editor-edit-format] [--show-model-warnings | --no-show-model-warnings] + [--check-model-accepts-settings | --no-check-model-accepts-settings] [--max-chat-history-tokens] [--cache-prompts | --no-cache-prompts] [--cache-keepalive-pings] [--map-tokens] @@ -57,6 +56,7 @@ usage: aider [-h] [--model] [--opus] [--sonnet] [--haiku] [--4] [--attribute-committer | --no-attribute-committer] [--attribute-commit-message-author | --no-attribute-commit-message-author] [--attribute-commit-message-committer | --no-attribute-commit-message-committer] + [--git-commit-verify | --no-git-commit-verify] [--commit] [--commit-prompt] [--dry-run | --no-dry-run] [--skip-sanity-check-repo] [--watch-files | --no-watch-files] [--lint] @@ -80,7 +80,9 @@ usage: aider [-h] [--model] [--opus] [--sonnet] [--haiku] [--4] [--multiline | --no-multiline] [--notifications | --no-notifications] [--notifications-command] - [--detect-urls | --no-detect-urls] [--editor] + [--detect-urls | --no-detect-urls] [--editor] [--opus] + [--sonnet] [--haiku] [--4] [--4o] [--mini] [--4-turbo] + [--35turbo] [--deepseek] [--o1-mini] [--o1-preview] ``` @@ -98,58 +100,6 @@ Aliases: Specify the model to use for the main chat Environment variable: `AIDER_MODEL` -### `--opus` -Use claude-3-opus-20240229 model for the main chat -Environment variable: `AIDER_OPUS` - -### `--sonnet` -Use anthropic/claude-3-7-sonnet-20250219 model for the main chat -Environment variable: `AIDER_SONNET` - -### `--haiku` -Use claude-3-5-haiku-20241022 model for the main chat -Environment variable: `AIDER_HAIKU` - -### `--4` -Use gpt-4-0613 model for the main chat -Environment variable: `AIDER_4` -Aliases: - - `--4` - - `-4` - -### `--4o` -Use gpt-4o model for the main chat -Environment variable: `AIDER_4O` - -### `--mini` -Use gpt-4o-mini model for the main chat -Environment variable: `AIDER_MINI` - -### `--4-turbo` -Use gpt-4-1106-preview model for the main chat -Environment variable: `AIDER_4_TURBO` - -### `--35turbo` -Use gpt-3.5-turbo model for the main chat -Environment variable: `AIDER_35TURBO` -Aliases: - - `--35turbo` - - `--35-turbo` - - `--3` - - `-3` - -### `--deepseek` -Use deepseek/deepseek-chat model for the main chat -Environment variable: `AIDER_DEEPSEEK` - -### `--o1-mini` -Use o1-mini model for the main chat -Environment variable: `AIDER_O1_MINI` - -### `--o1-preview` -Use o1-preview model for the main chat -Environment variable: `AIDER_O1_PREVIEW` - ## API Keys and settings: ### `--openai-api-key VALUE` @@ -217,6 +167,10 @@ Environment variable: `AIDER_ALIAS` Set the reasoning_effort API parameter (default: not set) Environment variable: `AIDER_REASONING_EFFORT` +### `--thinking-tokens VALUE` +Set the thinking token budget for models that support it (default: not set) +Environment variable: `AIDER_THINKING_TOKENS` + ### `--verify-ssl` Verify the SSL cert when connecting to models (default: True) Default: True @@ -240,6 +194,14 @@ Aliases: Use architect edit format for the main chat Environment variable: `AIDER_ARCHITECT` +### `--auto-accept-architect` +Enable/disable automatic acceptance of architect changes (default: True) +Default: True +Environment variable: `AIDER_AUTO_ACCEPT_ARCHITECT` +Aliases: + - `--auto-accept-architect` + - `--no-auto-accept-architect` + ### `--weak-model WEAK_MODEL` Specify the model to use for commit messages and chat history summarization (default depends on --model) Environment variable: `AIDER_WEAK_MODEL` @@ -260,6 +222,14 @@ Aliases: - `--show-model-warnings` - `--no-show-model-warnings` +### `--check-model-accepts-settings` +Check if model accepts settings like reasoning_effort/thinking_tokens (default: True) +Default: True +Environment variable: `AIDER_CHECK_MODEL_ACCEPTS_SETTINGS` +Aliases: + - `--check-model-accepts-settings` + - `--no-check-model-accepts-settings` + ### `--max-chat-history-tokens VALUE` Soft limit on tokens for chat history, after which summarization begins. If unspecified, defaults to the model's max_chat_history_tokens. Environment variable: `AIDER_MAX_CHAT_HISTORY_TOKENS` @@ -473,6 +443,14 @@ Aliases: - `--attribute-commit-message-committer` - `--no-attribute-commit-message-committer` +### `--git-commit-verify` +Enable/disable git pre-commit hooks with --no-verify (default: False) +Default: False +Environment variable: `AIDER_GIT_COMMIT_VERIFY` +Aliases: + - `--git-commit-verify` + - `--no-git-commit-verify` + ### `--commit` Commit all pending changes with a suitable commit message, then exit Default: False @@ -775,4 +753,69 @@ Aliases: ### `--editor VALUE` Specify which editor to use for the /editor command Environment variable: `AIDER_EDITOR` + +## Deprecated model settings: + +### `--opus` +Use claude-3-opus-20240229 model for the main chat (deprecated, use --model) +Default: False +Environment variable: `AIDER_OPUS` + +### `--sonnet` +Use anthropic/claude-3-7-sonnet-20250219 model for the main chat (deprecated, use --model) +Default: False +Environment variable: `AIDER_SONNET` + +### `--haiku` +Use claude-3-5-haiku-20241022 model for the main chat (deprecated, use --model) +Default: False +Environment variable: `AIDER_HAIKU` + +### `--4` +Use gpt-4-0613 model for the main chat (deprecated, use --model) +Default: False +Environment variable: `AIDER_4` +Aliases: + - `--4` + - `-4` + +### `--4o` +Use gpt-4o model for the main chat (deprecated, use --model) +Default: False +Environment variable: `AIDER_4O` + +### `--mini` +Use gpt-4o-mini model for the main chat (deprecated, use --model) +Default: False +Environment variable: `AIDER_MINI` + +### `--4-turbo` +Use gpt-4-1106-preview model for the main chat (deprecated, use --model) +Default: False +Environment variable: `AIDER_4_TURBO` + +### `--35turbo` +Use gpt-3.5-turbo model for the main chat (deprecated, use --model) +Default: False +Environment variable: `AIDER_35TURBO` +Aliases: + - `--35turbo` + - `--35-turbo` + - `--3` + - `-3` + +### `--deepseek` +Use deepseek/deepseek-chat model for the main chat (deprecated, use --model) +Default: False +Environment variable: `AIDER_DEEPSEEK` + +### `--o1-mini` +Use o1-mini model for the main chat (deprecated, use --model) +Default: False +Environment variable: `AIDER_O1_MINI` + +### `--o1-preview` +Use o1-preview model for the main chat (deprecated, use --model) +Default: False +Environment variable: `AIDER_O1_PREVIEW` diff --git a/aider/website/docs/config/reasoning.md b/aider/website/docs/config/reasoning.md index 9147b0338..168516feb 100644 --- a/aider/website/docs/config/reasoning.md +++ b/aider/website/docs/config/reasoning.md @@ -6,29 +6,170 @@ description: How to configure reasoning model settings from secondary providers. # Reasoning models -Many -"reasoning" models have restrictions on how they can be used: -they sometimes prohibit streaming, use of temperature and/or the system prompt. -Some also support different levels of "reasoning effort". +![Thinking demo](/assets/thinking.jpg) -Aider is configured to work properly with these models -when served through major provider APIs. +## Basic usage -You may need to [configure model settings](/docs/config/adv-model-settings.html) -if you are using them through another provider -and see errors related to temperature or system prompt. +Aider is configured to work with most popular reasoning models out of the box. +You can use them like this: -Include settings for your new provider in `.aider.model.setting.yml` file -at the root of your project or in your home directory. +```bash +# Sonnet uses a thinking token budget +aider --model sonnet --thinking-tokens 8k -## Reasoning effort +# o3-mini uses low/medium/high reasoning effort +aider --model o3-mini --reasoning-effort high + +# R1 doesn't have configurable thinking/reasoning +aider --model r1 +``` + +Inside the aider chat, you can use `/thinking-tokens 4k` or `/reasoning-effort low` to change +the amount of reasoning. + +The rest of this document describes more advanced details which are mainly needed +if you're configuring aider to work with a lesser known reasoning model or one served +via an unusual provider. + +## Reasoning settings + +Different models support different reasoning settings. Aider provides several ways to control reasoning behavior: + +### Reasoning effort You can use the `--reasoning-effort` switch to control the reasoning effort of models which support this setting. +This switch is useful for OpenAI's reasoning models, which accept "low", "medium" and "high". -## Temperature, streaming and system prompt +### Thinking tokens -You should find one of the existing model setting configuration entries +You can use the `--thinking-tokens` switch to request +the model use a certain number of thinking tokens. +This switch is useful for Sonnet 3.7. +You can specify the token budget like "1024", "1k", "8k" or "0.01M". + +### Model compatibility and settings + +Not all models support these two settings. Aider uses the +[model's metadata](/docs/config/adv-model-settings.html) +to determine which settings each model accepts: + +```yaml +- name: o3-mini + ... + accepts_settings: ["reasoning_effort"] +``` + +If you try to use a setting that a model doesn't explicitly support, Aider will warn you: + +``` +Warning: o3-mini does not support 'thinking_tokens', ignoring. +Use --no-check-model-accepts-settings to force the 'thinking_tokens' setting. +``` + +The warning informs you that: +1. The setting won't be applied because the model doesn't list it in `accepts_settings` +2. You can use `--no-check-model-accepts-settings` to force the setting anyway + +This functionality helps prevent API errors while still allowing you to experiment with settings when needed. + +Each model has a predefined list of supported settings in its configuration. For example: + +- OpenAI reasoning models generally support `reasoning_effort` +- Anthropic reasoning models generally support `thinking_tokens` + + +### How `accepts_settings` works + +Models define which reasoning settings they accept using the `accepts_settings` property: + +```yaml +- name: a-fancy-reasoning-model + edit_format: diff + use_repo_map: true + accepts_settings: # <--- + - reasoning_effort # <--- +``` + +This configuration: +1. Tells Aider that the model accepts the `reasoning_effort` setting +2. Indicates the model does NOT accept `thinking_tokens` (since it's not listed) +3. Causes Aider to ignore any `--thinking-tokens` value passed for this model +4. Generates a warning if you try to use `--thinking-tokens` with this model + +You can override this behavior with `--no-check-model-accepts-settings`, which will: +1. Force Aider to apply all settings passed via command line +2. Skip all compatibility checks +3. Potentially cause API errors if the model truly doesn't support the setting + +This is useful when testing new models or using models through custom API providers. + + +## Thinking tokens in XML tags + +There is also a `reasoning_tag` setting, which takes the name of an XML tag +that the model uses to wrap its reasoning/thinking output. + +For example when using DeepSeek R1 from Fireworks, the reasoning comes back inside +`...` tags, so aider's settings +include `reasoning_tag: think`. + +``` + +The user wants me to greet them! + + +Hello! +``` + +Aider will display the thinking/reasoning output, +but it won't be used for file editing instructions, added to the chat history, etc. +Aider will rely on the non-thinking output for instructions on how to make code changes, etc. + +### Model-specific reasoning tags + +Different models use different XML tags for their reasoning: +When using custom or self-hosted models, you may need to specify the appropriate reasoning tag in your configuration. + +```yaml +- name: fireworks_ai/accounts/fireworks/models/deepseek-r1 + edit_format: diff + weak_model_name: fireworks_ai/accounts/fireworks/models/deepseek-v3 + use_repo_map: true + extra_params: + max_tokens: 160000 + use_temperature: false + editor_model_name: fireworks_ai/accounts/fireworks/models/deepseek-v3 + editor_edit_format: editor-diff + reasoning_tag: think # <--- +``` + +## Reasoning model limitations + +Many "reasoning" models have restrictions on how they can be used: +they sometimes prohibit streaming, use of temperature and/or the system prompt. +Aider is configured to work properly with popular models +when served through major provider APIs. + +If you're using a model through a different provider (like Azure or custom deployment), +you may need to [configure model settings](/docs/config/adv-model-settings.html) +if you see errors related to temperature or system prompt. + +Include settings for your new provider in `.aider.model.settings.yml` file +at the root of your project or in your home directory. + +### Temperature, streaming and system prompt + +Reasoning models often have specific requirements for these settings: + +| Setting | Description | Common Restrictions | +|---------|-------------|---------------------| +| `use_temperature` | Whether to use temperature sampling | Many reasoning models require this set to `false` | +| `streaming` | Whether to stream responses | Some reasoning models don't support streaming | +| `use_system_prompt` | Whether to use system prompt | Some reasoning models don't support system prompts | + +It may be helpful to find one of the +[existing model setting configuration entries](https://github.com/Aider-AI/aider/blob/main/aider/resources/model-settings.yml) for the model you are interested in, say o3-mini: ```yaml @@ -39,6 +180,7 @@ for the model you are interested in, say o3-mini: use_temperature: false # <--- editor_model_name: gpt-4o editor_edit_format: editor-diff + accepts_settings: ["reasoning_effort"] ``` Pay attention to these settings, which must be set to `false` @@ -48,8 +190,9 @@ for certain reasoning models: - `streaming` - `use_system_prompt` -Here's an example of -the settings to use o3-mini via Azure. +### Custom provider example + +Here's an example of the settings to use o3-mini via Azure. Note that aider already has these settings pre-configured, but they serve as a good example of how to adapt the main model settings for a different provider. @@ -62,29 +205,5 @@ settings for a different provider. use_temperature: false # <--- editor_model_name: azure/gpt-4o editor_edit_format: editor-diff -``` - -## Thinking tokens - -There is also a `remove_reasoning` setting, which takes the name of a tag. -This is used to remove everything inside that XML tag pair. - -For example when using DeepSeek R1 from Fireworks, the reasoning comes back inside -`...` tags, so aider's settings -include `remove_reasoning: think` to remove that part of the response. - -Aider will still *display* think reasoning output, it just won't use it -to find file editing instructions, etc. - -```yaml -- name: fireworks_ai/accounts/fireworks/models/deepseek-r1 - edit_format: diff - weak_model_name: fireworks_ai/accounts/fireworks/models/deepseek-v3 - use_repo_map: true - extra_params: - max_tokens: 160000 - use_temperature: false - editor_model_name: fireworks_ai/accounts/fireworks/models/deepseek-v3 - editor_edit_format: editor-diff - remove_reasoning: think # <--- + accepts_settings: ["reasoning_effort"] ``` diff --git a/aider/website/docs/faq.md b/aider/website/docs/faq.md index 2fde49cbb..7135ada5f 100644 --- a/aider/website/docs/faq.md +++ b/aider/website/docs/faq.md @@ -153,6 +153,21 @@ Add 6.9k tokens of command output to the chat? (Y)es/(N)o [Yes]: Yes /ask Are there any problems with the way this change works with the FooBar class? ``` +And of course you can prepare diff output outside of aider and provide it as +a file for aider to read: + +``` +$ git diff -C10 v1..v2 > v1-v2-changes.diff +$ aider --read v1-v2-changes.diff + +Aider v0.77.2.dev+import +Main model: anthropic/claude-3-7-sonnet-20250219 with diff edit format, 8k think tokens +────────────────────────────────── +v1-v2-changes.diff +> Do you see any potential bugs in this PR? +``` + + {: .tip } The `/git` command will not work for this purpose, as its output is not included in the chat. @@ -249,11 +264,9 @@ tr:hover { background-color: #f5f5f5; } - - - - - + + +
    Model NameTotal TokensPercent
    anthropic/claude-3-7-sonnet-202502191,948,55099.0%
    fireworks_ai/accounts/fireworks/models/deepseek-r114,9610.8%
    deepseek/deepseek-reasoner4,4300.2%
    o3-mini970.0%
    claude-3-7-sonnet-20250219930.0%
    anthropic/claude-3-7-sonnet-202502191,466,93459.5%
    gemini/gemini-2.5-pro-exp-03-25968,70439.3%
    deepseek/deepseek-chat30,3071.2%
    diff --git a/aider/website/docs/git.md b/aider/website/docs/git.md index 3c17de47f..00ee5a272 100644 --- a/aider/website/docs/git.md +++ b/aider/website/docs/git.md @@ -40,6 +40,7 @@ While it is not recommended, you can disable aider's use of git in a few ways: - `--no-auto-commits` will stop aider from git committing each of its changes. - `--no-dirty-commits` will stop aider from committing dirty files before applying its edits. - `--no-git` will completely stop aider from using git on your files. You should ensure you are keeping sensible backups of the files you are working with. + - `--git-commit-verify` will run pre-commit hooks when making git commits. By default, aider skips pre-commit hooks by using the `--no-verify` flag (`--git-commit-verify=False`). ## Commit messages diff --git a/aider/website/docs/index.md b/aider/website/docs/index.md new file mode 100644 index 000000000..e0b952565 --- /dev/null +++ b/aider/website/docs/index.md @@ -0,0 +1,47 @@ +--- +nav_exclude: true +--- + +# Aider Documentation + +Aider is AI pair programming in your terminal. This documentation will help you get the most out of aider. + +
    +{% assign pages_list = site.html_pages | sort: "nav_order" %} + +
      +{% for page in pages_list %} + {% if page.title and page.url != "/" and page.parent == nil and page.nav_exclude != true %} +
    • + {{ page.title }}{% if page.description %} — {{ page.description }}{% endif %} + + {% assign children = site.html_pages | where: "parent", page.title | sort: "nav_order" %} + {% if children.size > 0 %} +
        + {% for child in children %} + {% if child.title %} +
      • + {{ child.title }}{% if child.description %} — {{ child.description }}{% endif %} + + {% assign grandchildren = site.html_pages | where: "parent", child.title | sort: "nav_order" %} + {% if grandchildren.size > 0 %} +
          + {% for grandchild in grandchildren %} + {% if grandchild.title %} +
        • + {{ grandchild.title }}{% if grandchild.description %} — {{ grandchild.description }}{% endif %} +
        • + {% endif %} + {% endfor %} +
        + {% endif %} +
      • + {% endif %} + {% endfor %} +
      + {% endif %} +
    • + {% endif %} +{% endfor %} +
    +
    diff --git a/aider/website/docs/languages.md b/aider/website/docs/languages.md index 731a7c7d5..216a3fc90 100644 --- a/aider/website/docs/languages.md +++ b/aider/website/docs/languages.md @@ -55,55 +55,208 @@ cog.out(get_supported_languages_md()) | Language | File extension | Repo map | Linter | |:--------:|:--------------:|:--------:|:------:| +| actionscript | .as | | ✓ | +| ada | .adb | | ✓ | +| ada | .ads | | ✓ | +| agda | .agda | | ✓ | +| arduino | .ino | ✓ | ✓ | +| asm | .asm | | ✓ | +| asm | .s | | ✓ | +| astro | .astro | | ✓ | | bash | .bash | | ✓ | +| bash | .sh | | ✓ | +| bash | .zsh | | ✓ | +| beancount | .bean | | ✓ | +| bibtex | .bib | | ✓ | +| bicep | .bicep | | ✓ | +| bitbake | .bb | | ✓ | +| bitbake | .bbappend | | ✓ | +| bitbake | .bbclass | | ✓ | | c | .c | ✓ | ✓ | -| commonlisp | .cl | | ✓ | +| c | .h | ✓ | ✓ | +| cairo | .cairo | | ✓ | +| capnp | .capnp | | ✓ | +| chatito | .chatito | ✓ | ✓ | +| clarity | .clar | | ✓ | +| clojure | .clj | | ✓ | +| clojure | .cljc | | ✓ | +| clojure | .cljs | | ✓ | +| clojure | .edn | | ✓ | +| cmake | .cmake | | ✓ | +| cmake | CMakeLists.txt | | ✓ | +| commonlisp | .cl | ✓ | ✓ | +| commonlisp | .lisp | ✓ | ✓ | +| cpon | .cpon | | ✓ | | cpp | .cc | ✓ | ✓ | | cpp | .cpp | ✓ | ✓ | +| cpp | .cxx | ✓ | ✓ | +| cpp | .h++ | ✓ | ✓ | +| cpp | .hpp | ✓ | ✓ | +| cpp | .hxx | ✓ | ✓ | | csharp | .cs | ✓ | ✓ | | css | .css | | ✓ | -| dockerfile | .dockerfile | | ✓ | -| dot | .dot | | ✓ | +| csv | .csv | | ✓ | +| cuda | .cu | | ✓ | +| cuda | .cuh | | ✓ | +| d | .d | ✓ | ✓ | +| dart | .dart | ✓ | ✓ | +| dockerfile | Dockerfile | | ✓ | +| dtd | .dtd | | ✓ | | elisp | .el | ✓ | ✓ | | elixir | .ex | ✓ | ✓ | +| elixir | .exs | ✓ | ✓ | | elm | .elm | ✓ | ✓ | -| embedded_template | .et | | ✓ | | erlang | .erl | | ✓ | +| erlang | .hrl | | ✓ | +| fennel | .fnl | | ✓ | +| firrtl | .fir | | ✓ | +| fish | .fish | | ✓ | +| fortran | .f | | ✓ | +| fortran | .f03 | | ✓ | +| fortran | .f08 | | ✓ | +| fortran | .f90 | | ✓ | +| fortran | .f95 | | ✓ | +| func | .fc | | ✓ | +| gdscript | .gd | | ✓ | +| gitattributes | .gitattributes | | ✓ | +| gitcommit | .gitcommit | | ✓ | +| gitignore | .gitignore | | ✓ | +| gleam | .gleam | ✓ | ✓ | +| glsl | .frag | | ✓ | +| glsl | .glsl | | ✓ | +| glsl | .vert | | ✓ | +| gn | .gn | | ✓ | +| gn | .gni | | ✓ | | go | .go | ✓ | ✓ | -| gomod | .gomod | | ✓ | +| gomod | go.mod | | ✓ | +| gosum | go.sum | | ✓ | +| groovy | .groovy | | ✓ | +| gstlaunch | .launch | | ✓ | | hack | .hack | | ✓ | +| hare | .ha | | ✓ | | haskell | .hs | | ✓ | +| haxe | .hx | | ✓ | | hcl | .hcl | ✓ | ✓ | | hcl | .tf | ✓ | ✓ | +| hcl | .tfvars | ✓ | ✓ | +| heex | .heex | | ✓ | +| hlsl | .hlsl | | ✓ | +| html | .htm | | ✓ | | html | .html | | ✓ | +| hyprlang | .hypr | | ✓ | +| ispc | .ispc | | ✓ | +| janet | .janet | | ✓ | | java | .java | ✓ | ✓ | | javascript | .js | ✓ | ✓ | +| javascript | .jsx | ✓ | ✓ | | javascript | .mjs | ✓ | ✓ | | jsdoc | .jsdoc | | ✓ | | json | .json | | ✓ | +| jsonnet | .jsonnet | | ✓ | +| jsonnet | .libsonnet | | ✓ | | julia | .jl | | ✓ | +| kconfig | Kconfig | | ✓ | +| kdl | .kdl | | ✓ | | kotlin | .kt | ✓ | ✓ | -| lua | .lua | | ✓ | +| kotlin | .kts | ✓ | ✓ | +| latex | .cls | | ✓ | +| latex | .sty | | ✓ | +| latex | .tex | | ✓ | +| linkerscript | .ld | | ✓ | +| llvm | .ll | | ✓ | +| lua | .lua | ✓ | ✓ | +| luadoc | .luadoc | | ✓ | +| luap | .luap | | ✓ | +| luau | .luau | | ✓ | +| magik | .magik | | ✓ | | make | .mk | | ✓ | +| make | Makefile | | ✓ | +| markdown | .markdown | | ✓ | | markdown | .md | | ✓ | -| objc | .m | | ✓ | +| matlab | .m | | ✓ | +| matlab | .mat | | ✓ | +| mermaid | .mermaid | | ✓ | +| meson | meson.build | | ✓ | +| ninja | .ninja | | ✓ | +| nix | .nix | | ✓ | +| nqc | .nqc | | ✓ | +| objc | .mm | | ✓ | +| odin | .odin | | ✓ | +| org | .org | | ✓ | +| pascal | .pas | | ✓ | +| pascal | .pp | | ✓ | +| pem | .pem | | ✓ | | perl | .pl | | ✓ | +| perl | .pm | | ✓ | +| pgn | .pgn | | ✓ | | php | .php | ✓ | ✓ | +| po | .po | | ✓ | +| po | .pot | | ✓ | +| pony | .pony | ✓ | ✓ | +| powershell | .ps1 | | ✓ | +| powershell | .psm1 | | ✓ | +| printf | .printf | | ✓ | +| prisma | .prisma | | ✓ | +| properties | .properties | ✓ | ✓ | +| proto | .proto | | ✓ | +| psv | .psv | | ✓ | +| purescript | .purs | | ✓ | +| pymanifest | MANIFEST.in | | ✓ | | python | .py | ✓ | ✓ | -| r | .R | | ✓ | -| r | .r | | ✓ | -| regex | .regex | | ✓ | +| qmldir | qmldir | | ✓ | +| qmljs | .qml | | ✓ | +| r | .R | ✓ | ✓ | +| r | .r | ✓ | ✓ | +| racket | .rkt | ✓ | ✓ | +| re2c | .re2c | | ✓ | +| readline | .inputrc | | ✓ | +| requirements | requirements.txt | | ✓ | +| ron | .ron | | ✓ | | rst | .rst | | ✓ | | ruby | .rb | ✓ | ✓ | | rust | .rs | ✓ | ✓ | +| scala | .sc | | ✓ | | scala | .scala | | ✓ | +| scheme | .scm | | ✓ | +| scheme | .ss | | ✓ | +| scss | .scss | | ✓ | +| smali | .smali | | ✓ | +| smithy | .smithy | | ✓ | +| solidity | .sol | ✓ | ✓ | +| sparql | .rq | | ✓ | | sql | .sql | | ✓ | -| sqlite | .sqlite | | ✓ | +| squirrel | .nut | | ✓ | +| starlark | .bzl | | ✓ | +| starlark | BUILD | | ✓ | +| starlark | WORKSPACE | | ✓ | +| svelte | .svelte | | ✓ | +| swift | .swift | ✓ | ✓ | +| tablegen | .td | | ✓ | +| tcl | .tcl | | ✓ | +| thrift | .thrift | | ✓ | | toml | .toml | | ✓ | -| tsq | .tsq | | ✓ | +| tsv | .tsv | | ✓ | +| twig | .twig | | ✓ | | typescript | .ts | ✓ | ✓ | | typescript | .tsx | ✓ | ✓ | -| yaml | .yaml | | ✓ | +| typst | .typ | | ✓ | +| udev | .rules | ✓ | ✓ | +| ungrammar | .ungram | | ✓ | +| uxntal | .tal | | ✓ | +| verilog | .sv | | ✓ | +| verilog | .v | | ✓ | +| vhdl | .vhd | | ✓ | +| vhdl | .vhdl | | ✓ | +| vim | .vim | | ✓ | +| vim | .vimrc | | ✓ | +| vue | .vue | | ✓ | +| wgsl | .wgsl | | ✓ | +| xcompose | .XCompose | | ✓ | +| xml | .svg | | ✓ | +| xml | .xml | | ✓ | +| xml | .xsl | | ✓ | +| yuck | .yuck | | ✓ | +| zig | .zig | | ✓ | diff --git a/aider/website/docs/leaderboards/index.md b/aider/website/docs/leaderboards/index.md index cd142e261..38e511a28 100644 --- a/aider/website/docs/leaderboards/index.md +++ b/aider/website/docs/leaderboards/index.md @@ -41,11 +41,11 @@ The model also has to successfully apply all its changes to the source file with Model - Percent completed correctly + Percent correct Percent using correct edit format Command Edit format - Total Cost + Cost @@ -88,6 +88,14 @@ The model also has to successfully apply all its changes to the source file with td:nth-child(3), td:nth-child(4) { font-size: 12px; } + + /* Hide command and edit format columns on mobile */ + @media screen and (max-width: 767px) { + th:nth-child(4), td:nth-child(4), /* Command column */ + th:nth-child(5), td:nth-child(5) { /* Edit format column */ + display: none; + } + } @@ -116,6 +124,6 @@ mod_dates = [get_last_modified_date(file) for file in files] latest_mod_date = max(mod_dates) cog.out(f"{latest_mod_date.strftime('%B %d, %Y.')}") ]]]--> -March 07, 2025. +March 25, 2025.

    diff --git a/aider/website/docs/llms/anthropic.md b/aider/website/docs/llms/anthropic.md index 514f27b45..cf69ab610 100644 --- a/aider/website/docs/llms/anthropic.md +++ b/aider/website/docs/llms/anthropic.md @@ -19,11 +19,11 @@ python -m pip install -U aider-chat export ANTHROPIC_API_KEY= # Mac/Linux setx ANTHROPIC_API_KEY # Windows, restart shell after setx -# Aider uses Claude 3.7 Sonnet by default (or use --sonnet) +# Aider uses Claude 3.7 Sonnet by default aider # Claude 3 Opus -aider --opus +aider --model claude-3-opus-20240229 # List models available from Anthropic aider --list-models anthropic/ diff --git a/aider/website/docs/llms/deepseek.md b/aider/website/docs/llms/deepseek.md index c49c49c7e..72073c1df 100644 --- a/aider/website/docs/llms/deepseek.md +++ b/aider/website/docs/llms/deepseek.md @@ -16,6 +16,6 @@ export DEEPSEEK_API_KEY= # Mac/Linux setx DEEPSEEK_API_KEY # Windows, restart shell after setx # Use DeepSeek Chat v3 -aider --deepseek +aider --model deepseek/deepseek-chat ``` diff --git a/aider/website/docs/llms/gemini.md b/aider/website/docs/llms/gemini.md index 8d8234d88..8cd70d5de 100644 --- a/aider/website/docs/llms/gemini.md +++ b/aider/website/docs/llms/gemini.md @@ -19,7 +19,8 @@ pipx inject aider-chat google-generativeai export GEMINI_API_KEY= # Mac/Linux setx GEMINI_API_KEY # Windows, restart shell after setx -aider --model gemini/gemini-1.5-pro-latest +# You can run the Gemini 2.5 Pro model with: +aider --model gemini-2.5-pro # List models available from Gemini aider --list-models gemini/ diff --git a/aider/website/docs/llms/ollama.md b/aider/website/docs/llms/ollama.md index 014baa175..463dc4a3e 100644 --- a/aider/website/docs/llms/ollama.md +++ b/aider/website/docs/llms/ollama.md @@ -11,8 +11,8 @@ Aider can connect to local Ollama models. # Pull the model ollama pull -# Start your ollama server -ollama serve +# Start your ollama server, increasing the context window to 8k tokens +OLLAMA_CONTEXT_LENGTH=8192 ollama serve # In another terminal window... python -m pip install -U aider-chat diff --git a/aider/website/docs/llms/openai.md b/aider/website/docs/llms/openai.md index 638087d32..a9d907afb 100644 --- a/aider/website/docs/llms/openai.md +++ b/aider/website/docs/llms/openai.md @@ -23,7 +23,7 @@ aider --model o3-mini --api-key openai= aider --model o1-mini --api-key openai= # GPT-4o -aider --4o --api-key openai= +aider --model gpt-4o --api-key openai= # List models available from OpenAI aider --list-models openai/ diff --git a/aider/website/docs/recordings/auto-accept-architect.md b/aider/website/docs/recordings/auto-accept-architect.md new file mode 100644 index 000000000..a2d741e22 --- /dev/null +++ b/aider/website/docs/recordings/auto-accept-architect.md @@ -0,0 +1,31 @@ +--- +parent: Screen recordings +nav_order: 1 +layout: minimal +highlight_image: /assets/recordings.jpg +description: See how a new command-line option is added to automatically accept edits proposed by the architect model, with implementation. Aider also updates the project's HISTORY file. +--- + +# Add --auto-accept-architect feature + + + +{% include recording.md %} + +## Commentary + +- 0:01 We're going to add a new feature to automatically accept edits proposed by the architect model. +- 0:11 First, let's add the new switch. +- 0:40 Aider figured out that it should be passed to the Coder class. +- 0:48 Now we need to implement the functionality. +- 1:00 Let's do some manual testing. +- 1:28 That worked. Let's make sure we can turn it off too. +- 1:42 That worked too. Let's have aider update the HISTORY file to document the new feature. +- 2:00 Let's quickly tidy up the changes to HISTORY. +- 2:05 All done! + + + diff --git a/aider/website/docs/recordings/dont-drop-original-read-files.md b/aider/website/docs/recordings/dont-drop-original-read-files.md new file mode 100644 index 000000000..675f4dc21 --- /dev/null +++ b/aider/website/docs/recordings/dont-drop-original-read-files.md @@ -0,0 +1,35 @@ +--- +parent: Screen recordings +nav_order: 1 +layout: minimal +highlight_image: /assets/recordings.jpg +description: Follow along as aider is modified to preserve read-only files specified at launch when using the /drop command. Aider does this implementation and adds test coverage. +--- + +# Don't /drop read-only files added at launch + + + +{% include recording.md %} + +## Commentary + +- 0:01 We're going to update the /drop command to keep any read only files that were originally specified at launch. +- 0:10 We've added files that handle the main CLI and in-chat slash commands like /drop. +- 0:20 Let's explain the needed change to aider. +- 1:20 Ok, let's look at the code. +- 1:30 I'd prefer not to use "hasattr()", let's ask for improvements. +- 1:45 Let's try some manual testing. +- 2:10 Looks good. Let's check the existing test suite to ensure we didn't break anything. +- 2:19 Let's ask aider to add tests for this. +- 2:50 Tests look reasonable, we're done! + + + + + + + diff --git a/aider/website/docs/recordings/index.md b/aider/website/docs/recordings/index.md new file mode 100644 index 000000000..ac549039d --- /dev/null +++ b/aider/website/docs/recordings/index.md @@ -0,0 +1,21 @@ +--- +title: Screen recordings +has_children: true +nav_order: 75 +has_toc: false +description: Screen recordings of aider building aider. +highlight_image: /assets/recordings.jpg +--- + +# Screen recordings + +Below are a series of screen recordings of the aider developer using aider +to enhance aider. +They contain commentary that describes how aider is being used, +and might provide some inspiration for your own use of aider. + +{% assign sorted_pages = site.pages | where: "parent", "Screen recordings" | sort: "nav_order" %} +{% for page in sorted_pages %} +- [{{ page.title }}]({{ page.url | relative_url }}) - {{ page.description }} +{% endfor %} + diff --git a/aider/website/docs/recordings/model-accepts-settings.md b/aider/website/docs/recordings/model-accepts-settings.md new file mode 100644 index 000000000..3cf5d3e20 --- /dev/null +++ b/aider/website/docs/recordings/model-accepts-settings.md @@ -0,0 +1,69 @@ +--- +parent: Screen recordings +nav_order: 1 +layout: minimal +highlight_image: /assets/recordings.jpg +description: Watch the implementation of a warning system that alerts users when they try to apply reasoning settings to models that don't support them. Includes adding model metadata, confirmation dialogs, refactoring, and comprehensive test coverage. +--- + +# Warn when users apply unsupported reasoning settings + + + +{% include recording.md %} + +## Commentary + +- 0:01 Users sometimes run aider with "reasoning" settings that aren't supported by the model they're using. This can cause LLM API calls to completely fail, with non-specific error messages from the API provider. We're going to warn users up front to prevent this. +- 0:25 Ok, let's ask aider to add a new model setting where we can note which reasoning settings it supports. And then print a warning if the user tries to apply an unsupported setting. +- 1:30 Looks like it's including some extra changes we don't want. +- 1:45 Let's have a look at the models code and clean up some stray lines. +- 2:00 It also made the warning logic too conservative. We want to warn unless the setting is explicitly known to be supported. +- 3:00 Ok, good. Now lets add a setting to silence these warnings for power users who are doing something intentional. +- 3:45 Now we need to update the database of model settings to annotate which models support which reasoning settings. We'll start with the code that handles "fallback" settings for known models on unknown providers. +- 4:45 Oh, we forgot to give aider the actual file with that code! Aider asks to see it. +- 5:00 Ok, we've confused aider by asking it to change code it couldn't see. +- 5:10 Let's clear the chat and refine the prompt and try again. +- 6:00 Ok, looks good. Let's move on and update the full model settings database YAML file. Each main model like "o1" appears here from many providers, like OpenAI, OpenRouter, etc. We want to update them all. +- 7:43 Let's interrupt and refine the prompt to be more clear about which models to update. +- 9:20 Looks good. Let's review the YAML file and eyeball all the relevant models. +- 10:20 Now let's do some manual testing. +- 10:41 Ok, it should not be warning us about using "thinking tokens" with Sonnet 3.7. +- 10:55 Let's see if aider can spot the problem? +- 11:28 That doesn't sound like a promising solution. Let's add more of the relevant code, clear history and try again. +- 12:00 Ok, let's try aider's proposed solution. +- 12:32 And see if it worked... Nope! Still getting the unneeded warning. Undo that change! +- 12:48 Time for some manual print debugging. +- 13:00 It seems like the "accept_settings" value is not being set? +- 14:30 Aha! I have a local model settings file for Sonnet which overrides aider's built in settings. And we did not update it. Let's add "accepts_settings" there. +- 14:45 That was the problem, it wasn't a bug. +- 14:59 Ok, let's add test coverage for all this stuff. +- 15:09 And while aider writes tests, let's use "git diff" to review all the changes we've made. +- 15:34 Aider is done writing tests, let's try them. +- 15:44 One passed, one failed. Let's eyeball the passing test first. +- 16:04 And let's see if aider can fix the failing test. +- 16:14 Aider needs to see another file, which makes sense. +- 16:29 It's found the problem, but is trying to "fix" the code. We want it to fix the test. +- 16:47 Ok, tests are passing. +- 16:55 We should stop and ask the user "are you sure?", not just flash a warning if they're about to break their API calls. +- 17:59 Ok, that confirmation dialog looks good. +- 18:35 This code is a little bit repetitive. Let's do a bit of refactoring. +- 19:44 Sonnet is messing up the code editing instructions, so aider is retrying. +- 19:54 Let's clear the chat history and try again. +- 20:25 Are tests still passing after the refactor? +- 20:55 Tests passed, good. Let's tweak the warning text. +- 21:10 And now let's have aider update the docs to explain these changes. +- 22:32 Let's proofread and edit the updated docs. +- 24:25 And a "git diff" of all the docs changes to do a final check. +- 24:56 Let's have aider update the project's HISTORY file. +- 25:35 We can refine the HISTORY entries a bit. +- 26:20 All done! + + + + + + diff --git a/aider/website/docs/recordings/tree-sitter-language-pack.md b/aider/website/docs/recordings/tree-sitter-language-pack.md new file mode 100644 index 000000000..f51ef0ad3 --- /dev/null +++ b/aider/website/docs/recordings/tree-sitter-language-pack.md @@ -0,0 +1,80 @@ +--- +parent: Screen recordings +nav_order: 0 +layout: minimal +highlight_image: /assets/recordings.jpg +description: Watch how aider adds support for tons of new programming languages by integrating with tree-sitter-language-pack. Demonstrates using aider to script downloading a collection of files, and using ad-hoc bash scripts to have aider modify a collection of files. +--- + +# Add language support via tree-sitter-language-pack + + + +{% include recording.md %} + + +## Commentary + +- 0:01 We're going to add a ton of new languages to aider via tree-sitter-language-pack. +- 0:10 First, lets try and find which languages it supports. +- 1:00 Ok, there's a language definitions json file +- 1:10 Does it have the github repos for each language? +- 1:29 Ok, this is what we need. +- 1:45 We need to get all the tags files from each repository for aider's repo-map. Let's have aider write a script to fetch them all. +- 2:05 We'll show aider the language definitions json file. +- 3:37 Looks like it can't find most of the tags.scm files. +- 4:19 Maybe we should have it try other branches besides master? +- 5:02 Ok, it seems to be downloading them now. +- 5:55 Let's make it so we can re-run the script and only download files we haven't fetched yet. +- 6:12 I see lots of tags files, so it's working. +- 6:30 Ok, restart to run with latest code. This will take awhile to fetch them all. +- 9:02 The Grep-AST module needs to know about all the new languages. +- 9:45 Let's have aider add them all, and register each using their commonly used file extensions. +- 10:15 Some of the languages need to be recognized by their base name, not by their extension. +- 11:15 Let's sanity check if Grep-AST can handle PowerShell, one of the new languages. +- 12:00 Looks like it's parsing PowerShell fine. +- 13:00 Ok, let's download all the tags files into the right spot in the aider repo. +- 14:00 This will take a minute... +- 16:07 Delete some no-op or empty tags files. +- 16:16 Let's commit all the unmodified tags files. +- 16:33 We need to update each tag file, so that aider can identify names of functions, classes, etc in all these languages. +- 17:01 Let's use a bash loop to script aider to modify each tags file. +- 17:12 I'm giving aider a read-only example of an already modified tags file, as an example to follow. +- 19:04 Looks like it correctly updated the first couple of tags files. +- 19:28 Let's grep to watch aider's progress working through the list of files. +- 20:20 It's working on the Dart language now... +- 20:50 E-lisp is up next... +- 21:30 This is going to take a little while... +- 24:39 Let's add a README file with attribution for these tags files. +- 26:55 Ok, all the files are updated with tags for definitions and references to named code objects. +- 27:10 Let's add test coverage to be sure these languages work with the repo-map. +- 27:19 Each language needs a "fixture" with some sample code to parse during the test. Let's show aider the layout of the fixtures directory. +- 27:50 We can use a bash loop to ask aider to add test coverage for each new tags file. +- 28:12 We'll pass the fixtures directory listing to aider. +- 28:52 Just need to fix the bash to correctly iterate through the list of tags files. +- 29:27 I forgot to ask aider to actually generate a sample code fixture for each language. +- 30:25 Lets run the repo-map tests to see if the first new test works. +- 30:37 Tests for the Arduino language failed, with an empty repo-map? That's not good. +- 31:52 Can aider figure out what's wrong? +- 32:27 Well, aider made the test pass by basically skipping Arduino. +- 32:36 Let me see if I can use Grep-AST on the new Arduino fixture code. +- 32:42 Oh! I'm not using the updated Grep-AST that knows about all the new languages. +- 32:54 Ok, now we're parsing Arduino code properly. Undo aider's bogus test fix. +- 33:05 Ok, arduino passes now but there seems to be a regression with tsx? +- 33:20 Can aider figure out why? +- 34:10 Let's check the parsers map. +- 35:00 Well, that's all for this recording. The tsx problem was due to a bad mapping from ".tsx" to "typescript" in the map that aider generated earlier. + + + + + + + + + + + diff --git a/aider/website/docs/repomap.md b/aider/website/docs/repomap.md index 4174860f9..900c31f1a 100644 --- a/aider/website/docs/repomap.md +++ b/aider/website/docs/repomap.md @@ -87,6 +87,8 @@ Aider optimizes the repo map by selecting the most important parts of the codebase which will fit into the active token budget. +The optimization identifies and maps the portions of the code base +which are most relevant to the current state of the chat. The token budget is influenced by the `--map-tokens` switch, which defaults to 1k tokens. diff --git a/aider/website/docs/usage/commands.md b/aider/website/docs/usage/commands.md index b73d82ac8..9a0caca19 100644 --- a/aider/website/docs/usage/commands.md +++ b/aider/website/docs/usage/commands.md @@ -28,11 +28,14 @@ cog.out(get_help_md()) | **/clear** | Clear the chat history | | **/code** | Ask for changes to your code. If no prompt provided, switches to code mode. | | **/commit** | Commit edits to the repo made outside the chat (commit message optional) | +| **/context** | Enter context mode to see surrounding code context. If no prompt provided, switches to context mode. | | **/copy** | Copy the last assistant message to the clipboard | | **/copy-context** | Copy the current chat context as markdown, suitable to paste into a web UI | | **/diff** | Display the diff of changes since the last message | | **/drop** | Remove files from the chat session to free up context space | +| **/edit** | Alias for /editor: Open an editor to write a prompt | | **/editor** | Open an editor to write a prompt | +| **/editor-model** | Switch the Editor Model to a new LLM | | **/exit** | Exit the application | | **/git** | Run a git command (output excluded from chat) | | **/help** | Ask questions about aider | @@ -41,21 +44,24 @@ cog.out(get_help_md()) | **/ls** | List all known files and indicate which are included in the chat session | | **/map** | Print out the current repository map | | **/map-refresh** | Force a refresh of the repository map | -| **/model** | Switch to a new LLM | +| **/model** | Switch the Main Model to a new LLM | | **/models** | Search the list of available models | | **/multiline-mode** | Toggle multiline mode (swaps behavior of Enter and Meta+Enter) | | **/paste** | Paste image/text from the clipboard into the chat. Optionally provide a name for the image. | | **/quit** | Exit the application | | **/read-only** | Add files to the chat that are for reference only, or turn added files to read-only | +| **/reasoning-effort** | Set the reasoning effort level (values: number or low/medium/high depending on model) | | **/report** | Report a problem by opening a GitHub Issue | | **/reset** | Drop all files and clear the chat history | | **/run** | Run a shell command and optionally add the output to the chat (alias: !) | | **/save** | Save commands to a file that can reconstruct the current chat session's files | | **/settings** | Print out the current settings | | **/test** | Run a shell command and add the output to the chat on non-zero exit code | +| **/think-tokens** | Set the thinking token budget (supports formats like 8096, 8k, 10.5k, 0.5M) | | **/tokens** | Report on the number of tokens used by the current chat context | | **/undo** | Undo the last git commit if it was done by aider | | **/voice** | Record and transcribe voice input | +| **/weak-model** | Switch the Weak Model to a new LLM | | **/web** | Scrape a webpage, convert to markdown and send in a message | @@ -93,6 +99,8 @@ The interactive prompt is built with [prompt-toolkit](https://github.com/prompt- - `Ctrl-N` : Move down to the next history entry. - `Ctrl-P` : Move up to the previous history entry. - `Ctrl-R` : Reverse search in command history. +- `Ctrl-X Ctrl-E` : Open the current input in an external editor +- `Ctrl-Y` : Paste (yank) text that was previously cut. ### Vi diff --git a/aider/website/docs/usage/lint-test.md b/aider/website/docs/usage/lint-test.md index 4c18baf8e..0dfdccbae 100644 --- a/aider/website/docs/usage/lint-test.md +++ b/aider/website/docs/usage/lint-test.md @@ -29,6 +29,33 @@ This is how most linters normally operate. By default, aider will lint any files which it edits. You can disable this with the `--no-auto-lint` switch. +### Per-language linters + +To specify different linters based on the code language, use `--lint "language: cmd"`. + +### Code formatting "linters" + +Many people use code formatters as linters, to format and pretty their code. +These tools sometimes return non-zero exit codes if they make changes, which will +confuse aider into thinking there's an actual lint error that needs to be fixed. + +You can use formatters by wrapping them in a shell script like this and setting +the script as your linter. + +```bash +#!/bin/bash + +# Run it twice. +# +# First attempt may reformat/modify files, and therefore exit with non-zero status. +# +# Second attempt will not do anything and exit 0 unless there's a real problem beyond +# the code formatting that was completed. + +pre-commit run --files $* >/dev/null \ + || pre-commit run --files $* +``` + ## Testing You can run tests with `/test `. diff --git a/aider/website/docs/usage/notifications.md b/aider/website/docs/usage/notifications.md index 6f31c59ee..ee7febb72 100644 --- a/aider/website/docs/usage/notifications.md +++ b/aider/website/docs/usage/notifications.md @@ -44,6 +44,29 @@ For example, on macOS you might use: aider --notifications-command "say 'Aider is ready'" ``` +### Remote Notifications + +For remote notifications you could use [Apprise](https://github.com/caronc/apprise), +which is a cross-platform Python library for sending notifications to various services. + +We can use Apprise to send notifications to Slack + +```bash +aider --notifications-command "apprise -b 'Aider is ready' 'slack://your-slack-webhook-token'" +``` + +or Discord +```bash +aider --notifications-command "apprise -b 'Aider is ready' 'discord://your-discord-webhook-token'" +``` + +or even to your phone via Pushbullet +```bash +aider --notifications-command "apprise -b 'Aider is ready' 'pbul://your-pushbullet-access-token'" +``` + +Check more how to use and configure Apprise on their GitHub page. + ## Configuration You can add these settings to your configuration file: diff --git a/aider/website/index.html b/aider/website/index.html new file mode 100644 index 000000000..180d92e66 --- /dev/null +++ b/aider/website/index.html @@ -0,0 +1,658 @@ +--- +layout: none +--- + + + + + + Aider - AI Pair Programming in Your Terminal + + + + + + + + + + + + +
    + +
    + +
    +
    +
    +
    +

    AI pair programming in your terminal

    +

    + Aider lets you pair program with LLMs to start + a new project or build on your existing + codebase. +

    + + +
    + +
    +
    + +
    +
    +
    + + +
    +
    + +
    +
    +

    Features

    +
    + +
    + +

    + Cloud and local LLMs +

    +
    +

    Aider works best with Claude 3.7 Sonnet, DeepSeek R1 & Chat V3, OpenAI o1, o3-mini & GPT-4o, but can connect to almost any LLM, including local models.

    +
    + +
    + +

    Maps your codebase

    +
    +

    + Aider makes a map of your entire codebase, + which helps it work well in larger projects. +

    +
    + +
    + +

    100+ code languages

    +
    +

    + Aider works with most popular programming + languages: python, javascript, rust, ruby, go, cpp, + php, html, css, and dozens more. +

    +
    + +
    + +

    Git integration

    +
    +

    + Aider automatically commits changes with + sensible commit messages. + Use familiar git tools to easily + diff, manage and undo AI changes. +

    +
    + +
    + +

    In your IDE

    +
    +

    + Use aider from within your favorite IDE or editor. + Ask for changes by adding comments to + your code and aider will get to work. +

    +
    + +
    + +

    Images & web pages

    +
    +

    + Add images and web pages to the chat to + provide visual context, screenshots, reference docs, + etc. +

    +
    + +
    + +

    Voice-to-code

    +
    +

    + Speak with aider about your code! Request new features, + test cases or bug fixes using your voice and let aider + implement the changes. +

    +
    + +
    + +

    Linting & testing

    +
    +

    + Automatically lint and test your code every time aider makes changes. + Aider can fix problems detected by your linters and test suites. +

    +
    + +
    + +

    Copy/paste to web chat

    +
    +

    + Aider works best with LLM APIs, + but it can also work an LLM via its web chat interface. + Aider streamlines copy/pasting code + back and forth with a browser. +

    +
    +
    +
    +
    + +
    +
    +

    Getting Started

    +
    +
    +
    python -m pip install aider-install
    +aider-install
    +
    +# Change directory into your codebase
    +cd /to/your/project
    +
    +# DeepSeek
    +aider --model deepseek --api-key deepseek=<key>
    +
    +# Claude 3.7 Sonnet
    +aider --model sonnet --api-key anthropic=<key>
    +
    +# o3-mini
    +aider --model o3-mini --api-key openai=<key>
    +
    +
    +

    Want more details?

    + +
    +
    +
    +
    + +
    +
    +

    Kind Words From Users

    +
    + +
    +
    +
    + + + + + + + + +
    +
    +

    More Information

    +
    +
    +

    Documentation

    +

    Everything you need to get started and make the most of Aider

    + +
    +
    +

    Community & Resources

    +

    Connect with other users and find additional resources

    + +
    +
    +
    +
    + + + + + + + + + + + diff --git a/aider/website/index.md b/aider/website/index.md deleted file mode 100644 index f63179cd5..000000000 --- a/aider/website/index.md +++ /dev/null @@ -1,172 +0,0 @@ ---- -title: Home -nav_order: 1 ---- - - - - - -# Aider is AI pair programming in your terminal - -Aider lets you pair program with LLMs, -to edit code in your local git repository. -Start a new project or work with an existing code base. -Aider works best with Claude 3.7 Sonnet, DeepSeek R1 & Chat V3, OpenAI o1, o3-mini & GPT-4o. Aider can [connect to almost any LLM, including local models](https://aider.chat/docs/llms.html). - - - - -

    - -

    - - -

    - - - - - - -

    - -## Getting started - - -If you already have python 3.8-3.13 installed, you can get started quickly like this: - -```bash -python -m pip install aider-install -aider-install - -# Change directory into your code base -cd /to/your/project - -# Work with DeepSeek via DeepSeek's API -aider --model deepseek --api-key deepseek=your-key-goes-here - -# Work with Claude 3.7 Sonnet via Anthropic's API -aider --model sonnet --api-key anthropic=your-key-goes-here - -# Work with GPT-4o via OpenAI's API -aider --model gpt-4o --api-key openai=your-key-goes-here - -# Work with Sonnet via OpenRouter's API -aider --model openrouter/anthropic/claude-3.7-sonnet --api-key openrouter=your-key-goes-here - -# Work with DeepSeek via OpenRouter's API -aider --model openrouter/deepseek/deepseek-chat --api-key openrouter=your-key-goes-here -``` - - -See the -[installation instructions](https://aider.chat/docs/install.html) -and -[usage documentation](https://aider.chat/docs/usage.html) -for more details. - -## Features - -- Run aider with the files you want to edit: `aider ...` -- Ask for changes: - - Add new features or test cases. - - Describe a bug. - - Paste in an error message or GitHub issue URL. - - Refactor code. - - Update docs. -- Aider will edit your files to complete your request. -- Aider [automatically git commits](https://aider.chat/docs/git.html) changes with a sensible commit message. -- [Use aider inside your favorite editor or IDE](https://aider.chat/docs/usage/watch.html). -- Aider works with [most popular languages](https://aider.chat/docs/languages.html): python, javascript, typescript, php, html, css, and more... -- Aider can edit multiple files at once for complex requests. -- Aider uses a [map of your entire git repo](https://aider.chat/docs/repomap.html), which helps it work well in larger codebases. -- Edit files in your editor or IDE while chatting with aider, -and it will always use the latest version. -Pair program with AI. -- [Add images to the chat](https://aider.chat/docs/usage/images-urls.html) (GPT-4o, Claude 3.5 Sonnet, etc). -- [Add URLs to the chat](https://aider.chat/docs/usage/images-urls.html) and aider will read their content. -- [Code with your voice](https://aider.chat/docs/usage/voice.html). -- Aider works best with Claude 3.7 Sonnet, DeepSeek V3, o1 & GPT-4o and can [connect to almost any LLM](https://aider.chat/docs/llms.html). - - -## Top tier performance - -[Aider has one of the top scores on SWE Bench](https://aider.chat/2024/06/02/main-swe-bench.html). -SWE Bench is a challenging software engineering benchmark where aider -solved *real* GitHub issues from popular open source -projects like django, scikitlearn, matplotlib, etc. - -## More info - -- [Documentation](https://aider.chat/) -- [Installation](https://aider.chat/docs/install.html) -- [Usage](https://aider.chat/docs/usage.html) -- [Tutorial videos](https://aider.chat/docs/usage/tutorials.html) -- [Connecting to LLMs](https://aider.chat/docs/llms.html) -- [Configuration](https://aider.chat/docs/config.html) -- [Troubleshooting](https://aider.chat/docs/troubleshooting.html) -- [LLM Leaderboards](https://aider.chat/docs/leaderboards/) -- [GitHub](https://github.com/Aider-AI/aider) -- [Discord](https://discord.gg/Tv2uQnR88V) -- [Blog](https://aider.chat/blog/) - - -## Kind words from users - -- *The best free open source AI coding assistant.* -- [IndyDevDan](https://youtu.be/YALpX8oOn78) -- *The best AI coding assistant so far.* -- [Matthew Berman](https://www.youtube.com/watch?v=df8afeb1FY8) -- *Aider ... has easily quadrupled my coding productivity.* -- [SOLAR_FIELDS](https://news.ycombinator.com/item?id=36212100) -- *It's a cool workflow... Aider's ergonomics are perfect for me.* -- [qup](https://news.ycombinator.com/item?id=38185326) -- *It's really like having your senior developer live right in your Git repo - truly amazing!* -- [rappster](https://github.com/Aider-AI/aider/issues/124) -- *What an amazing tool. It's incredible.* -- [valyagolev](https://github.com/Aider-AI/aider/issues/6#issue-1722897858) -- *Aider is such an astounding thing!* -- [cgrothaus](https://github.com/Aider-AI/aider/issues/82#issuecomment-1631876700) -- *It was WAY faster than I would be getting off the ground and making the first few working versions.* -- [Daniel Feldman](https://twitter.com/d_feldman/status/1662295077387923456) -- *THANK YOU for Aider! It really feels like a glimpse into the future of coding.* -- [derwiki](https://news.ycombinator.com/item?id=38205643) -- *It's just amazing. It is freeing me to do things I felt were out my comfort zone before.* -- [Dougie](https://discord.com/channels/1131200896827654144/1174002618058678323/1174084556257775656) -- *This project is stellar.* -- [funkytaco](https://github.com/Aider-AI/aider/issues/112#issuecomment-1637429008) -- *Amazing project, definitely the best AI coding assistant I've used.* -- [joshuavial](https://github.com/Aider-AI/aider/issues/84) -- *I absolutely love using Aider ... It makes software development feel so much lighter as an experience.* -- [principalideal0](https://discord.com/channels/1131200896827654144/1133421607499595858/1229689636012691468) -- *I have been recovering from multiple shoulder surgeries ... and have used aider extensively. It has allowed me to continue productivity.* -- [codeninja](https://www.reddit.com/r/OpenAI/s/nmNwkHy1zG) -- *I am an aider addict. I'm getting so much more work done, but in less time.* -- [dandandan](https://discord.com/channels/1131200896827654144/1131200896827654149/1135913253483069470) -- *After wasting $100 on tokens trying to find something better, I'm back to Aider. It blows everything else out of the water hands down, there's no competition whatsoever.* -- [SystemSculpt](https://discord.com/channels/1131200896827654144/1131200896827654149/1178736602797846548) -- *Aider is amazing, coupled with Sonnet 3.5 it’s quite mind blowing.* -- [Josh Dingus](https://discord.com/channels/1131200896827654144/1133060684540813372/1262374225298198548) -- *Hands down, this is the best AI coding assistant tool so far.* -- [IndyDevDan](https://www.youtube.com/watch?v=MPYFPvxfGZs) -- *[Aider] changed my daily coding workflows. It's mind-blowing how a single Python application can change your life.* -- [maledorak](https://discord.com/channels/1131200896827654144/1131200896827654149/1258453375620747264) -- *Best agent for actual dev work in existing codebases.* -- [Nick Dobos](https://twitter.com/NickADobos/status/1690408967963652097?s=20) - diff --git a/benchmark/README.md b/benchmark/README.md index b9e1b1e43..3f3f2db85 100644 --- a/benchmark/README.md +++ b/benchmark/README.md @@ -43,7 +43,7 @@ These steps only need to be done once. ``` # Clone the aider repo -git clone git@github.com:Aider-AI/aider.git +git clone https://github.com/Aider-AI/aider.git # Create the scratch dir to hold benchmarking results inside the main aider dir: cd aider diff --git a/requirements.txt b/requirements.txt index e6fb6d59e..4a7fcb19d 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,10 +1,10 @@ # This file was autogenerated by uv via the following command: # uv pip compile --no-strip-extras --constraint=requirements/common-constraints.txt --output-file=tmp.requirements.txt requirements/requirements.in -aiohappyeyeballs==2.5.0 +aiohappyeyeballs==2.6.1 # via # -c requirements/common-constraints.txt # aiohttp -aiohttp==3.11.13 +aiohttp==3.11.14 # via # -c requirements/common-constraints.txt # litellm @@ -16,13 +16,13 @@ annotated-types==0.7.0 # via # -c requirements/common-constraints.txt # pydantic -anyio==4.8.0 +anyio==4.9.0 # via # -c requirements/common-constraints.txt # httpx # openai # watchfiles -attrs==25.1.0 +attrs==25.3.0 # via # -c requirements/common-constraints.txt # aiohttp @@ -73,7 +73,7 @@ distro==1.9.0 # -c requirements/common-constraints.txt # openai # posthog -filelock==3.17.0 +filelock==3.18.0 # via # -c requirements/common-constraints.txt # huggingface-hub @@ -86,7 +86,7 @@ frozenlist==1.5.0 # -c requirements/common-constraints.txt # aiohttp # aiosignal -fsspec==2025.2.0 +fsspec==2025.3.0 # via # -c requirements/common-constraints.txt # huggingface-hub @@ -98,7 +98,7 @@ gitpython==3.1.44 # via # -c requirements/common-constraints.txt # -r requirements/requirements.in -grep-ast==0.7.2 +grep-ast==0.8.1 # via # -c requirements/common-constraints.txt # -r requirements/requirements.in @@ -115,7 +115,7 @@ httpx==0.28.1 # -c requirements/common-constraints.txt # litellm # openai -huggingface-hub==0.29.2 +huggingface-hub==0.29.3 # via # -c requirements/common-constraints.txt # tokenizers @@ -139,7 +139,7 @@ jinja2==3.1.6 # via # -c requirements/common-constraints.txt # litellm -jiter==0.8.2 +jiter==0.9.0 # via # -c requirements/common-constraints.txt # openai @@ -156,7 +156,7 @@ jsonschema-specifications==2024.10.1 # via # -c requirements/common-constraints.txt # jsonschema -litellm==1.63.2 +litellm==1.65.0 # via # -c requirements/common-constraints.txt # -r requirements/requirements.in @@ -184,7 +184,7 @@ monotonic==1.6 # via # -c requirements/common-constraints.txt # posthog -multidict==6.1.0 +multidict==6.2.0 # via # -c requirements/common-constraints.txt # aiohttp @@ -198,7 +198,7 @@ numpy==1.26.4 # -c requirements/common-constraints.txt # scipy # soundfile -openai==1.65.4 +openai==1.69.0 # via # -c requirements/common-constraints.txt # litellm @@ -224,7 +224,7 @@ pip==25.0.1 # via # -c requirements/common-constraints.txt # -r requirements/requirements.in -posthog==3.19.0 +posthog==3.23.0 # via # -c requirements/common-constraints.txt # -r requirements/requirements.in @@ -232,7 +232,7 @@ prompt-toolkit==3.0.50 # via # -c requirements/common-constraints.txt # -r requirements/requirements.in -propcache==0.3.0 +propcache==0.3.1 # via # -c requirements/common-constraints.txt # aiohttp @@ -253,12 +253,12 @@ pycparser==2.22 # via # -c requirements/common-constraints.txt # cffi -pydantic==2.10.6 +pydantic==2.11.1 # via # -c requirements/common-constraints.txt # litellm # openai -pydantic-core==2.27.2 +pydantic-core==2.33.0 # via # -c requirements/common-constraints.txt # pydantic @@ -286,7 +286,7 @@ python-dateutil==2.9.0.post0 # via # -c requirements/common-constraints.txt # posthog -python-dotenv==1.0.1 +python-dotenv==1.1.0 # via # -c requirements/common-constraints.txt # litellm @@ -315,7 +315,7 @@ rich==13.9.4 # via # -c requirements/common-constraints.txt # -r requirements/requirements.in -rpds-py==0.23.1 +rpds-py==0.24.0 # via # -c requirements/common-constraints.txt # jsonschema @@ -359,7 +359,7 @@ tiktoken==0.9.0 # via # -c requirements/common-constraints.txt # litellm -tokenizers==0.21.0 +tokenizers==0.21.1 # via # -c requirements/common-constraints.txt # litellm @@ -379,7 +379,7 @@ tree-sitter-embedded-template==0.23.2 # via # -c requirements/common-constraints.txt # tree-sitter-language-pack -tree-sitter-language-pack==0.6.0 +tree-sitter-language-pack==0.6.1 # via # -c requirements/common-constraints.txt # grep-ast @@ -387,7 +387,7 @@ tree-sitter-yaml==0.7.0 # via # -c requirements/common-constraints.txt # tree-sitter-language-pack -typing-extensions==4.12.2 +typing-extensions==4.13.0 # via # -c requirements/common-constraints.txt # anyio @@ -397,6 +397,11 @@ typing-extensions==4.12.2 # pydantic # pydantic-core # referencing + # typing-inspection +typing-inspection==0.4.0 + # via + # -c requirements/common-constraints.txt + # pydantic urllib3==2.3.0 # via # -c requirements/common-constraints.txt diff --git a/requirements/common-constraints.txt b/requirements/common-constraints.txt index d28e7dce1..44227b723 100644 --- a/requirements/common-constraints.txt +++ b/requirements/common-constraints.txt @@ -1,8 +1,8 @@ # This file was autogenerated by uv via the following command: # uv pip compile --no-strip-extras --output-file=requirements/common-constraints.txt requirements/requirements.in requirements/requirements-browser.in requirements/requirements-dev.in requirements/requirements-help.in requirements/requirements-playwright.in -aiohappyeyeballs==2.5.0 +aiohappyeyeballs==2.6.1 # via aiohttp -aiohttp==3.11.13 +aiohttp==3.11.14 # via # huggingface-hub # litellm @@ -13,12 +13,12 @@ altair==5.5.0 # via streamlit annotated-types==0.7.0 # via pydantic -anyio==4.8.0 +anyio==4.9.0 # via # httpx # openai # watchfiles -attrs==25.1.0 +attrs==25.3.0 # via # aiohttp # jsonschema @@ -27,6 +27,8 @@ backoff==2.2.1 # via # -r requirements/requirements.in # posthog +banks==2.0.0 + # via llama-index-core beautifulsoup4==4.13.3 # via -r requirements/requirements.in blinker==1.9.0 @@ -59,6 +61,8 @@ codespell==2.4.1 # via -r requirements/requirements-dev.in cogapp==3.4.1 # via -r requirements/requirements-dev.in +colorama==0.4.6 + # via griffe configargparse==1.7 # via -r requirements/requirements.in contourpy==1.3.1 @@ -68,7 +72,9 @@ cycler==0.12.1 dataclasses-json==0.6.7 # via llama-index-core deprecated==1.2.18 - # via llama-index-core + # via + # banks + # llama-index-core diff-match-patch==20241021 # via -r requirements/requirements.in dill==0.3.9 @@ -85,7 +91,7 @@ distro==1.9.0 # via # openai # posthog -filelock==3.17.0 +filelock==3.18.0 # via # huggingface-hub # torch @@ -101,7 +107,7 @@ frozenlist==1.5.0 # via # aiohttp # aiosignal -fsspec==2025.2.0 +fsspec==2025.3.0 # via # huggingface-hub # llama-index-core @@ -116,8 +122,10 @@ greenlet==3.1.1 # via # playwright # sqlalchemy -grep-ast==0.7.2 +grep-ast==0.8.1 # via -r requirements/requirements.in +griffe==1.7.0 + # via banks h11==0.14.0 # via httpcore httpcore==1.0.7 @@ -127,13 +135,13 @@ httpx==0.28.1 # litellm # llama-index-core # openai -huggingface-hub[inference]==0.29.2 +huggingface-hub[inference]==0.29.3 # via # llama-index-embeddings-huggingface # sentence-transformers # tokenizers # transformers -identify==2.6.8 +identify==2.6.9 # via pre-commit idna==3.10 # via @@ -149,15 +157,16 @@ importlib-metadata==7.2.1 # litellm importlib-resources==6.5.2 # via -r requirements/requirements.in -iniconfig==2.0.0 +iniconfig==2.1.0 # via pytest jinja2==3.1.6 # via # altair + # banks # litellm # pydeck # torch -jiter==0.8.2 +jiter==0.9.0 # via openai joblib==1.4.2 # via @@ -174,9 +183,9 @@ jsonschema-specifications==2024.10.1 # via jsonschema kiwisolver==1.4.8 # via matplotlib -litellm==1.63.2 +litellm==1.65.0 # via -r requirements/requirements.in -llama-index-core==0.12.22 +llama-index-core==0.12.27 # via # -r requirements/requirements-help.in # llama-index-embeddings-huggingface @@ -202,7 +211,7 @@ monotonic==1.6 # via posthog mpmath==1.3.0 # via sympy -multidict==6.1.0 +multidict==6.2.0 # via # aiohttp # yarl @@ -210,7 +219,7 @@ multiprocess==0.70.17 # via pathos mypy-extensions==1.0.0 # via typing-inspect -narwhals==1.29.1 +narwhals==1.32.0 # via altair nest-asyncio==1.6.0 # via llama-index-core @@ -236,7 +245,7 @@ numpy==1.26.4 # soundfile # streamlit # transformers -openai==1.65.4 +openai==1.69.0 # via litellm packaging==24.2 # via @@ -274,27 +283,27 @@ pip==25.0.1 # pip-tools pip-tools==7.4.1 # via -r requirements/requirements-dev.in -platformdirs==4.3.6 +platformdirs==4.3.7 # via virtualenv -playwright==1.50.0 +playwright==1.51.0 # via -r requirements/requirements-playwright.in pluggy==1.5.0 # via pytest -posthog==3.19.0 +posthog==3.23.0 # via -r requirements/requirements.in pox==0.3.5 # via pathos ppft==1.7.6.9 # via pathos -pre-commit==4.1.0 +pre-commit==4.2.0 # via -r requirements/requirements-dev.in prompt-toolkit==3.0.50 # via -r requirements/requirements.in -propcache==0.3.0 +propcache==0.3.1 # via # aiohttp # yarl -protobuf==5.29.3 +protobuf==5.29.4 # via streamlit psutil==7.0.0 # via -r requirements/requirements.in @@ -306,12 +315,13 @@ pycodestyle==2.12.1 # via flake8 pycparser==2.22 # via cffi -pydantic==2.10.6 +pydantic==2.11.1 # via + # banks # litellm # llama-index-core # openai -pydantic-core==2.27.2 +pydantic-core==2.33.0 # via pydantic pydeck==0.9.1 # via streamlit @@ -325,7 +335,7 @@ pygments==2.19.1 # via rich pypandoc==1.15 # via -r requirements/requirements.in -pyparsing==3.2.1 +pyparsing==3.2.3 # via matplotlib pyperclip==1.9.0 # via -r requirements/requirements.in @@ -344,9 +354,9 @@ python-dateutil==2.9.0.post0 # matplotlib # pandas # posthog -python-dotenv==1.0.1 +python-dotenv==1.1.0 # via litellm -pytz==2025.1 +pytz==2025.2 # via pandas pyyaml==6.0.2 # via @@ -377,7 +387,7 @@ rich==13.9.4 # via # -r requirements/requirements.in # typer -rpds-py==0.23.1 +rpds-py==0.24.0 # via # jsonschema # referencing @@ -392,9 +402,9 @@ scipy==1.13.1 # sentence-transformers semver==3.0.4 # via -r requirements/requirements-dev.in -sentence-transformers==3.4.1 +sentence-transformers==4.0.1 # via llama-index-embeddings-huggingface -setuptools==75.8.2 +setuptools==78.1.0 # via pip-tools shellingham==1.5.4 # via typer @@ -417,9 +427,9 @@ soundfile==0.13.1 # via -r requirements/requirements.in soupsieve==2.6 # via beautifulsoup4 -sqlalchemy[asyncio]==2.0.38 +sqlalchemy[asyncio]==2.0.40 # via llama-index-core -streamlit==1.43.0 +streamlit==1.44.0 # via -r requirements/requirements-browser.in sympy==1.13.3 # via torch @@ -427,13 +437,13 @@ tenacity==9.0.0 # via # llama-index-core # streamlit -threadpoolctl==3.5.0 +threadpoolctl==3.6.0 # via scikit-learn tiktoken==0.9.0 # via # litellm # llama-index-core -tokenizers==0.21.0 +tokenizers==0.21.1 # via # litellm # transformers @@ -453,7 +463,7 @@ tqdm==4.67.1 # openai # sentence-transformers # transformers -transformers==4.49.0 +transformers==4.50.3 # via sentence-transformers tree-sitter==0.24.0 # via tree-sitter-language-pack @@ -461,13 +471,13 @@ tree-sitter-c-sharp==0.23.1 # via tree-sitter-language-pack tree-sitter-embedded-template==0.23.2 # via tree-sitter-language-pack -tree-sitter-language-pack==0.6.0 +tree-sitter-language-pack==0.6.1 # via grep-ast tree-sitter-yaml==0.7.0 # via tree-sitter-language-pack typer==0.15.2 # via -r requirements/requirements-dev.in -typing-extensions==4.12.2 +typing-extensions==4.13.0 # via # altair # anyio @@ -479,22 +489,26 @@ typing-extensions==4.12.2 # pydantic-core # pyee # referencing + # sentence-transformers # sqlalchemy # streamlit # torch # typer # typing-inspect + # typing-inspection typing-inspect==0.9.0 # via # dataclasses-json # llama-index-core -tzdata==2025.1 +typing-inspection==0.4.0 + # via pydantic +tzdata==2025.2 # via pandas urllib3==2.3.0 # via # mixpanel # requests -uv==0.6.5 +uv==0.6.10 # via -r requirements/requirements-dev.in virtualenv==20.29.3 # via pre-commit diff --git a/requirements/requirements-browser.txt b/requirements/requirements-browser.txt index 2608a66ed..cd0310674 100644 --- a/requirements/requirements-browser.txt +++ b/requirements/requirements-browser.txt @@ -4,7 +4,7 @@ altair==5.5.0 # via # -c requirements/common-constraints.txt # streamlit -attrs==25.1.0 +attrs==25.3.0 # via # -c requirements/common-constraints.txt # jsonschema @@ -58,7 +58,7 @@ markupsafe==3.0.2 # via # -c requirements/common-constraints.txt # jinja2 -narwhals==1.29.1 +narwhals==1.32.0 # via # -c requirements/common-constraints.txt # altair @@ -81,7 +81,7 @@ pillow==11.1.0 # via # -c requirements/common-constraints.txt # streamlit -protobuf==5.29.3 +protobuf==5.29.4 # via # -c requirements/common-constraints.txt # streamlit @@ -97,7 +97,7 @@ python-dateutil==2.9.0.post0 # via # -c requirements/common-constraints.txt # pandas -pytz==2025.1 +pytz==2025.2 # via # -c requirements/common-constraints.txt # pandas @@ -110,7 +110,7 @@ requests==2.32.3 # via # -c requirements/common-constraints.txt # streamlit -rpds-py==0.23.1 +rpds-py==0.24.0 # via # -c requirements/common-constraints.txt # jsonschema @@ -123,7 +123,7 @@ smmap==5.0.2 # via # -c requirements/common-constraints.txt # gitdb -streamlit==1.43.0 +streamlit==1.44.0 # via # -c requirements/common-constraints.txt # -r requirements/requirements-browser.in @@ -139,13 +139,13 @@ tornado==6.4.2 # via # -c requirements/common-constraints.txt # streamlit -typing-extensions==4.12.2 +typing-extensions==4.13.0 # via # -c requirements/common-constraints.txt # altair # referencing # streamlit -tzdata==2025.1 +tzdata==2025.2 # via # -c requirements/common-constraints.txt # pandas diff --git a/requirements/requirements-dev.txt b/requirements/requirements-dev.txt index d1e095b66..6a551742c 100644 --- a/requirements/requirements-dev.txt +++ b/requirements/requirements-dev.txt @@ -38,7 +38,7 @@ distlib==0.3.9 # via # -c requirements/common-constraints.txt # virtualenv -filelock==3.17.0 +filelock==3.18.0 # via # -c requirements/common-constraints.txt # virtualenv @@ -46,7 +46,7 @@ fonttools==4.56.0 # via # -c requirements/common-constraints.txt # matplotlib -identify==2.6.8 +identify==2.6.9 # via # -c requirements/common-constraints.txt # pre-commit @@ -54,7 +54,7 @@ imgcat==0.6.0 # via # -c requirements/common-constraints.txt # -r requirements/requirements-dev.in -iniconfig==2.0.0 +iniconfig==2.1.0 # via # -c requirements/common-constraints.txt # pytest @@ -118,7 +118,7 @@ pip-tools==7.4.1 # via # -c requirements/common-constraints.txt # -r requirements/requirements-dev.in -platformdirs==4.3.6 +platformdirs==4.3.7 # via # -c requirements/common-constraints.txt # virtualenv @@ -134,7 +134,7 @@ ppft==1.7.6.9 # via # -c requirements/common-constraints.txt # pathos -pre-commit==4.1.0 +pre-commit==4.2.0 # via # -c requirements/common-constraints.txt # -r requirements/requirements-dev.in @@ -142,7 +142,7 @@ pygments==2.19.1 # via # -c requirements/common-constraints.txt # rich -pyparsing==3.2.1 +pyparsing==3.2.3 # via # -c requirements/common-constraints.txt # matplotlib @@ -165,7 +165,7 @@ python-dateutil==2.9.0.post0 # -c requirements/common-constraints.txt # matplotlib # pandas -pytz==2025.1 +pytz==2025.2 # via # -c requirements/common-constraints.txt # pandas @@ -181,7 +181,7 @@ semver==3.0.4 # via # -c requirements/common-constraints.txt # -r requirements/requirements-dev.in -setuptools==75.8.2 +setuptools==78.1.0 # via # -c requirements/common-constraints.txt # pip-tools @@ -197,15 +197,15 @@ typer==0.15.2 # via # -c requirements/common-constraints.txt # -r requirements/requirements-dev.in -typing-extensions==4.12.2 +typing-extensions==4.13.0 # via # -c requirements/common-constraints.txt # typer -tzdata==2025.1 +tzdata==2025.2 # via # -c requirements/common-constraints.txt # pandas -uv==0.6.5 +uv==0.6.10 # via # -c requirements/common-constraints.txt # -r requirements/requirements-dev.in diff --git a/requirements/requirements-help.txt b/requirements/requirements-help.txt index 5879f0c23..6db5da775 100644 --- a/requirements/requirements-help.txt +++ b/requirements/requirements-help.txt @@ -1,10 +1,10 @@ # This file was autogenerated by uv via the following command: # uv pip compile --no-strip-extras --constraint=requirements/common-constraints.txt --output-file=requirements/requirements-help.txt requirements/requirements-help.in -aiohappyeyeballs==2.5.0 +aiohappyeyeballs==2.6.1 # via # -c requirements/common-constraints.txt # aiohttp -aiohttp==3.11.13 +aiohttp==3.11.14 # via # -c requirements/common-constraints.txt # huggingface-hub @@ -17,14 +17,18 @@ annotated-types==0.7.0 # via # -c requirements/common-constraints.txt # pydantic -anyio==4.8.0 +anyio==4.9.0 # via # -c requirements/common-constraints.txt # httpx -attrs==25.1.0 +attrs==25.3.0 # via # -c requirements/common-constraints.txt # aiohttp +banks==2.0.0 + # via + # -c requirements/common-constraints.txt + # llama-index-core certifi==2025.1.31 # via # -c requirements/common-constraints.txt @@ -39,6 +43,10 @@ click==8.1.8 # via # -c requirements/common-constraints.txt # nltk +colorama==0.4.6 + # via + # -c requirements/common-constraints.txt + # griffe dataclasses-json==0.6.7 # via # -c requirements/common-constraints.txt @@ -46,12 +54,13 @@ dataclasses-json==0.6.7 deprecated==1.2.18 # via # -c requirements/common-constraints.txt + # banks # llama-index-core dirtyjson==1.0.8 # via # -c requirements/common-constraints.txt # llama-index-core -filelock==3.17.0 +filelock==3.18.0 # via # -c requirements/common-constraints.txt # huggingface-hub @@ -66,7 +75,7 @@ frozenlist==1.5.0 # -c requirements/common-constraints.txt # aiohttp # aiosignal -fsspec==2025.2.0 +fsspec==2025.3.0 # via # -c requirements/common-constraints.txt # huggingface-hub @@ -76,6 +85,10 @@ greenlet==3.1.1 # via # -c requirements/common-constraints.txt # sqlalchemy +griffe==1.7.0 + # via + # -c requirements/common-constraints.txt + # banks h11==0.14.0 # via # -c requirements/common-constraints.txt @@ -88,7 +101,7 @@ httpx==0.28.1 # via # -c requirements/common-constraints.txt # llama-index-core -huggingface-hub[inference]==0.29.2 +huggingface-hub[inference]==0.29.3 # via # -c requirements/common-constraints.txt # llama-index-embeddings-huggingface @@ -105,13 +118,14 @@ idna==3.10 jinja2==3.1.6 # via # -c requirements/common-constraints.txt + # banks # torch joblib==1.4.2 # via # -c requirements/common-constraints.txt # nltk # scikit-learn -llama-index-core==0.12.22 +llama-index-core==0.12.27 # via # -c requirements/common-constraints.txt # -r requirements/requirements-help.in @@ -132,7 +146,7 @@ mpmath==1.3.0 # via # -c requirements/common-constraints.txt # sympy -multidict==6.1.0 +multidict==6.2.0 # via # -c requirements/common-constraints.txt # aiohttp @@ -173,16 +187,17 @@ pillow==11.1.0 # -c requirements/common-constraints.txt # llama-index-core # sentence-transformers -propcache==0.3.0 +propcache==0.3.1 # via # -c requirements/common-constraints.txt # aiohttp # yarl -pydantic==2.10.6 +pydantic==2.11.1 # via # -c requirements/common-constraints.txt + # banks # llama-index-core -pydantic-core==2.27.2 +pydantic-core==2.33.0 # via # -c requirements/common-constraints.txt # pydantic @@ -218,7 +233,7 @@ scipy==1.13.1 # -c requirements/common-constraints.txt # scikit-learn # sentence-transformers -sentence-transformers==3.4.1 +sentence-transformers==4.0.1 # via # -c requirements/common-constraints.txt # llama-index-embeddings-huggingface @@ -226,7 +241,7 @@ sniffio==1.3.1 # via # -c requirements/common-constraints.txt # anyio -sqlalchemy[asyncio]==2.0.38 +sqlalchemy[asyncio]==2.0.40 # via # -c requirements/common-constraints.txt # llama-index-core @@ -238,7 +253,7 @@ tenacity==9.0.0 # via # -c requirements/common-constraints.txt # llama-index-core -threadpoolctl==3.5.0 +threadpoolctl==3.6.0 # via # -c requirements/common-constraints.txt # scikit-learn @@ -246,7 +261,7 @@ tiktoken==0.9.0 # via # -c requirements/common-constraints.txt # llama-index-core -tokenizers==0.21.0 +tokenizers==0.21.1 # via # -c requirements/common-constraints.txt # transformers @@ -263,11 +278,11 @@ tqdm==4.67.1 # nltk # sentence-transformers # transformers -transformers==4.49.0 +transformers==4.50.3 # via # -c requirements/common-constraints.txt # sentence-transformers -typing-extensions==4.12.2 +typing-extensions==4.13.0 # via # -c requirements/common-constraints.txt # anyio @@ -275,14 +290,20 @@ typing-extensions==4.12.2 # llama-index-core # pydantic # pydantic-core + # sentence-transformers # sqlalchemy # torch # typing-inspect + # typing-inspection typing-inspect==0.9.0 # via # -c requirements/common-constraints.txt # dataclasses-json # llama-index-core +typing-inspection==0.4.0 + # via + # -c requirements/common-constraints.txt + # pydantic urllib3==2.3.0 # via # -c requirements/common-constraints.txt diff --git a/requirements/requirements-playwright.txt b/requirements/requirements-playwright.txt index 6a2405f65..c33177850 100644 --- a/requirements/requirements-playwright.txt +++ b/requirements/requirements-playwright.txt @@ -4,7 +4,7 @@ greenlet==3.1.1 # via # -c requirements/common-constraints.txt # playwright -playwright==1.50.0 +playwright==1.51.0 # via # -c requirements/common-constraints.txt # -r requirements/requirements-playwright.in @@ -12,7 +12,7 @@ pyee==12.1.1 # via # -c requirements/common-constraints.txt # playwright -typing-extensions==4.12.2 +typing-extensions==4.13.0 # via # -c requirements/common-constraints.txt # pyee diff --git a/scripts/30k-image.py b/scripts/30k-image.py new file mode 100644 index 000000000..9a62206e4 --- /dev/null +++ b/scripts/30k-image.py @@ -0,0 +1,235 @@ +#!/usr/bin/env python +""" +Generate a celebratory SVG image for Aider reaching 30,000 GitHub stars. +This creates a shareable social media graphic with confetti animation. +""" + +import argparse +import base64 +import math +import os +import random +from pathlib import Path + +# Default colors for the celebration image +AIDER_GREEN = "#14b014" +AIDER_BLUE = "#4C6EF5" +DARK_COLOR = "#212529" +LIGHT_COLOR = "#F8F9FA" +GOLD_COLOR = "#f1c40f" + +# Default dimensions for social sharing +DEFAULT_WIDTH = 1200 +DEFAULT_HEIGHT = 630 + + +def embed_font(): + """Returns base64 encoded font data for the GlassTTYVT220 font.""" + # Path to the font file + font_path = ( + Path(__file__).parent.parent / "aider" / "website" / "assets" / "Glass_TTY_VT220.ttf" + ) + + # If font file doesn't exist, return empty string + if not font_path.exists(): + print(f"Warning: Font file not found at {font_path}") + return "" + + # Read and encode the font file + with open(font_path, "rb") as f: + font_data = f.read() + + # Return base64 encoded font data + return base64.b64encode(font_data).decode("utf-8") + + +def generate_confetti(count=150, width=DEFAULT_WIDTH, height=DEFAULT_HEIGHT): + """Generate SVG confetti elements for the celebration.""" + confetti = [] + colors = [AIDER_GREEN, AIDER_BLUE, GOLD_COLOR, "#e74c3c", "#9b59b6", "#3498db", "#2ecc71"] + + # Define text safe zones + # Main content safe zone (centered area) + safe_zone_x_min = width * 0.2 + safe_zone_x_max = width * 0.8 + safe_zone_y_min = height * 0.25 + safe_zone_y_max = height * 0.75 + + # Footer safe zone (for GitHub URL) + footer_safe_zone_x_min = width * 0.25 + footer_safe_zone_x_max = width * 0.75 + footer_safe_zone_y_min = height - 100 # 100px from bottom + footer_safe_zone_y_max = height # Bottom of image + + # Keep trying until we have enough confetti pieces + attempts = 0 + confetti_count = 0 + + while confetti_count < count and attempts < count * 3: + attempts += 1 + + # Generate random position + x = random.randint(0, width) + y = random.randint(0, height) + + # Skip if the position is in either of the safe zones + if ( + (safe_zone_x_min < x < safe_zone_x_max) and (safe_zone_y_min < y < safe_zone_y_max) + ) or ( + (footer_safe_zone_x_min < x < footer_safe_zone_x_max) + and (footer_safe_zone_y_min < y < footer_safe_zone_y_max) + ): + continue + + confetti_count += 1 + size = random.randint(5, 15) + color = random.choice(colors) + rotation = random.randint(0, 360) + delay = random.uniform(0, 2) + duration = random.uniform(1, 3) + + # Randomly choose between rect (square), circle, and star shapes + shape_type = random.choice(["rect", "circle", "star"]) + + if shape_type == "rect": + shape = f""" + + + """ + elif shape_type == "circle": + shape = f""" + + + """ + else: # star + # Create a simple 5-point star + points = [] + for j in range(5): + angle = j * 2 * 3.14159 / 5 + x_point = x + (size * 0.5) * math.cos(angle) + y_point = y + (size * 0.5) * math.sin(angle) + points.append(f"{x_point},{y_point}") + + # Inner points of the star + inner_angle = angle + 3.14159 / 5 + inner_x = x + (size * 0.2) * math.cos(inner_angle) + inner_y = y + (size * 0.2) * math.sin(inner_angle) + points.append(f"{inner_x},{inner_y}") + + points_str = " ".join(points) + shape = f""" + + + + """ + + confetti.append(shape) + + return "\n".join(confetti) + + +def generate_celebration_svg(output_path=None, width=DEFAULT_WIDTH, height=DEFAULT_HEIGHT): + """Generate a celebratory SVG for 30K GitHub stars.""" + + # Font embedding + font_data = embed_font() + font_face = f""" + @font-face {{ + font-family: 'GlassTTYVT220'; + src: url(data:font/truetype;charset=utf-8;base64,{font_data}) format('truetype'); + font-weight: normal; + font-style: normal; + }} + """ if font_data else "" + + # Generate confetti elements + confetti = generate_confetti(count=150, width=width, height=height) + + # Create the SVG content + svg_content = f""" + + + + + + + + + + + + + + + + + + + + + + + + + + + + {confetti} + + + + 30,000 GitHub stars! + Thank you to our amazing community! + github.com/Aider-AI/aider + + + +""" + + # Write to file if output path is specified + if output_path: + with open(output_path, "w") as f: + f.write(svg_content) + print(f"Celebration SVG saved to {output_path}") + + return svg_content + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description="Generate a celebration SVG for Aider's 30K GitHub stars" + ) + parser.add_argument( + "--output", + "-o", + type=str, + default="aider-30k-stars.svg", + help="Output file path (default: aider-30k-stars.svg)", + ) + parser.add_argument( + "--width", + "-w", + type=int, + default=DEFAULT_WIDTH, + help=f"Image width in pixels (default: {DEFAULT_WIDTH})", + ) + parser.add_argument( + "--height", + "-ht", + type=int, + default=DEFAULT_HEIGHT, + help=f"Image height in pixels (default: {DEFAULT_HEIGHT})", + ) + args = parser.parse_args() + + # Generate the SVG + generate_celebration_svg(args.output, args.width, args.height) diff --git a/scripts/blame.py b/scripts/blame.py index 6c395a293..40a561d8a 100755 --- a/scripts/blame.py +++ b/scripts/blame.py @@ -13,8 +13,10 @@ import yaml from tqdm import tqdm website_files = [ + "aider/website/index.html", "aider/website/share/index.md", "aider/website/_includes/head_custom.html", + "aider/website/_includes/home.css", "aider/website/docs/leaderboards/index.md", ] @@ -222,9 +224,10 @@ def get_counts_for_file(start_tag, end_tag, authors, fname): [ "git", "blame", - "-M", - "-C", - "-C", + "-M100", # Detect moved lines within a file with 100% similarity + "-C100", # Detect moves across files with 100% similarity + "-C", # Increase detection effort + "-C", # Increase detection effort even more "--abbrev=9", f"{start_tag}..{end_tag}", "--", @@ -233,7 +236,18 @@ def get_counts_for_file(start_tag, end_tag, authors, fname): ) else: text = run( - ["git", "blame", "-M", "-C", "-C", "--abbrev=9", f"{start_tag}..HEAD", "--", fname] + [ + "git", + "blame", + "-M100", # Detect moved lines within a file with 100% similarity + "-C100", # Detect moves across files with 100% similarity + "-C", # Increase detection effort + "-C", # Increase detection effort even more + "--abbrev=9", + f"{start_tag}..HEAD", + "--", + fname, + ] ) if not text: return None diff --git a/scripts/dl_icons.py b/scripts/dl_icons.py new file mode 100644 index 000000000..8240ca641 --- /dev/null +++ b/scripts/dl_icons.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python3 +""" +Download Material Design Icons SVGs used in the README and save to local assets. +""" + +import os +from pathlib import Path + +import requests + +# Create the directory if it doesn't exist +ICONS_DIR = Path("aider/website/assets/icons") +ICONS_DIR.mkdir(parents=True, exist_ok=True) + +# Icons used in the README.md features section +ICONS = [ + "brain", + "map-outline", + "code-tags", + "source-branch", + "monitor", + "image-multiple", + "microphone", + "check-all", + "content-copy", +] + + +def download_icon(icon_name): + """Download an SVG icon from Material Design Icons CDN.""" + url = f"https://cdn.jsdelivr.net/npm/@mdi/svg@latest/svg/{icon_name}.svg" + print(f"Downloading {url}...") + + response = requests.get(url) + if response.status_code != 200: + print(f"Failed to download {icon_name}.svg: {response.status_code}") + return False + + # Save the SVG file + output_path = ICONS_DIR / f"{icon_name}.svg" + with open(output_path, "wb") as f: + f.write(response.content) + + print(f"Saved {icon_name}.svg to {output_path}") + return True + + +def main(): + print(f"Downloading icons to {ICONS_DIR}") + + success_count = 0 + for icon in ICONS: + if download_icon(icon): + success_count += 1 + + print(f"Successfully downloaded {success_count}/{len(ICONS)} icons") + + +if __name__ == "__main__": + main() diff --git a/scripts/history_prompts.py b/scripts/history_prompts.py index 4079d9d3e..5902b9f57 100644 --- a/scripts/history_prompts.py +++ b/scripts/history_prompts.py @@ -1,11 +1,15 @@ history_prompt = """ -Update the history with changes shown in the diffs. +Update the history doc with changes shown in the diffs. Describe actual user-facing changes, not every single commit that was made implementing them. Only add new items not already listed. Do NOT edit or update existing history entries. Do NOT add duplicate entries for changes that have existing history entries. +Pay attention to see if changes are later modified or superseded. +The history doc should only reflect the *final* version of changes which have evolved within a version's commit history. +If the history doc already describes the final behavior, don't document the changes that led us there. + End each bullet with a period. If the change was made by someone other than Paul Gauthier note it at the end of the bullet point as ", by XXX." diff --git a/scripts/homepage.py b/scripts/homepage.py new file mode 100755 index 000000000..d79fe84c2 --- /dev/null +++ b/scripts/homepage.py @@ -0,0 +1,560 @@ +#!/usr/bin/env python3 + +import argparse +import json +import os +import sys +import time +from datetime import datetime + +import requests +import yaml +from dotenv import load_dotenv +from google.cloud import bigquery +from google.oauth2 import service_account + +TOKENS_PER_WEEK = "15B" + +# Badge tooltip texts +GITHUB_STARS_TOOLTIP = "Total number of GitHub stars the Aider project has received" +PYPI_DOWNLOADS_TOOLTIP = "Total number of installations via pip from PyPI" +TOKENS_WEEKLY_TOOLTIP = "Number of tokens processed weekly by Aider users" +OPENROUTER_TOOLTIP = "Aider's ranking among applications on the OpenRouter platform" +SINGULARITY_TOOLTIP = "Percentage of the new code in Aider's last release written by Aider itself" + +# Cache settings +CACHE_DIR = os.path.expanduser("~/.cache/aider-badges") +CACHE_DURATION = 24 * 60 * 60 # 24 hours in seconds + + +def ensure_cache_dir(): + """Create the cache directory if it doesn't exist""" + os.makedirs(CACHE_DIR, exist_ok=True) + + +def get_cache_path(package_name): + """Get the path to the cache file for a package""" + return os.path.join(CACHE_DIR, f"{package_name}_downloads.json") + + +def read_from_cache(package_name): + """ + Read download statistics from cache if available and not expired + Returns (downloads, is_valid) tuple where is_valid is True if cache is valid + """ + cache_path = get_cache_path(package_name) + + if not os.path.exists(cache_path): + return None, False + + try: + with open(cache_path, "r") as f: + cache_data = json.load(f) + + # Check if cache is expired + timestamp = cache_data.get("timestamp", 0) + current_time = time.time() + + if current_time - timestamp > CACHE_DURATION: + return None, False + + return cache_data.get("downloads"), True + except Exception as e: + print(f"Error reading from cache: {e}", file=sys.stderr) + return None, False + + +def write_to_cache(package_name, downloads): + """Write download statistics to cache""" + cache_path = get_cache_path(package_name) + + try: + ensure_cache_dir() + cache_data = { + "downloads": downloads, + "timestamp": time.time(), + "datetime": datetime.now().isoformat(), + } + + with open(cache_path, "w") as f: + json.dump(cache_data, f) + + return True + except Exception as e: + print(f"Error writing to cache: {e}", file=sys.stderr) + return False + + +def get_downloads_from_bigquery(credentials_path=None, package_name="aider-chat"): + """ + Fetch download statistics for a package from Google BigQuery PyPI dataset + Uses a 24-hour cache to avoid unnecessary API calls + """ + # Check if we have a valid cached value + cached_downloads, is_valid = read_from_cache(package_name) + if is_valid: + print(f"Using cached download statistics for {package_name} (valid for 24 hours)") + return cached_downloads + + print(f"Cache invalid or expired, fetching fresh download statistics for {package_name}") + + try: + # Initialize credentials if path provided + credentials = None + if credentials_path: + credentials = service_account.Credentials.from_service_account_file( + credentials_path, scopes=["https://www.googleapis.com/auth/cloud-platform"] + ) + + # Create a client + client = bigquery.Client(credentials=credentials) + + # Query to get total downloads for the package, excluding CI/CD systems + query = f""" + SELECT COUNT(*) as total_downloads + FROM `bigquery-public-data.pypi.file_downloads` + WHERE file.project = '{package_name}' + AND NOT ( + -- Exclude common CI/CD systems based on installer name patterns + LOWER(details.installer.name) LIKE '%github%' OR + LOWER(details.installer.name) LIKE '%travis%' OR + LOWER(details.installer.name) LIKE '%circle%' OR + LOWER(details.installer.name) LIKE '%jenkins%' OR + LOWER(details.installer.name) LIKE '%gitlab%' OR + LOWER(details.installer.name) LIKE '%azure%' OR + LOWER(details.installer.name) LIKE '%ci%' OR + LOWER(details.installer.name) LIKE '%cd%' OR + LOWER(details.installer.name) LIKE '%bot%' OR + LOWER(details.installer.name) LIKE '%build%' + ) + """ + + # Execute the query + query_job = client.query(query) + results = query_job.result() + + # Get the first (and only) row + for row in results: + downloads = row.total_downloads + # Write the result to cache + write_to_cache(package_name, downloads) + return downloads + + return 0 + except Exception as e: + print(f"Error fetching download statistics from BigQuery: {e}", file=sys.stderr) + # If there was an error but we have a cached value, use it even if expired + if cached_downloads is not None: + print("Using expired cached data due to BigQuery error") + return cached_downloads + return None + + +def get_total_downloads( + api_key=None, package_name="aider-chat", use_bigquery=False, credentials_path=None +): + """ + Fetch total downloads for a Python package + + If use_bigquery is True, fetches from BigQuery. + Otherwise uses pepy.tech API (requires api_key). + """ + if use_bigquery: + print(f"Using BigQuery to fetch download statistics for {package_name}") + return get_downloads_from_bigquery(credentials_path, package_name) + + # Fall back to pepy.tech API + print(f"Using pepy.tech API to fetch download statistics for {package_name}") + if not api_key: + print("API key not provided for pepy.tech", file=sys.stderr) + sys.exit(1) + + url = f"https://api.pepy.tech/api/v2/projects/{package_name}" + headers = {"X-API-Key": api_key} + + try: + response = requests.get(url, headers=headers) + response.raise_for_status() # Raise an exception for HTTP errors + + data = response.json() + total_downloads = data.get("total_downloads", 0) + + return total_downloads + except requests.exceptions.RequestException as e: + print(f"Error fetching download statistics from pepy.tech: {e}", file=sys.stderr) + sys.exit(1) + + +def get_github_stars(repo="paul-gauthier/aider"): + """ + Fetch the number of GitHub stars for a repository + """ + url = f"https://api.github.com/repos/{repo}" + headers = {"Accept": "application/vnd.github.v3+json"} + + try: + response = requests.get(url, headers=headers) + response.raise_for_status() # Raise an exception for HTTP errors + + data = response.json() + stars = data.get("stargazers_count", 0) + + return stars + except requests.exceptions.RequestException as e: + print(f"Error fetching GitHub stars: {e}", file=sys.stderr) + return None + + +def get_latest_release_aider_percentage(): + """ + Get the percentage of code written by Aider in the LATEST release + from the blame.yml file + """ + blame_path = os.path.join( + os.path.dirname(os.path.dirname(os.path.abspath(__file__))), + "aider", + "website", + "_data", + "blame.yml", + ) + + try: + with open(blame_path, "r") as f: + blame_data = yaml.safe_load(f) + + if not blame_data or len(blame_data) == 0: + return 0, "unknown" + + # Find the latest release by parsing version numbers + latest_version = None + latest_release = None + + for release in blame_data: + version_tag = release.get("end_tag", "") + if not version_tag.startswith("v"): + continue + + # Parse version like "v0.77.0" into a tuple (0, 77, 0) + try: + version_parts = tuple(int(part) for part in version_tag[1:].split(".")) + if latest_version is None or version_parts > latest_version: + latest_version = version_parts + latest_release = release + except ValueError: + # Skip if version can't be parsed as integers + continue + + if latest_release: + percentage = latest_release.get("aider_percentage", 0) + version = latest_release.get("end_tag", "unknown") + return percentage, version + + return 0, "unknown" + except Exception as e: + print(f"Error reading blame data: {e}", file=sys.stderr) + return 0, "unknown" + + +def format_number(number): + """ + Format a large number with K, M, B suffixes with 1 decimal place + """ + if number is None: + return "0" + + if number >= 1_000_000_000: + return f"{number / 1_000_000_000:.1f}B" + elif number >= 1_000_000: + return f"{number / 1_000_000:.1f}M" + elif number >= 1_000: + return f"{number / 1_000:.1f}K" + else: + return str(number) + + +def generate_badges_md(downloads, stars, aider_percentage): + """ + Generate markdown for badges with updated values + """ + # Format downloads to 1 decimal place with M suffix + downloads_formatted = format_number(downloads) + + # Round aider percentage to whole number + aider_percent_rounded = round(aider_percentage) + + markdown = f""" GitHub Stars + PyPI Downloads + Tokens per week + OpenRouter Ranking + Singularity""" # noqa + + return markdown + + +def get_badges_md(): + """ + Get all statistics and return the generated badges markdown + """ + # Load environment variables from .env file + load_dotenv() + + # Check if we should use BigQuery and get credentials path + bigquery_env = os.environ.get("USE_BIGQUERY", "false") + use_bigquery = bigquery_env.lower() in ("true", "1", "yes") or os.path.exists(bigquery_env) + credentials_path = bigquery_env if os.path.exists(bigquery_env) else None + + # Get API key from environment variable if not using BigQuery + api_key = None + if not use_bigquery: + api_key = os.environ.get("PEPY_API_KEY") + if not api_key: + print( + ( + "API key not provided and BigQuery not enabled. Please set PEPY_API_KEY" + " environment variable" + ), + file=sys.stderr, + ) + sys.exit(1) + + # Get PyPI downloads for the default package + total_downloads = get_total_downloads(api_key, "aider-chat", use_bigquery, credentials_path) + + # Get GitHub stars for the default repo + stars = get_github_stars("paul-gauthier/aider") + + # Get Aider contribution percentage in latest release + percentage, _ = get_latest_release_aider_percentage() + + # Generate and return badges markdown + return generate_badges_md(total_downloads, stars, percentage) + + +def get_badges_html(): + """ + Get all statistics and return HTML-formatted badges + """ + # Load environment variables from .env file + load_dotenv() + + # Check if we should use BigQuery and get credentials path + bigquery_env = os.environ.get("USE_BIGQUERY", "false") + use_bigquery = bigquery_env.lower() in ("true", "1", "yes") or os.path.exists(bigquery_env) + credentials_path = bigquery_env if os.path.exists(bigquery_env) else None + + # Get API key from environment variable if not using BigQuery + api_key = None + if not use_bigquery: + api_key = os.environ.get("PEPY_API_KEY") + if not api_key: + print( + ( + "API key not provided and BigQuery not enabled. Please set PEPY_API_KEY" + " environment variable" + ), + file=sys.stderr, + ) + sys.exit(1) + + # Get PyPI downloads for the default package + total_downloads = get_total_downloads(api_key, "aider-chat", use_bigquery, credentials_path) + + # Get GitHub stars for the default repo + stars = get_github_stars("paul-gauthier/aider") + + # Get Aider contribution percentage in latest release + percentage, _ = get_latest_release_aider_percentage() + + # Format values + downloads_formatted = format_number(total_downloads) + # Stars should be rounded to whole numbers + if stars is None: + stars_formatted = "0" + elif stars >= 1_000_000_000: + stars_formatted = f"{round(stars / 1_000_000_000)}B" + elif stars >= 1_000_000: + stars_formatted = f"{round(stars / 1_000_000)}M" + elif stars >= 1_000: + stars_formatted = f"{round(stars / 1_000)}K" + else: + stars_formatted = str(int(round(stars))) + aider_percent_rounded = round(percentage) + + # Generate HTML badges + html = f""" + ⭐ GitHub Stars + {stars_formatted} + + + 📦 Installs + {downloads_formatted} + +
    + 📈 Tokens/week + {TOKENS_PER_WEEK} +
    + + 🏆 OpenRouter + Top 20 + + + 🔄 Singularity + {aider_percent_rounded}% +""" # noqa + + return html + + +def get_testimonials_js(): + """ + Extract testimonials from README.md and format them as JavaScript array + """ + # Path to README.md, relative to this script + readme_path = os.path.join( + os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "README.md" + ) + + testimonials = [] + in_testimonials_section = False + + try: + with open(readme_path, "r", encoding="utf-8") as f: + for line in f: + # Check if we're entering the testimonials section + if line.strip() == "## Kind Words From Users": + in_testimonials_section = True + continue + + # If we've hit another section after testimonials, stop + if in_testimonials_section and line.startswith("##"): + break + + # Process testimonial lines + if in_testimonials_section and line.strip().startswith('- *"'): + # Extract the quote text: between *" and "* + quote_match = line.split('*"')[1].split('"*')[0].strip() + + # Extract the author: between "— [" and "]" + author_match = line.split("— [")[1].split("]")[0].strip() + + # Extract the link: between "(" and ")" + link_match = line.split("](")[1].split(")")[0].strip() + + testimonials.append( + {"text": quote_match, "author": author_match, "link": link_match} + ) + + # Format as JavaScript array with script tags + if not testimonials: + return "" + + js_array = "" + + return js_array + + except Exception as e: + print(f"Error reading testimonials from README: {e}", file=sys.stderr) + # Return empty array as fallback + return "" + + +def main(): + # Load environment variables from .env file + load_dotenv() + + # Ensure cache directory exists + ensure_cache_dir() + + parser = argparse.ArgumentParser(description="Get total downloads and GitHub stars for aider") + parser.add_argument( + "--api-key", + help=( + "pepy.tech API key (can also be set via PEPY_API_KEY in .env file or environment" + " variable)" + ), + ) + parser.add_argument( + "--package", default="aider-chat", help="Package name (default: aider-chat)" + ) + parser.add_argument( + "--github-repo", + default="paul-gauthier/aider", + help="GitHub repository (default: paul-gauthier/aider)", + ) + parser.add_argument("--markdown", action="store_true", help="Generate markdown badges block") + parser.add_argument( + "--use-bigquery", + action="store_true", + help="Use BigQuery to fetch download statistics instead of pepy.tech", + ) + parser.add_argument( + "--credentials-path", help="Path to Google Cloud service account credentials JSON file" + ) + args = parser.parse_args() + + # Determine whether to use BigQuery and get credentials path + bigquery_env = os.environ.get("USE_BIGQUERY", "false") + use_bigquery = ( + args.use_bigquery + or bigquery_env.lower() in ("true", "1", "yes") + or os.path.exists(bigquery_env) + ) + credentials_path = args.credentials_path or ( + bigquery_env if os.path.exists(bigquery_env) else None + ) + + # Check for required parameters + api_key = None + if not use_bigquery: + # Get API key from args or environment variable + api_key = args.api_key or os.environ.get("PEPY_API_KEY") + if not api_key: + print( + ( + "API key not provided and BigQuery not enabled. Please set PEPY_API_KEY" + " environment variable, use --api-key, or enable BigQuery with --use-bigquery" + ), + file=sys.stderr, + ) + sys.exit(1) + elif use_bigquery and not credentials_path and not args.credentials_path: + print( + ( + "BigQuery enabled but no credentials provided. Please set" + " USE_BIGQUERY to path of credentials file or use --credentials-path" + ), + file=sys.stderr, + ) + # Continue execution - BigQuery might work without explicit credentials in some environments + + # Get PyPI downloads + total_downloads = get_total_downloads(api_key, args.package, use_bigquery, credentials_path) + print(f"Total downloads for {args.package}: {total_downloads:,}") + + # Get GitHub stars + stars = get_github_stars(args.github_repo) + if stars is not None: + print(f"GitHub stars for {args.github_repo}: {stars:,}") + + # Get Aider contribution percentage in latest release + percentage, version = get_latest_release_aider_percentage() + print(f"Aider wrote {percentage:.2f}% of code in the LATEST release ({version})") + + +if __name__ == "__main__": + main() diff --git a/scripts/jekyll_run.sh b/scripts/jekyll_run.sh index 97aa071ff..da1e0a49b 100755 --- a/scripts/jekyll_run.sh +++ b/scripts/jekyll_run.sh @@ -1,13 +1,16 @@ #!/bin/bash -# Run the Docker container +# Run the Docker container with optimizations for faster builds docker run \ --rm \ -v "$PWD/aider/website:/site" \ -p 4000:4000 \ -e HISTFILE=/site/.bash_history \ + -e JEKYLL_ENV=development \ -it \ - my-jekyll-site + my-jekyll-site bundle exec jekyll serve --host 0.0.0.0 $* -# --entrypoint /bin/bash \ +# Additional options: +# --incremental: Only rebuilds files that changed +# --livereload: Auto-refreshes browser when content changes diff --git a/scripts/logo_svg.py b/scripts/logo_svg.py new file mode 100755 index 000000000..7a69bdaba --- /dev/null +++ b/scripts/logo_svg.py @@ -0,0 +1,174 @@ +#!/usr/bin/env python3 +""" +Script to generate an SVG logo for Aider with embedded font. +Reads the Glass_TTY_VT220.ttf font, subsets it to only include the letters needed, +and creates an SVG with the word "aider" in terminal green (#14b014) on a transparent background. +""" + +import argparse +import base64 +import os +import tempfile + +from fontTools.subset import main as subset_main + + +def subset_font(font_path, text): + """ + Create a subset of the font containing only the characters needed for the text. + + Args: + font_path (str): Path to the TTF font file + text (str): Text for which to extract characters + + Returns: + bytes: The subsetted font data + """ + # Create a temporary file to store the subset font + with tempfile.NamedTemporaryFile(suffix=".ttf", delete=False) as tmp_file: + tmp_path = tmp_file.name + + # Get unique characters from the text + unique_chars = set(text.lower() + text.upper()) + + # Create the subsetting command + subset_args = [ + font_path, + "--output-file=" + tmp_path, + "--unicodes=" + ",".join([f"U+{ord(c):04X}" for c in unique_chars]), + "--name-IDs=*", # Keep all name records + "--recalc-bounds", + "--drop-tables=", # Don't drop any tables by default + ] + + # Run the subsetting + subset_main(subset_args) + + # Read the subsetted font + with open(tmp_path, "rb") as f: + font_data = f.read() + + # Clean up the temporary file + os.unlink(tmp_path) + + return font_data + + +def generate_svg_with_embedded_font(font_path, text="aider", color="#14b014", output_path=None): + """ + Generate an SVG with embedded TTF font data. + + Args: + font_path (str): Path to the TTF font file + text (str): Text to display in the SVG + color (str): Color of the text (hex format) + output_path (str, optional): Path to save the SVG file, if None prints to stdout + + Returns: + str: The SVG content + """ + # Subset the font to only include the needed characters + font_data = subset_font(font_path, text) + + # Encode the font data as base64 + font_base64 = base64.b64encode(font_data).decode("utf-8") + + # Calculate SVG dimensions based on text length + # These values can be adjusted to modify the appearance + char_width = 40 + width = len(text) * char_width + height = 60 + text_x = width / 2 # Center point of the SVG width + text_y = height * 0.62 # Center point of the SVG height + + # Create the SVG with embedded font and glow effect + svg = f""" + + + + + + + + + + {text} +""" # noqa + + # Save to file or print to stdout + if output_path: + with open(output_path, "w") as f: + f.write(svg) + print(f"SVG logo saved to {output_path}") + + return svg + + +def main(): + parser = argparse.ArgumentParser(description="Generate an SVG logo with embedded font") + parser.add_argument( + "--font", + type=str, + default="aider/website/assets/Glass_TTY_VT220.ttf", + help="Path to the TTF font file", + ) + parser.add_argument("--text", type=str, default="aider", help="Text to display in the SVG") + parser.add_argument( + "--color", type=str, default="#14b014", help="Color of the text (hex format)" + ) + parser.add_argument( + "--output", + type=str, + default="aider/website/assets/logo.svg", + help="Path to save the SVG file", + ) + parser.add_argument( + "--verbose", action="store_true", help="Print additional information about font subsetting" + ) + + args = parser.parse_args() + + # Make sure the font file exists + if not os.path.exists(args.font): + print(f"Error: Font file not found at {args.font}") + return + + # Create output directory if it doesn't exist + if args.output: + output_dir = os.path.dirname(args.output) + if output_dir and not os.path.exists(output_dir): + os.makedirs(output_dir) + + # Generate the SVG + if args.verbose: + print(f"Subsetting font {args.font} to include only characters for: {args.text}") + + svg = generate_svg_with_embedded_font( + args.font, text=args.text, color=args.color, output_path=args.output + ) + + if args.verbose and args.output: + # Calculate size savings + original_size = os.path.getsize(args.font) + output_size = len(svg.encode("utf-8")) + print(f"Original font size: {original_size / 1024:.2f} KB") + print(f"Output SVG size: {output_size / 1024:.2f} KB") + + +if __name__ == "__main__": + main() diff --git a/scripts/recording_audio.py b/scripts/recording_audio.py new file mode 100755 index 000000000..7506d4c89 --- /dev/null +++ b/scripts/recording_audio.py @@ -0,0 +1,338 @@ +#!/usr/bin/env python3 +""" +Generate TTS audio files for recording commentary using OpenAI's API. +Usage: python scripts/recording_audio.py path/to/recording.md +""" + +import argparse +import json +import os +import re +import subprocess +import tempfile +from pathlib import Path + +import requests +from dotenv import load_dotenv + +# Load environment variables from .env file +load_dotenv() + +# Configuration +OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY") +OUTPUT_DIR = "aider/website/assets/audio" +VOICE = "onyx" # Options: alloy, echo, fable, onyx, nova, shimmer +MP3_BITRATE = "32k" # Lower bitrate for smaller files + + +def extract_recording_id(markdown_file): + """Extract recording ID from the markdown file path.""" + return Path(markdown_file).stem + + +def extract_commentary(markdown_file): + """Extract commentary markers from markdown file.""" + with open(markdown_file, "r") as f: + content = f.read() + + # Find Commentary section + commentary_match = re.search(r"## Commentary\s+(.*?)(?=##|\Z)", content, re.DOTALL) + if not commentary_match: + print(f"No Commentary section found in {markdown_file}") + return [] + + commentary = commentary_match.group(1).strip() + + # Extract timestamp-message pairs + markers = [] + for line in commentary.split("\n"): + line = line.strip() + if line.startswith("- "): + line = line[2:] # Remove the list marker + match = re.match(r"(\d+):(\d+)\s+(.*)", line) + if match: + minutes, seconds, message = match.groups() + time_in_seconds = int(minutes) * 60 + int(seconds) + markers.append((time_in_seconds, message)) + + return markers + + +def check_ffmpeg(): + """Check if FFmpeg is available.""" + try: + subprocess.run(["ffmpeg", "-version"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) + return True + except (subprocess.SubprocessError, FileNotFoundError): + return False + + +def compress_audio(input_file, output_file, bitrate=MP3_BITRATE): + """Compress audio file using FFmpeg.""" + if not check_ffmpeg(): + print("Warning: FFmpeg not found, skipping compression") + return False + + try: + subprocess.run( + [ + "ffmpeg", + "-i", + input_file, + "-b:a", + bitrate, + "-ac", + "1", # Mono audio + "-y", # Overwrite output file + output_file, + ], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) + return True + except subprocess.SubprocessError as e: + print(f"Error compressing audio: {e}") + return False + + +def generate_audio_openai(text, output_file, voice=VOICE, bitrate=MP3_BITRATE): + """Generate audio using OpenAI TTS API and compress it.""" + if not OPENAI_API_KEY: + print("Error: OPENAI_API_KEY environment variable not set") + return False + + url = "https://api.openai.com/v1/audio/speech" + headers = {"Authorization": f"Bearer {OPENAI_API_KEY}", "Content-Type": "application/json"} + data = {"model": "tts-1", "input": text, "voice": voice} + + try: + response = requests.post(url, headers=headers, json=data) + + if response.status_code == 200: + # Use a temporary file for the initial audio + with tempfile.NamedTemporaryFile(suffix=".mp3", delete=False) as temp_file: + temp_path = temp_file.name + temp_file.write(response.content) + + # Get original file size + original_size = os.path.getsize(temp_path) + + # Compress the audio to reduce file size + success = compress_audio(temp_path, output_file, bitrate) + + # If compression failed or FFmpeg not available, use the original file + if not success: + with open(output_file, "wb") as f: + f.write(response.content) + print(f" ℹ Using original file: {original_size} bytes") + else: + compressed_size = os.path.getsize(output_file) + reduction = (1 - compressed_size / original_size) * 100 + print( + f" ℹ Compressed: {original_size} → {compressed_size} bytes ({reduction:.1f}%" + " reduction)" + ) + + # Clean up the temporary file + try: + os.unlink(temp_path) + except OSError: + pass + + return True + else: + print(f"Error: {response.status_code}, {response.text}") + return False + except Exception as e: + print(f"Exception during API call: {e}") + return False + + +def load_metadata(output_dir): + """Load the audio metadata JSON file if it exists.""" + metadata_file = os.path.join(output_dir, "metadata.json") + + if os.path.exists(metadata_file): + try: + with open(metadata_file, "r") as f: + return json.load(f) + except json.JSONDecodeError: + print(f"Warning: Could not parse metadata file {metadata_file}, will recreate it") + + return {} + + +def save_metadata(output_dir, metadata): + """Save the audio metadata to JSON file.""" + metadata_file = os.path.join(output_dir, "metadata.json") + + with open(metadata_file, "w") as f: + json.dump(metadata, f, indent=2) + + +def get_timestamp_key(time_sec): + """Generate a consistent timestamp key format for metadata.""" + minutes = time_sec // 60 + seconds = time_sec % 60 + return f"{minutes:02d}-{seconds:02d}" + + +def main(): + parser = argparse.ArgumentParser(description="Generate TTS audio for recording commentary.") + parser.add_argument("markdown_file", help="Path to the recording markdown file") + parser.add_argument("--voice", default=VOICE, help=f"OpenAI voice to use (default: {VOICE})") + parser.add_argument( + "--output-dir", default=OUTPUT_DIR, help=f"Output directory (default: {OUTPUT_DIR})" + ) + parser.add_argument( + "--dry-run", action="store_true", help="Print what would be done without generating audio" + ) + parser.add_argument( + "--force", action="store_true", help="Force regeneration of all audio files" + ) + parser.add_argument( + "--bitrate", + default=MP3_BITRATE, + help=f"MP3 bitrate for compression (default: {MP3_BITRATE})", + ) + parser.add_argument( + "--compress-only", + action="store_true", + help="Only compress existing files without generating new ones", + ) + + args = parser.parse_args() + + # Use args.voice directly instead of modifying global VOICE + selected_voice = args.voice + selected_bitrate = args.bitrate + + # Check if FFmpeg is available for compression + if not check_ffmpeg() and not args.dry_run: + print("Warning: FFmpeg not found. Audio compression will be skipped.") + print("To enable compression, please install FFmpeg: https://ffmpeg.org/download.html") + + recording_id = extract_recording_id(args.markdown_file) + print(f"Processing recording: {recording_id}") + + # Create output directory + output_dir = os.path.join(args.output_dir, recording_id) + print(f"Audio directory: {output_dir}") + if not args.dry_run: + os.makedirs(output_dir, exist_ok=True) + + # If compress-only flag is set, just compress existing files + if args.compress_only: + print("Compressing existing files only...") + metadata = load_metadata(output_dir) + for timestamp_key in metadata: + filename = f"{timestamp_key}.mp3" + file_path = os.path.join(output_dir, filename) + + if os.path.exists(file_path): + temp_file = f"{file_path}.temp" + print(f"Compressing: {filename}") + + if not args.dry_run: + success = compress_audio(file_path, temp_file, selected_bitrate) + if success: + # Get file sizes for reporting + original_size = os.path.getsize(file_path) + compressed_size = os.path.getsize(temp_file) + reduction = (1 - compressed_size / original_size) * 100 + + # Replace original with compressed version + os.replace(temp_file, file_path) + print( + f" ✓ Compressed: {original_size} → {compressed_size} bytes" + f" ({reduction:.1f}% reduction)" + ) + else: + print(" ✗ Failed to compress") + if os.path.exists(temp_file): + os.remove(temp_file) + else: + print(f" Would compress: {file_path}") + + return + + # Extract commentary markers + markers = extract_commentary(args.markdown_file) + + if not markers: + print("No commentary markers found!") + return + + print(f"Found {len(markers)} commentary markers") + + # Load existing metadata + metadata = load_metadata(output_dir) + + # Create a dictionary of current markers for easier comparison + current_markers = {} + for time_sec, message in markers: + timestamp_key = get_timestamp_key(time_sec) + current_markers[timestamp_key] = message + + # Track files that need to be deleted (no longer in the markdown) + files_to_delete = [] + for timestamp_key in metadata: + if timestamp_key not in current_markers: + files_to_delete.append(f"{timestamp_key}.mp3") + + # Delete files that are no longer needed + if files_to_delete and not args.dry_run: + for filename in files_to_delete: + file_path = os.path.join(output_dir, filename) + if os.path.exists(file_path): + print(f"Removing obsolete file: {filename}") + os.remove(file_path) + elif files_to_delete: + print(f"Would remove {len(files_to_delete)} obsolete files: {', '.join(files_to_delete)}") + + # Generate audio for each marker + for time_sec, message in markers: + timestamp_key = get_timestamp_key(time_sec) + filename = f"{timestamp_key}.mp3" + output_file = os.path.join(output_dir, filename) + + # Check if we need to generate this file + needs_update = args.force or ( + timestamp_key not in metadata or metadata[timestamp_key] != message + ) + + minutes = time_sec // 60 + seconds = time_sec % 60 + + print(f"Marker at {minutes}:{seconds:02d} - {message}") + + if not needs_update: + print(" ✓ Audio file already exists with correct content") + continue + + if args.dry_run: + print(f" Would generate: {output_file}") + else: + print(f" Generating: {output_file}") + success = generate_audio_openai( + message, output_file, voice=selected_voice, bitrate=selected_bitrate + ) + if success: + print(" ✓ Generated audio file") + # Update metadata with the new message + metadata[timestamp_key] = message + else: + print(" ✗ Failed to generate audio") + + # Save updated metadata + if not args.dry_run: + # Remove entries for deleted files + for timestamp_key in list(metadata.keys()): + if timestamp_key not in current_markers: + del metadata[timestamp_key] + + save_metadata(output_dir, metadata) + + +if __name__ == "__main__": + main() diff --git a/scripts/redact-cast.py b/scripts/redact-cast.py new file mode 100755 index 000000000..91f230e87 --- /dev/null +++ b/scripts/redact-cast.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 +import json +import os +import re +import sys + +import pyte +from tqdm import tqdm + +from aider.dump import dump # noqa + + +def main(): + if len(sys.argv) != 3: + print(f"Usage: {sys.argv[0]} input_cast_file output_cast_file") + sys.exit(1) + + input_file = sys.argv[1] + output_file = sys.argv[2] + + # Count total lines for progress bar + total_lines = sum(1 for _ in open(input_file, "r")) + + with open(input_file, "r") as fin, open(output_file, "w") as fout: + # Process header + header = fin.readline().strip() + fout.write(header + "\n") + + # Parse header for terminal dimensions + header_data = json.loads(header) + width = header_data.get("width", 80) + height = header_data.get("height", 24) + print(f"Terminal dimensions: {width}x{height}") + + screen = pyte.Screen(width, height) + stream = pyte.Stream(screen) + + # Process events line by line + for line in tqdm(fin, desc="Processing events", total=total_lines - 1): + if not line.strip(): + continue + + event = json.loads(line) + + if not (len(event) >= 3 and event[1] == "o"): + fout.write(line) + continue + + output_text = event[2] + stream.feed(output_text) + + # Check if "Atuin" is visible on screen + atuin_visible = False + for display_line in screen.display: + if "Atuin" in display_line or "[ GLOBAL ]" in display_line: + atuin_visible = True + break + + if not atuin_visible: + fout.write(line) + + +if __name__ == "__main__": + main() diff --git a/scripts/tmux_record.sh b/scripts/tmux_record.sh new file mode 100755 index 000000000..de40cca35 --- /dev/null +++ b/scripts/tmux_record.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +# Check if there is exactly one active window +WINDOW_COUNT=$(tmux list-windows | wc -l) +if [ "$WINDOW_COUNT" -ne 1 ]; then + echo "Error: Expected exactly 1 tmux window, found $WINDOW_COUNT windows." + exit 1 +fi + +# Get tmux window size (width x height) +TMUX_SIZE=$(tmux display -p '#{window_width}x#{window_height}') + +# Print the terminal size +echo "Using terminal size: $TMUX_SIZE" + +# Start asciinema recording with the tmux window size +asciinema rec -c "tmux attach -t 0 -r" --headless --tty-size $TMUX_SIZE $* + diff --git a/scripts/tsl_pack_langs.py b/scripts/tsl_pack_langs.py new file mode 100755 index 000000000..cc56ae6bd --- /dev/null +++ b/scripts/tsl_pack_langs.py @@ -0,0 +1,145 @@ +#!/usr/bin/env python3 + +import json +import os +import sys +import time + +import requests + + +def get_default_branch(owner, repo): + """Get the default branch of a GitHub repository using the API.""" + api_url = f"https://api.github.com/repos/{owner}/{repo}" + try: + response = requests.get(api_url) + response.raise_for_status() + return response.json().get("default_branch") + except requests.exceptions.RequestException: + return None + + +def try_download_tags(owner, repo, branch, directory, output_path): + """Try to download tags.scm from a specific branch.""" + base_url = f"https://raw.githubusercontent.com/{owner}/{repo}/{branch}" + if directory: + tags_url = f"{base_url}/{directory}/queries/tags.scm" + else: + tags_url = f"{base_url}/queries/tags.scm" + + try: + response = requests.get(tags_url) + response.raise_for_status() + + # Save the file + with open(output_path, "w") as f: + f.write(response.text) + return True + except requests.exceptions.RequestException: + return False + + +def main(): + # Path to the language definitions file + lang_def_path = "../../tmp/tree-sitter-language-pack/sources/language_definitions.json" + + # Path to store the tags.scm files + output_dir = "aider/queries/tree-sitter-language-pack" + + # Create the output directory if it doesn't exist + os.makedirs(output_dir, exist_ok=True) + + # Common branch names to try if API fails and config branch doesn't work + common_branches = ["main", "master", "dev", "develop"] + + try: + # Load the language definitions + with open(lang_def_path, "r") as f: + lang_defs = json.load(f) + except Exception as e: + print(f"Error loading language definitions: {e}") + sys.exit(1) + + print(f"Found {len(lang_defs)} language definitions") + + # Process each language + successes = 0 + total = len(lang_defs) + + for lang, config in lang_defs.items(): + # Extract repo URL from the config + repo_url = config.get("repo") + print(f"Processing {lang} ({repo_url})...") + + if not repo_url: + print(f"Skipping {lang}: No repository URL found") + continue + + directory = config.get("directory", "") + + # Parse the GitHub repository URL + if "github.com" not in repo_url: + print(f"Skipping {lang}: Not a GitHub repository") + continue + + # Extract the owner and repo name from the URL + parts = repo_url.rstrip("/").split("/") + if len(parts) < 5: + print(f"Skipping {lang}: Invalid GitHub URL format") + continue + + owner = parts[-2] + repo = parts[-1] + + # Create output directory and set output file path + os.makedirs(output_dir, exist_ok=True) + output_file = os.path.join(output_dir, f"{lang}-tags.scm") + + # Skip if file already exists + if os.path.exists(output_file): + print(f"Skipping {lang}: tags.scm already exists") + successes += 1 + continue + + # Try branches in this order: + # 1. Branch specified in the config + # 2. Default branch from GitHub API + # 3. Common branch names (main, master, etc.) + + branches_to_try = [] + + # 1. Branch from config (if specified) + config_branch = config.get("branch") + if config_branch: + branches_to_try.append(config_branch) + + # 2. Default branch from GitHub API + default_branch = get_default_branch(owner, repo) + if default_branch and default_branch not in branches_to_try: + branches_to_try.append(default_branch) + + # 3. Add common branch names + for branch in common_branches: + if branch not in branches_to_try: + branches_to_try.append(branch) + + # Try each branch + success = False + for branch in branches_to_try: + if try_download_tags(owner, repo, branch, directory, output_file): + print(f"Successfully downloaded tags for {lang} (branch: {branch})") + success = True + successes += 1 + break + + if not success: + print(f"Failed to download tags for {lang} after trying all branches") + + # Be nice to GitHub's API + time.sleep(0.1) + + print(f"All language tags processed. Downloaded {successes}/{total} successfully.") + + +if __name__ == "__main__": + main() diff --git a/scripts/update-docs.sh b/scripts/update-docs.sh index ecde8ac01..7807c795e 100755 --- a/scripts/update-docs.sh +++ b/scripts/update-docs.sh @@ -17,7 +17,7 @@ fi # README.md before index.md, because index.md uses cog to include README.md cog $ARG \ README.md \ - aider/website/index.md \ + aider/website/index.html \ aider/website/HISTORY.md \ aider/website/docs/usage/commands.md \ aider/website/docs/languages.md \ diff --git a/scripts/update-history.py b/scripts/update-history.py index 968210a63..e8fa455b2 100755 --- a/scripts/update-history.py +++ b/scripts/update-history.py @@ -7,25 +7,57 @@ import tempfile from history_prompts import history_prompt -from aider import __version__ +def get_latest_version_from_history(): + with open("HISTORY.md", "r") as f: + history_content = f.read() -def get_base_version(): - # Parse current version like "0.64.2.dev" to get major.minor - match = re.match(r"(\d+\.\d+)", __version__) + # Find most recent version header + match = re.search(r"### Aider v(\d+\.\d+\.\d+)", history_content) if not match: - raise ValueError(f"Could not parse version: {__version__}") - return match.group(1) + ".0" + raise ValueError("Could not find version header in HISTORY.md") + return match.group(1) def run_git_log(): - base_ver = get_base_version() + latest_ver = get_latest_version_from_history() cmd = [ "git", "log", - "-p", "--pretty=full", - f"v{base_ver}..HEAD", + f"v{latest_ver}..HEAD", + "--", + "aider/", + ":!aider/website/", + ":!scripts/", + ":!HISTORY.md", + ] + result = subprocess.run(cmd, capture_output=True, text=True) + return result.stdout + + +def run_git_diff(): + latest_ver = get_latest_version_from_history() + cmd = [ + "git", + "diff", + f"v{latest_ver}..HEAD", + "--", + "aider/", + ":!aider/website/", + ":!scripts/", + ":!HISTORY.md", + ] + result = subprocess.run(cmd, capture_output=True, text=True) + return result.stdout + + +def run_plain_git_log(): + latest_ver = get_latest_version_from_history() + cmd = [ + "git", + "log", + f"v{latest_ver}..HEAD", "--", "aider/", ":!aider/website/", @@ -37,16 +69,18 @@ def run_git_log(): def main(): - # Get the git log output - diff_content = run_git_log() + # Get the git log and diff output + log_content = run_git_log() + plain_log_content = run_plain_git_log() + diff_content = run_git_diff() # Extract relevant portion of HISTORY.md - base_ver = get_base_version() + latest_ver = get_latest_version_from_history() with open("HISTORY.md", "r") as f: history_content = f.read() # Find the section for this version - version_header = f"### Aider v{base_ver}" + version_header = f"### Aider v{latest_ver}" start_idx = history_content.find("# Release history") if start_idx == -1: raise ValueError("Could not find start of release history") @@ -66,10 +100,18 @@ def main(): relevant_history = history_content[start_idx:next_version_idx] # Save relevant portions to temporary files + with tempfile.NamedTemporaryFile(mode="w", delete=False, suffix=".log") as tmp_log: + tmp_log.write(log_content) + log_path = tmp_log.name + with tempfile.NamedTemporaryFile(mode="w", delete=False, suffix=".diff") as tmp_diff: tmp_diff.write(diff_content) diff_path = tmp_diff.name + with tempfile.NamedTemporaryFile(mode="w", delete=False, suffix=".plain_log") as tmp_plain_log: + tmp_plain_log.write(plain_log_content) + plain_log_path = tmp_plain_log.name + with tempfile.NamedTemporaryFile(mode="w", delete=False, suffix=".md") as tmp_hist: tmp_hist.write(relevant_history) hist_path = tmp_hist.name @@ -81,7 +123,20 @@ def main(): # Construct and run the aider command message = history_prompt.format(aider_line=aider_line) - cmd = ["aider", hist_path, "--read", diff_path, "--msg", message, "--no-auto-commit"] + cmd = [ + "aider", + hist_path, + "--read", + log_path, + "--read", + plain_log_path, + "--read", + diff_path, + "--msg", + message, + "--no-git", + "--no-auto-lint", + ] subprocess.run(cmd) # Read back the updated history @@ -108,6 +163,8 @@ def main(): subprocess.run(["scripts/update-docs.sh"]) # Cleanup + os.unlink(log_path) + os.unlink(plain_log_path) os.unlink(diff_path) os.unlink(hist_path) diff --git a/scripts/versionbump.py b/scripts/versionbump.py index 6625d33f7..2087ca939 100755 --- a/scripts/versionbump.py +++ b/scripts/versionbump.py @@ -66,9 +66,7 @@ def check_main_branch_up_to_date(): # Function to check if we can push to the origin repository def check_ok_to_push(): print("Checking if it's ok to push to origin repository...") - result = subprocess.run(["git", "push", "--dry-run", "origin"], capture_output=True, text=True) - print(result.stdout) - print(result.stderr) + result = subprocess.run(["git", "push", "--dry-run", "origin"]) if result.returncode != 0: print("Error: Cannot push to origin repository.") @@ -123,7 +121,7 @@ def main(): ["git", "add", "aider/__init__.py"], ["git", "commit", "-m", f"version bump to {new_version}"], ["git", "tag", f"v{new_version}"], - ["git", "push", "origin"], + ["git", "push", "origin", "--no-verify"], ["git", "push", "origin", f"v{new_version}", "--no-verify"], ] diff --git a/tests/basic/__init__.py b/tests/basic/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/basic/test_aws_credentials.py b/tests/basic/test_aws_credentials.py new file mode 100644 index 000000000..87d2b3a63 --- /dev/null +++ b/tests/basic/test_aws_credentials.py @@ -0,0 +1,169 @@ +import os +from unittest.mock import patch + +from aider.models import Model + + +class TestAWSCredentials: + """Test AWS credential handling, especially AWS_PROFILE.""" + + def test_bedrock_model_with_aws_profile(self): + """Test that Bedrock models accept AWS_PROFILE as valid authentication.""" + # Save original environment + original_env = os.environ.copy() + + try: + # Set up test environment + os.environ.clear() + os.environ["AWS_PROFILE"] = "test-profile" + + # Create a model instance + with patch("aider.llm.litellm.validate_environment") as mock_validate: + # Mock the litellm validate_environment to return missing AWS keys + mock_validate.return_value = { + "missing_keys": ["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY"], + "keys_in_environment": False, + } + + # Test with a bedrock model + model = Model("bedrock/anthropic.claude-v2") + + # Check that the AWS keys were removed from missing_keys + assert "AWS_ACCESS_KEY_ID" not in model.missing_keys + assert "AWS_SECRET_ACCESS_KEY" not in model.missing_keys + # With no missing keys, validation should pass + assert model.keys_in_environment + + finally: + # Restore original environment + os.environ.clear() + os.environ.update(original_env) + + def test_us_anthropic_model_with_aws_profile(self): + """Test that us.anthropic models accept AWS_PROFILE as valid authentication.""" + # Save original environment + original_env = os.environ.copy() + + try: + # Set up test environment + os.environ.clear() + os.environ["AWS_PROFILE"] = "test-profile" + + # Create a model instance + with patch("aider.llm.litellm.validate_environment") as mock_validate: + # Mock the litellm validate_environment to return missing AWS keys + mock_validate.return_value = { + "missing_keys": ["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY"], + "keys_in_environment": False, + } + + # Test with a us.anthropic model + model = Model("us.anthropic.claude-3-7-sonnet-20250219-v1:0") + + # Check that the AWS keys were removed from missing_keys + assert "AWS_ACCESS_KEY_ID" not in model.missing_keys + assert "AWS_SECRET_ACCESS_KEY" not in model.missing_keys + # With no missing keys, validation should pass + assert model.keys_in_environment + + finally: + # Restore original environment + os.environ.clear() + os.environ.update(original_env) + + def test_non_bedrock_model_with_aws_profile(self): + """Test that non-Bedrock models do not accept AWS_PROFILE for AWS credentials.""" + # Save original environment + original_env = os.environ.copy() + + try: + # Set up test environment + os.environ.clear() + os.environ["AWS_PROFILE"] = "test-profile" + + # Create a model instance + with patch("aider.llm.litellm.validate_environment") as mock_validate: + # Mock the litellm validate_environment to return missing AWS keys + mock_validate.return_value = { + "missing_keys": ["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY"], + "keys_in_environment": False, + } + + # Test with a non-Bedrock model + model = Model("gpt-4") + + # For non-Bedrock models, AWS credential keys should remain in missing_keys + assert "AWS_ACCESS_KEY_ID" in model.missing_keys + assert "AWS_SECRET_ACCESS_KEY" in model.missing_keys + # With missing keys, validation should fail + assert not model.keys_in_environment + + finally: + # Restore original environment + os.environ.clear() + os.environ.update(original_env) + + def test_bedrock_model_without_aws_profile(self): + """Test that Bedrock models require credentials when AWS_PROFILE is not set.""" + # Save original environment + original_env = os.environ.copy() + + try: + # Set up test environment + os.environ.clear() + + # Create a model instance + with patch("aider.llm.litellm.validate_environment") as mock_validate: + # Mock the litellm validate_environment to return missing AWS keys + mock_validate.return_value = { + "missing_keys": ["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY"], + "keys_in_environment": False, + } + + # Test with a bedrock model without AWS_PROFILE + model = Model("bedrock/anthropic.claude-v2") + + # Without AWS_PROFILE, AWS credential keys should remain in missing_keys + assert "AWS_ACCESS_KEY_ID" in model.missing_keys + assert "AWS_SECRET_ACCESS_KEY" in model.missing_keys + # With missing keys, validation should fail + assert not model.keys_in_environment + + finally: + # Restore original environment + os.environ.clear() + os.environ.update(original_env) + + def test_mixed_missing_keys_with_aws_profile(self): + """Test that only AWS credential keys are affected by AWS_PROFILE.""" + # Save original environment + original_env = os.environ.copy() + + try: + # Set up test environment + os.environ.clear() + os.environ["AWS_PROFILE"] = "test-profile" + + # Create a model instance + with patch("aider.llm.litellm.validate_environment") as mock_validate: + # Mock the litellm validate_environment to return missing AWS keys and another key + mock_validate.return_value = { + "missing_keys": ["AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "ANOTHER_KEY"], + "keys_in_environment": False, + } + + # Test with a bedrock model + model = Model("bedrock/anthropic.claude-v2") + + # AWS credential keys should be removed from missing_keys + assert "AWS_ACCESS_KEY_ID" not in model.missing_keys + assert "AWS_SECRET_ACCESS_KEY" not in model.missing_keys + # But other keys should remain + assert "ANOTHER_KEY" in model.missing_keys + # With other missing keys, validation should still fail + assert not model.keys_in_environment + + finally: + # Restore original environment + os.environ.clear() + os.environ.update(original_env) diff --git a/tests/basic/test_coder.py b/tests/basic/test_coder.py index ba24e7081..8fa5d6426 100644 --- a/tests/basic/test_coder.py +++ b/tests/basic/test_coder.py @@ -37,7 +37,9 @@ class TestCoder(unittest.TestCase): repo.git.commit("-m", "init") # YES! - io = InputOutput(yes=True) + # Use a completely mocked IO object instead of a real one + io = MagicMock() + io.confirm_ask = MagicMock(return_value=True) coder = Coder.create(self.GPT35, None, io, fnames=["added.txt"]) self.assertTrue(coder.allowed_to_edit("added.txt")) @@ -283,6 +285,87 @@ class TestCoder(unittest.TestCase): self.assertEqual(coder.abs_fnames, set([str(fname.resolve())])) + def test_get_file_mentions_various_formats(self): + with GitTemporaryDirectory(): + io = InputOutput(pretty=False, yes=True) + coder = Coder.create(self.GPT35, None, io) + + # Create test files + test_files = [ + "file1.txt", + "file2.py", + "dir/nested_file.js", + "dir/subdir/deep_file.html", + "file99.txt", + "special_chars!@#.md", + ] + + # Pre-format the Windows path to avoid backslash issues in f-string expressions + windows_path = test_files[2].replace("/", "\\") + win_path3 = test_files[3].replace("/", "\\") + + for fname in test_files: + fpath = Path(fname) + fpath.parent.mkdir(parents=True, exist_ok=True) + fpath.touch() + + # Mock get_addable_relative_files to return our test files + coder.get_addable_relative_files = MagicMock(return_value=set(test_files)) + + # Test different mention formats + test_cases = [ + # Simple plain text mentions + (f"You should edit {test_files[0]} first", {test_files[0]}), + # Multiple files in plain text + (f"Edit both {test_files[0]} and {test_files[1]}", {test_files[0], test_files[1]}), + # Files in backticks + (f"Check the file `{test_files[2]}`", {test_files[2]}), + # Files in code blocks + (f"```\n{test_files[3]}\n```", {test_files[3]}), + # Files in code blocks with language specifier + # ( + # f"```python\nwith open('{test_files[1]}', 'r') as f:\n" + # f" data = f.read()\n```", + # {test_files[1]}, + # ), + # Files with Windows-style paths + (f"Edit the file {windows_path}", {test_files[2]}), + # Files with different quote styles + (f'Check "{test_files[5]}" now', {test_files[5]}), + # All files in one complex message + ( + ( + f"First, edit `{test_files[0]}`. Then modify {test_files[1]}.\n" + f"```js\n// Update this file\nconst file = '{test_files[2]}';\n```\n" + f"Finally check {win_path3}" + ), + {test_files[0], test_files[1], test_files[2], test_files[3]}, + ), + # Files mentioned in markdown bold format + (f"You should check **{test_files[0]}** for issues", {test_files[0]}), + ( + f"Look at both **{test_files[1]}** and **{test_files[2]}**", + {test_files[1], test_files[2]}, + ), + ( + f"The file **{win_path3}** needs updating", + {test_files[3]}, + ), + ( + f"Files to modify:\n- **{test_files[0]}**\n- **{test_files[4]}**", + {test_files[0], test_files[4]}, + ), + ] + + for content, expected_mentions in test_cases: + with self.subTest(content=content): + mentioned_files = coder.get_file_mentions(content) + self.assertEqual( + mentioned_files, + expected_mentions, + f"Failed to extract mentions from: {content}", + ) + def test_get_file_mentions_path_formats(self): with GitTemporaryDirectory(): io = InputOutput(pretty=False, yes=True) @@ -1059,6 +1142,112 @@ This command will print 'Hello, World!' to the console.""" sanity_check_messages(coder.cur_messages) self.assertEqual(coder.cur_messages[-1]["role"], "assistant") + def test_architect_coder_auto_accept_true(self): + with GitTemporaryDirectory(): + io = InputOutput(yes=True) + io.confirm_ask = MagicMock(return_value=True) + + # Create an ArchitectCoder with auto_accept_architect=True + with patch("aider.coders.architect_coder.AskCoder.__init__", return_value=None): + from aider.coders.architect_coder import ArchitectCoder + + coder = ArchitectCoder() + coder.io = io + coder.main_model = self.GPT35 + coder.auto_accept_architect = True + coder.verbose = False + coder.total_cost = 0 + coder.cur_messages = [] + coder.done_messages = [] + coder.summarizer = MagicMock() + coder.summarizer.too_big.return_value = False + + # Mock editor_coder creation and execution + mock_editor = MagicMock() + with patch("aider.coders.architect_coder.Coder.create", return_value=mock_editor): + # Set partial response content + coder.partial_response_content = "Make these changes to the code" + + # Call reply_completed + coder.reply_completed() + + # Verify that confirm_ask was not called (auto-accepted) + io.confirm_ask.assert_not_called() + + # Verify that editor coder was created and run + mock_editor.run.assert_called_once() + + def test_architect_coder_auto_accept_false_confirmed(self): + with GitTemporaryDirectory(): + io = InputOutput(yes=False) + io.confirm_ask = MagicMock(return_value=True) + + # Create an ArchitectCoder with auto_accept_architect=False + with patch("aider.coders.architect_coder.AskCoder.__init__", return_value=None): + from aider.coders.architect_coder import ArchitectCoder + + coder = ArchitectCoder() + coder.io = io + coder.main_model = self.GPT35 + coder.auto_accept_architect = False + coder.verbose = False + coder.total_cost = 0 + coder.cur_messages = [] + coder.done_messages = [] + coder.summarizer = MagicMock() + coder.summarizer.too_big.return_value = False + coder.cur_messages = [] + coder.done_messages = [] + coder.summarizer = MagicMock() + coder.summarizer.too_big.return_value = False + + # Mock editor_coder creation and execution + mock_editor = MagicMock() + with patch("aider.coders.architect_coder.Coder.create", return_value=mock_editor): + # Set partial response content + coder.partial_response_content = "Make these changes to the code" + + # Call reply_completed + coder.reply_completed() + + # Verify that confirm_ask was called + io.confirm_ask.assert_called_once_with("Edit the files?") + + # Verify that editor coder was created and run + mock_editor.run.assert_called_once() + + def test_architect_coder_auto_accept_false_rejected(self): + with GitTemporaryDirectory(): + io = InputOutput(yes=False) + io.confirm_ask = MagicMock(return_value=False) + + # Create an ArchitectCoder with auto_accept_architect=False + with patch("aider.coders.architect_coder.AskCoder.__init__", return_value=None): + from aider.coders.architect_coder import ArchitectCoder + + coder = ArchitectCoder() + coder.io = io + coder.main_model = self.GPT35 + coder.auto_accept_architect = False + coder.verbose = False + coder.total_cost = 0 + + # Mock editor_coder creation and execution + mock_editor = MagicMock() + with patch("aider.coders.architect_coder.Coder.create", return_value=mock_editor): + # Set partial response content + coder.partial_response_content = "Make these changes to the code" + + # Call reply_completed + coder.reply_completed() + + # Verify that confirm_ask was called + io.confirm_ask.assert_called_once_with("Edit the files?") + + # Verify that editor coder was NOT created or run + # (because user rejected the changes) + mock_editor.run.assert_not_called() + if __name__ == "__main__": unittest.main() diff --git a/tests/basic/test_commands.py b/tests/basic/test_commands.py index a234c9b1d..154b32885 100644 --- a/tests/basic/test_commands.py +++ b/tests/basic/test_commands.py @@ -1283,6 +1283,38 @@ class TestCommands(TestCase): # Verify the file was not added self.assertEqual(len(coder.abs_fnames), 0) + def test_cmd_think_tokens(self): + io = InputOutput(pretty=False, fancy_input=False, yes=True) + coder = Coder.create(self.GPT35, None, io) + commands = Commands(io, coder) + + # Test with various formats + test_values = { + "8k": 8192, # 8 * 1024 + "10.5k": 10752, # 10.5 * 1024 + "512k": 524288, # 0.5 * 1024 * 1024 + } + + for input_value, expected_tokens in test_values.items(): + with mock.patch.object(io, "tool_output") as mock_tool_output: + commands.cmd_think_tokens(input_value) + + # Check that the model's thinking tokens were updated + self.assertEqual( + coder.main_model.extra_params["thinking"]["budget_tokens"], expected_tokens + ) + + # Check that the tool output shows the correct value with format + # Use the actual input_value (not normalized) in the assertion + mock_tool_output.assert_any_call( + f"Set thinking token budget to {expected_tokens:,} tokens ({input_value})." + ) + + # Test with no value provided - should display current value + with mock.patch.object(io, "tool_output") as mock_tool_output: + commands.cmd_think_tokens("") + mock_tool_output.assert_any_call(mock.ANY) # Just verify it calls tool_output + def test_cmd_add_aiderignored_file(self): with GitTemporaryDirectory(): repo = git.Repo() @@ -1632,6 +1664,58 @@ class TestCommands(TestCase): self.assertIn("-Further modified content", diff_output) self.assertIn("+Final modified content", diff_output) + def test_cmd_model(self): + io = InputOutput(pretty=False, fancy_input=False, yes=True) + coder = Coder.create(self.GPT35, None, io) + commands = Commands(io, coder) + + # Test switching the main model + with self.assertRaises(SwitchCoder) as context: + commands.cmd_model("gpt-4") + + # Check that the SwitchCoder exception contains the correct model configuration + self.assertEqual(context.exception.kwargs.get("main_model").name, "gpt-4") + self.assertEqual( + context.exception.kwargs.get("main_model").editor_model.name, + self.GPT35.editor_model.name, + ) + self.assertEqual( + context.exception.kwargs.get("main_model").weak_model.name, self.GPT35.weak_model.name + ) + + def test_cmd_editor_model(self): + io = InputOutput(pretty=False, fancy_input=False, yes=True) + coder = Coder.create(self.GPT35, None, io) + commands = Commands(io, coder) + + # Test switching the editor model + with self.assertRaises(SwitchCoder) as context: + commands.cmd_editor_model("gpt-4") + + # Check that the SwitchCoder exception contains the correct model configuration + self.assertEqual(context.exception.kwargs.get("main_model").name, self.GPT35.name) + self.assertEqual(context.exception.kwargs.get("main_model").editor_model.name, "gpt-4") + self.assertEqual( + context.exception.kwargs.get("main_model").weak_model.name, self.GPT35.weak_model.name + ) + + def test_cmd_weak_model(self): + io = InputOutput(pretty=False, fancy_input=False, yes=True) + coder = Coder.create(self.GPT35, None, io) + commands = Commands(io, coder) + + # Test switching the weak model + with self.assertRaises(SwitchCoder) as context: + commands.cmd_weak_model("gpt-4") + + # Check that the SwitchCoder exception contains the correct model configuration + self.assertEqual(context.exception.kwargs.get("main_model").name, self.GPT35.name) + self.assertEqual( + context.exception.kwargs.get("main_model").editor_model.name, + self.GPT35.editor_model.name, + ) + self.assertEqual(context.exception.kwargs.get("main_model").weak_model.name, "gpt-4") + def test_cmd_ask(self): io = InputOutput(pretty=False, fancy_input=False, yes=True) coder = Coder.create(self.GPT35, None, io) @@ -1722,6 +1806,213 @@ class TestCommands(TestCase): del coder del commands + def test_reset_with_original_read_only_files(self): + with GitTemporaryDirectory() as repo_dir: + io = InputOutput(pretty=False, fancy_input=False, yes=True) + coder = Coder.create(self.GPT35, None, io) + + # Create test files + orig_read_only = Path(repo_dir) / "orig_read_only.txt" + orig_read_only.write_text("Original read-only file") + + added_file = Path(repo_dir) / "added_file.txt" + added_file.write_text("Added file") + + added_read_only = Path(repo_dir) / "added_read_only.txt" + added_read_only.write_text("Added read-only file") + + # Initialize commands with original read-only files + commands = Commands(io, coder, original_read_only_fnames=[str(orig_read_only)]) + + # Add files to the chat + coder.abs_read_only_fnames.add(str(orig_read_only)) + coder.abs_fnames.add(str(added_file)) + coder.abs_read_only_fnames.add(str(added_read_only)) + + # Add some messages to the chat history + coder.cur_messages = [{"role": "user", "content": "Test message"}] + coder.done_messages = [{"role": "assistant", "content": "Test response"}] + + # Verify initial state + self.assertEqual(len(coder.abs_fnames), 1) + self.assertEqual(len(coder.abs_read_only_fnames), 2) + self.assertEqual(len(coder.cur_messages), 1) + self.assertEqual(len(coder.done_messages), 1) + + # Test reset command + commands.cmd_reset("") + + # Verify that original read-only file is preserved + # but other files and messages are cleared + self.assertEqual(len(coder.abs_fnames), 0) + self.assertEqual(len(coder.abs_read_only_fnames), 1) + self.assertIn(str(orig_read_only), coder.abs_read_only_fnames) + self.assertNotIn(str(added_read_only), coder.abs_read_only_fnames) + + # Chat history should be cleared + self.assertEqual(len(coder.cur_messages), 0) + self.assertEqual(len(coder.done_messages), 0) + + def test_reset_with_no_original_read_only_files(self): + with GitTemporaryDirectory() as repo_dir: + io = InputOutput(pretty=False, fancy_input=False, yes=True) + coder = Coder.create(self.GPT35, None, io) + + # Create test files + added_file = Path(repo_dir) / "added_file.txt" + added_file.write_text("Added file") + + added_read_only = Path(repo_dir) / "added_read_only.txt" + added_read_only.write_text("Added read-only file") + + # Initialize commands with no original read-only files + commands = Commands(io, coder) + + # Add files to the chat + coder.abs_fnames.add(str(added_file)) + coder.abs_read_only_fnames.add(str(added_read_only)) + + # Add some messages to the chat history + coder.cur_messages = [{"role": "user", "content": "Test message"}] + coder.done_messages = [{"role": "assistant", "content": "Test response"}] + + # Verify initial state + self.assertEqual(len(coder.abs_fnames), 1) + self.assertEqual(len(coder.abs_read_only_fnames), 1) + self.assertEqual(len(coder.cur_messages), 1) + self.assertEqual(len(coder.done_messages), 1) + + # Test reset command + commands.cmd_reset("") + + # Verify that all files and messages are cleared + self.assertEqual(len(coder.abs_fnames), 0) + self.assertEqual(len(coder.abs_read_only_fnames), 0) + self.assertEqual(len(coder.cur_messages), 0) + self.assertEqual(len(coder.done_messages), 0) + + def test_cmd_reasoning_effort(self): + io = InputOutput(pretty=False, fancy_input=False, yes=True) + coder = Coder.create(self.GPT35, None, io) + commands = Commands(io, coder) + + # Test with numeric values + with mock.patch.object(io, "tool_output") as mock_tool_output: + commands.cmd_reasoning_effort("0.8") + mock_tool_output.assert_any_call("Set reasoning effort to 0.8") + + # Test with text values (low/medium/high) + for effort_level in ["low", "medium", "high"]: + with mock.patch.object(io, "tool_output") as mock_tool_output: + commands.cmd_reasoning_effort(effort_level) + mock_tool_output.assert_any_call(f"Set reasoning effort to {effort_level}") + + # Check model's reasoning effort was updated + with mock.patch.object(coder.main_model, "set_reasoning_effort") as mock_set_effort: + commands.cmd_reasoning_effort("0.5") + mock_set_effort.assert_called_once_with("0.5") + + # Test with no value provided - should display current value + with mock.patch.object(io, "tool_output") as mock_tool_output: + commands.cmd_reasoning_effort("") + mock_tool_output.assert_any_call("Current reasoning effort: high") + + def test_drop_with_original_read_only_files(self): + with GitTemporaryDirectory() as repo_dir: + io = InputOutput(pretty=False, fancy_input=False, yes=True) + coder = Coder.create(self.GPT35, None, io) + + # Create test files + orig_read_only = Path(repo_dir) / "orig_read_only.txt" + orig_read_only.write_text("Original read-only file") + + added_file = Path(repo_dir) / "added_file.txt" + added_file.write_text("Added file") + + added_read_only = Path(repo_dir) / "added_read_only.txt" + added_read_only.write_text("Added read-only file") + + # Initialize commands with original read-only files + commands = Commands(io, coder, original_read_only_fnames=[str(orig_read_only)]) + + # Add files to the chat + coder.abs_read_only_fnames.add(str(orig_read_only)) + coder.abs_fnames.add(str(added_file)) + coder.abs_read_only_fnames.add(str(added_read_only)) + + # Verify initial state + self.assertEqual(len(coder.abs_fnames), 1) + self.assertEqual(len(coder.abs_read_only_fnames), 2) + + # Test bare drop command + with mock.patch.object(io, "tool_output") as mock_tool_output: + commands.cmd_drop("") + mock_tool_output.assert_called_with( + "Dropping all files from the chat session except originally read-only files." + ) + + # Verify that original read-only file is preserved, but other files are dropped + self.assertEqual(len(coder.abs_fnames), 0) + self.assertEqual(len(coder.abs_read_only_fnames), 1) + self.assertIn(str(orig_read_only), coder.abs_read_only_fnames) + self.assertNotIn(str(added_read_only), coder.abs_read_only_fnames) + + def test_drop_specific_original_read_only_file(self): + with GitTemporaryDirectory() as repo_dir: + io = InputOutput(pretty=False, fancy_input=False, yes=True) + coder = Coder.create(self.GPT35, None, io) + + # Create test file + orig_read_only = Path(repo_dir) / "orig_read_only.txt" + orig_read_only.write_text("Original read-only file") + + # Initialize commands with original read-only files + commands = Commands(io, coder, original_read_only_fnames=[str(orig_read_only)]) + + # Add file to the chat + coder.abs_read_only_fnames.add(str(orig_read_only)) + + # Verify initial state + self.assertEqual(len(coder.abs_read_only_fnames), 1) + + # Test specific drop command + commands.cmd_drop("orig_read_only.txt") + + # Verify that the original read-only file is dropped when specified explicitly + self.assertEqual(len(coder.abs_read_only_fnames), 0) + + def test_drop_with_no_original_read_only_files(self): + with GitTemporaryDirectory() as repo_dir: + io = InputOutput(pretty=False, fancy_input=False, yes=True) + coder = Coder.create(self.GPT35, None, io) + + # Create test files + added_file = Path(repo_dir) / "added_file.txt" + added_file.write_text("Added file") + + added_read_only = Path(repo_dir) / "added_read_only.txt" + added_read_only.write_text("Added read-only file") + + # Initialize commands with no original read-only files + commands = Commands(io, coder) + + # Add files to the chat + coder.abs_fnames.add(str(added_file)) + coder.abs_read_only_fnames.add(str(added_read_only)) + + # Verify initial state + self.assertEqual(len(coder.abs_fnames), 1) + self.assertEqual(len(coder.abs_read_only_fnames), 1) + + # Test bare drop command + with mock.patch.object(io, "tool_output") as mock_tool_output: + commands.cmd_drop("") + mock_tool_output.assert_called_with("Dropping all files from the chat session.") + + # Verify that all files are dropped + self.assertEqual(len(coder.abs_fnames), 0) + self.assertEqual(len(coder.abs_read_only_fnames), 0) + def test_cmd_load_with_switch_coder(self): with GitTemporaryDirectory() as repo_dir: io = InputOutput(pretty=False, fancy_input=False, yes=True) diff --git a/tests/basic/test_deprecated.py b/tests/basic/test_deprecated.py new file mode 100644 index 000000000..62f9b2ada --- /dev/null +++ b/tests/basic/test_deprecated.py @@ -0,0 +1,140 @@ +import os +from unittest import TestCase +from unittest.mock import MagicMock, patch + +from prompt_toolkit.input import DummyInput +from prompt_toolkit.output import DummyOutput + +from aider.deprecated import handle_deprecated_model_args +from aider.dump import dump # noqa +from aider.main import main + + +class TestDeprecated(TestCase): + def setUp(self): + self.original_env = os.environ.copy() + os.environ["OPENAI_API_KEY"] = "deadbeef" + os.environ["AIDER_CHECK_UPDATE"] = "false" + os.environ["AIDER_ANALYTICS"] = "false" + + def tearDown(self): + os.environ.clear() + os.environ.update(self.original_env) + + @patch("aider.io.InputOutput.tool_warning") + @patch("aider.io.InputOutput.offer_url") + def test_deprecated_args_show_warnings(self, mock_offer_url, mock_tool_warning): + # Prevent URL launches during tests + mock_offer_url.return_value = False + # Test all deprecated flags to ensure they show warnings + deprecated_flags = [ + "--opus", + "--sonnet", + "--haiku", + "--4", + "-4", + "--4o", + "--mini", + "--4-turbo", + "--35turbo", + "--35-turbo", + "--3", + "-3", + "--deepseek", + "--o1-mini", + "--o1-preview", + ] + + for flag in deprecated_flags: + mock_tool_warning.reset_mock() + + with patch("aider.models.Model"), self.subTest(flag=flag): + main( + [flag, "--no-git", "--exit", "--yes"], input=DummyInput(), output=DummyOutput() + ) + + # Look for the deprecation warning in all calls + deprecation_warning = None + dump(flag) + dump(mock_tool_warning.call_args_list) + for call_args in mock_tool_warning.call_args_list: + dump(call_args) + if "deprecated" in call_args[0][0]: + deprecation_warning = call_args[0][0] + break + + self.assertIsNotNone( + deprecation_warning, f"No deprecation warning found for {flag}" + ) + warning_msg = deprecation_warning + + self.assertIn("deprecated", warning_msg) + self.assertIn("use --model", warning_msg.lower()) + + @patch("aider.io.InputOutput.tool_warning") + @patch("aider.io.InputOutput.offer_url") + def test_model_alias_in_warning(self, mock_offer_url, mock_tool_warning): + # Prevent URL launches during tests + mock_offer_url.return_value = False + # Test that the warning uses the model alias if available + with patch("aider.models.MODEL_ALIASES", {"gpt4": "gpt-4-0613"}): + with patch("aider.models.Model"): + main( + ["--4", "--no-git", "--exit", "--yes"], input=DummyInput(), output=DummyOutput() + ) + + # Look for the deprecation warning in all calls + deprecation_warning = None + for call_args in mock_tool_warning.call_args_list: + if "deprecated" in call_args[0][0] and "--model gpt4" in call_args[0][0]: + deprecation_warning = call_args[0][0] + break + + self.assertIsNotNone( + deprecation_warning, "No deprecation warning with model alias found" + ) + warning_msg = deprecation_warning + self.assertIn("--model gpt4", warning_msg) + self.assertNotIn("--model gpt-4-0613", warning_msg) + + def test_model_is_set_correctly(self): + test_cases = [ + ("opus", "claude-3-opus-20240229"), + ("sonnet", "anthropic/claude-3-7-sonnet-20250219"), + ("haiku", "claude-3-5-haiku-20241022"), + ("4", "gpt-4-0613"), + # Testing the dash variant with underscore in attribute name + ("4o", "gpt-4o"), + ("mini", "gpt-4o-mini"), + ("4_turbo", "gpt-4-1106-preview"), + ("35turbo", "gpt-3.5-turbo"), + ("deepseek", "deepseek/deepseek-chat"), + ("o1_mini", "o1-mini"), + ("o1_preview", "o1-preview"), + ] + + for flag, expected_model in test_cases: + print(flag, expected_model) + + with self.subTest(flag=flag): + # Create a mock IO instance + mock_io = MagicMock() + + # Create args with ONLY the current flag set to True + args = MagicMock() + args.model = None + + # Ensure all flags are False by default + for test_flag, _ in test_cases: + setattr(args, test_flag, False) + + # Set only the current flag to True + setattr(args, flag, True) + + dump(args) + + # Call the handle_deprecated_model_args function + handle_deprecated_model_args(args, mock_io) + + # Check that args.model was set to the expected model + self.assertEqual(args.model, expected_model) diff --git a/tests/basic/test_exceptions.py b/tests/basic/test_exceptions.py index f9262a665..7a335133d 100644 --- a/tests/basic/test_exceptions.py +++ b/tests/basic/test_exceptions.py @@ -63,3 +63,20 @@ def test_context_window_error(): ) ex_info = ex.get_ex_info(ctx_error) assert ex_info.retry is False + + +def test_openrouter_error(): + """Test specific handling of OpenRouter API errors""" + ex = LiteLLMExceptions() + from litellm import APIConnectionError + + # Create an APIConnectionError with OpenrouterException message + openrouter_error = APIConnectionError( + message="APIConnectionError: OpenrouterException - 'choices'", + model="openrouter/model", + llm_provider="openrouter", + ) + + ex_info = ex.get_ex_info(openrouter_error) + assert ex_info.retry is True + assert "OpenRouter API provider is down" in ex_info.description diff --git a/tests/basic/test_main.py b/tests/basic/test_main.py index 47e8f256f..a6dead0ff 100644 --- a/tests/basic/test_main.py +++ b/tests/basic/test_main.py @@ -684,6 +684,94 @@ class TestMain(TestCase): ) self.assertTrue(coder.detect_urls) + def test_accepts_settings_warnings(self): + # Test that appropriate warnings are shown based on accepts_settings configuration + with GitTemporaryDirectory(): + # Test model that accepts the thinking_tokens setting + with ( + patch("aider.io.InputOutput.tool_warning") as mock_warning, + patch("aider.models.Model.set_thinking_tokens") as mock_set_thinking, + ): + main( + [ + "--model", + "anthropic/claude-3-7-sonnet-20250219", + "--thinking-tokens", + "1000", + "--yes", + "--exit", + ], + input=DummyInput(), + output=DummyOutput(), + ) + # No warning should be shown as this model accepts thinking_tokens + for call in mock_warning.call_args_list: + self.assertNotIn("thinking_tokens", call[0][0]) + # Method should be called + mock_set_thinking.assert_called_once_with("1000") + + # Test model that doesn't have accepts_settings for thinking_tokens + with ( + patch("aider.io.InputOutput.tool_warning") as mock_warning, + patch("aider.models.Model.set_thinking_tokens") as mock_set_thinking, + ): + main( + [ + "--model", + "gpt-4o", + "--thinking-tokens", + "1000", + "--check-model-accepts-settings", + "--yes", + "--exit", + ], + input=DummyInput(), + output=DummyOutput(), + ) + # Warning should be shown + warning_shown = False + for call in mock_warning.call_args_list: + if "thinking_tokens" in call[0][0]: + warning_shown = True + self.assertTrue(warning_shown) + # Method should NOT be called because model doesn't support it and check flag is on + mock_set_thinking.assert_not_called() + + # Test model that accepts the reasoning_effort setting + with ( + patch("aider.io.InputOutput.tool_warning") as mock_warning, + patch("aider.models.Model.set_reasoning_effort") as mock_set_reasoning, + ): + main( + ["--model", "o1", "--reasoning-effort", "3", "--yes", "--exit"], + input=DummyInput(), + output=DummyOutput(), + ) + # No warning should be shown as this model accepts reasoning_effort + for call in mock_warning.call_args_list: + self.assertNotIn("reasoning_effort", call[0][0]) + # Method should be called + mock_set_reasoning.assert_called_once_with("3") + + # Test model that doesn't have accepts_settings for reasoning_effort + with ( + patch("aider.io.InputOutput.tool_warning") as mock_warning, + patch("aider.models.Model.set_reasoning_effort") as mock_set_reasoning, + ): + main( + ["--model", "gpt-3.5-turbo", "--reasoning-effort", "3", "--yes", "--exit"], + input=DummyInput(), + output=DummyOutput(), + ) + # Warning should be shown + warning_shown = False + for call in mock_warning.call_args_list: + if "reasoning_effort" in call[0][0]: + warning_shown = True + self.assertTrue(warning_shown) + # Method should still be called by default + mock_set_reasoning.assert_not_called() + @patch("aider.models.ModelInfoManager.set_verify_ssl") def test_no_verify_ssl_sets_model_info_manager(self, mock_set_verify_ssl): with GitTemporaryDirectory(): @@ -840,6 +928,25 @@ class TestMain(TestCase): self.assertEqual(repo.git.config("user.name"), "Directive User") self.assertEqual(repo.git.config("user.email"), "directive@example.com") + def test_resolve_aiderignore_path(self): + # Import the function directly to test it + from aider.args import resolve_aiderignore_path + + # Test with absolute path + abs_path = os.path.abspath("/tmp/test/.aiderignore") + self.assertEqual(resolve_aiderignore_path(abs_path), abs_path) + + # Test with relative path and git root + git_root = "/path/to/git/root" + rel_path = ".aiderignore" + self.assertEqual( + resolve_aiderignore_path(rel_path, git_root), str(Path(git_root) / rel_path) + ) + + # Test with relative path and no git root + rel_path = ".aiderignore" + self.assertEqual(resolve_aiderignore_path(rel_path), rel_path) + def test_invalid_edit_format(self): with GitTemporaryDirectory(): with patch("aider.io.InputOutput.offer_url") as mock_offer_url: @@ -876,7 +983,7 @@ class TestMain(TestCase): coder = main( ["--exit", "--yes"], input=DummyInput(), output=DummyOutput(), return_coder=True ) - self.assertIn("openrouter/anthropic/claude", coder.main_model.name.lower()) + self.assertIn("openrouter/", coder.main_model.name.lower()) del os.environ["OPENROUTER_API_KEY"] # Test OpenAI API key @@ -892,7 +999,7 @@ class TestMain(TestCase): coder = main( ["--exit", "--yes"], input=DummyInput(), output=DummyOutput(), return_coder=True ) - self.assertIn("flash", coder.main_model.name.lower()) + self.assertIn("gemini", coder.main_model.name.lower()) del os.environ["GEMINI_API_KEY"] # Test no API keys @@ -935,7 +1042,7 @@ class TestMain(TestCase): def test_reasoning_effort_option(self): coder = main( - ["--reasoning-effort", "3", "--yes", "--exit"], + ["--reasoning-effort", "3", "--no-check-model-accepts-settings", "--yes", "--exit"], input=DummyInput(), output=DummyOutput(), return_coder=True, @@ -943,3 +1050,199 @@ class TestMain(TestCase): self.assertEqual( coder.main_model.extra_params.get("extra_body", {}).get("reasoning_effort"), "3" ) + + def test_thinking_tokens_option(self): + coder = main( + ["--model", "sonnet", "--thinking-tokens", "1000", "--yes", "--exit"], + input=DummyInput(), + output=DummyOutput(), + return_coder=True, + ) + self.assertEqual( + coder.main_model.extra_params.get("thinking", {}).get("budget_tokens"), 1000 + ) + + def test_list_models_includes_metadata_models(self): + # Test that models from model-metadata.json appear in list-models output + with GitTemporaryDirectory(): + # Create a temporary model-metadata.json with test models + metadata_file = Path(".aider.model.metadata.json") + test_models = { + "unique-model-name": { + "max_input_tokens": 8192, + "litellm_provider": "test-provider", + "mode": "chat", # Added mode attribute + }, + "another-provider/another-unique-model": { + "max_input_tokens": 4096, + "litellm_provider": "another-provider", + "mode": "chat", # Added mode attribute + }, + } + metadata_file.write_text(json.dumps(test_models)) + + # Capture stdout to check the output + with patch("sys.stdout", new_callable=StringIO) as mock_stdout: + main( + [ + "--list-models", + "unique-model", + "--model-metadata-file", + str(metadata_file), + "--yes", + "--no-gitignore", + ], + input=DummyInput(), + output=DummyOutput(), + ) + output = mock_stdout.getvalue() + + # Check that the unique model name from our metadata file is listed + self.assertIn("test-provider/unique-model-name", output) + + def test_list_models_includes_all_model_sources(self): + # Test that models from both litellm.model_cost and model-metadata.json + # appear in list-models + with GitTemporaryDirectory(): + # Create a temporary model-metadata.json with test models + metadata_file = Path(".aider.model.metadata.json") + test_models = { + "metadata-only-model": { + "max_input_tokens": 8192, + "litellm_provider": "test-provider", + "mode": "chat", # Added mode attribute + } + } + metadata_file.write_text(json.dumps(test_models)) + + # Capture stdout to check the output + with patch("sys.stdout", new_callable=StringIO) as mock_stdout: + main( + [ + "--list-models", + "metadata-only-model", + "--model-metadata-file", + str(metadata_file), + "--yes", + "--no-gitignore", + ], + input=DummyInput(), + output=DummyOutput(), + ) + output = mock_stdout.getvalue() + + dump(output) + + # Check that both models appear in the output + self.assertIn("test-provider/metadata-only-model", output) + + def test_check_model_accepts_settings_flag(self): + # Test that --check-model-accepts-settings affects whether settings are applied + with GitTemporaryDirectory(): + # When flag is on, setting shouldn't be applied to non-supporting model + with patch("aider.models.Model.set_thinking_tokens") as mock_set_thinking: + main( + [ + "--model", + "gpt-4o", + "--thinking-tokens", + "1000", + "--check-model-accepts-settings", + "--yes", + "--exit", + ], + input=DummyInput(), + output=DummyOutput(), + ) + # Method should not be called because model doesn't support it and flag is on + mock_set_thinking.assert_not_called() + + def test_list_models_with_direct_resource_patch(self): + # Test that models from resources/model-metadata.json are included in list-models output + with GitTemporaryDirectory(): + # Create a temporary file with test model metadata + test_file = Path(self.tempdir) / "test-model-metadata.json" + test_resource_models = { + "special-model": { + "max_input_tokens": 8192, + "litellm_provider": "resource-provider", + "mode": "chat", + } + } + test_file.write_text(json.dumps(test_resource_models)) + + # Create a mock for the resource file path + mock_resource_path = MagicMock() + mock_resource_path.__str__.return_value = str(test_file) + + # Create a mock for the files function that returns an object with joinpath + mock_files = MagicMock() + mock_files.joinpath.return_value = mock_resource_path + + with patch("aider.main.importlib_resources.files", return_value=mock_files): + # Capture stdout to check the output + with patch("sys.stdout", new_callable=StringIO) as mock_stdout: + main( + ["--list-models", "special", "--yes", "--no-gitignore"], + input=DummyInput(), + output=DummyOutput(), + ) + output = mock_stdout.getvalue() + + # Check that the resource model appears in the output + self.assertIn("resource-provider/special-model", output) + + # When flag is off, setting should be applied regardless of support + with patch("aider.models.Model.set_reasoning_effort") as mock_set_reasoning: + main( + [ + "--model", + "gpt-3.5-turbo", + "--reasoning-effort", + "3", + "--no-check-model-accepts-settings", + "--yes", + "--exit", + ], + input=DummyInput(), + output=DummyOutput(), + ) + # Method should be called because flag is off + mock_set_reasoning.assert_called_once_with("3") + + def test_model_accepts_settings_attribute(self): + with GitTemporaryDirectory(): + # Test with a model where we override the accepts_settings attribute + with patch("aider.models.Model") as MockModel: + # Setup mock model instance to simulate accepts_settings attribute + mock_instance = MockModel.return_value + mock_instance.name = "test-model" + mock_instance.accepts_settings = ["reasoning_effort"] + mock_instance.validate_environment.return_value = { + "missing_keys": [], + "keys_in_environment": [], + } + mock_instance.info = {} + mock_instance.weak_model_name = None + mock_instance.get_weak_model.return_value = None + + # Run with both settings, but model only accepts reasoning_effort + main( + [ + "--model", + "test-model", + "--reasoning-effort", + "3", + "--thinking-tokens", + "1000", + "--check-model-accepts-settings", + "--yes", + "--exit", + ], + input=DummyInput(), + output=DummyOutput(), + ) + + # Only set_reasoning_effort should be called, not set_thinking_tokens + mock_instance.set_reasoning_effort.assert_called_once_with("3") + mock_instance.set_thinking_tokens.assert_not_called() diff --git a/tests/basic/test_models.py b/tests/basic/test_models.py index 355ddeef1..b4fbfc239 100644 --- a/tests/basic/test_models.py +++ b/tests/basic/test_models.py @@ -160,6 +160,51 @@ class TestModels(unittest.TestCase): self.assertEqual(model.name, "github/o1-preview") self.assertEqual(model.use_temperature, False) + def test_parse_token_value(self): + # Create a model instance to test the parse_token_value method + model = Model("gpt-4") + + # Test integer inputs + self.assertEqual(model.parse_token_value(8096), 8096) + self.assertEqual(model.parse_token_value(1000), 1000) + + # Test string inputs + self.assertEqual(model.parse_token_value("8096"), 8096) + + # Test k/K suffix (kilobytes) + self.assertEqual(model.parse_token_value("8k"), 8 * 1024) + self.assertEqual(model.parse_token_value("8K"), 8 * 1024) + self.assertEqual(model.parse_token_value("10.5k"), 10.5 * 1024) + self.assertEqual(model.parse_token_value("0.5K"), 0.5 * 1024) + + # Test m/M suffix (megabytes) + self.assertEqual(model.parse_token_value("1m"), 1 * 1024 * 1024) + self.assertEqual(model.parse_token_value("1M"), 1 * 1024 * 1024) + self.assertEqual(model.parse_token_value("0.5M"), 0.5 * 1024 * 1024) + + # Test with spaces + self.assertEqual(model.parse_token_value(" 8k "), 8 * 1024) + + # Test conversion from other types + self.assertEqual(model.parse_token_value(8.0), 8) + + def test_set_thinking_tokens(self): + # Test that set_thinking_tokens correctly sets the tokens with different formats + model = Model("gpt-4") + + # Test with integer + model.set_thinking_tokens(8096) + self.assertEqual(model.extra_params["thinking"]["budget_tokens"], 8096) + self.assertFalse(model.use_temperature) + + # Test with string + model.set_thinking_tokens("10k") + self.assertEqual(model.extra_params["thinking"]["budget_tokens"], 10 * 1024) + + # Test with decimal value + model.set_thinking_tokens("0.5M") + self.assertEqual(model.extra_params["thinking"]["budget_tokens"], 0.5 * 1024 * 1024) + @patch("aider.models.check_pip_install_extra") def test_check_for_dependencies_bedrock(self, mock_check_pip): """Test that check_for_dependencies calls check_pip_install_extra for Bedrock models""" @@ -277,7 +322,7 @@ class TestModels(unittest.TestCase): self.assertTrue(model.use_repo_map) self.assertTrue(model.examples_as_sys_msg) self.assertFalse(model.use_temperature) - self.assertEqual(model.remove_reasoning, "think") + self.assertEqual(model.reasoning_tag, "think") # Test provider/deepseek-r1 case model = Model("someprovider/deepseek-r1") @@ -285,7 +330,7 @@ class TestModels(unittest.TestCase): self.assertTrue(model.use_repo_map) self.assertTrue(model.examples_as_sys_msg) self.assertFalse(model.use_temperature) - self.assertEqual(model.remove_reasoning, "think") + self.assertEqual(model.reasoning_tag, "think") # Test provider/deepseek-v3 case model = Model("anotherprovider/deepseek-v3") diff --git a/tests/basic/test_reasoning.py b/tests/basic/test_reasoning.py index bb6d6ce43..0386f29bc 100644 --- a/tests/basic/test_reasoning.py +++ b/tests/basic/test_reasoning.py @@ -5,7 +5,11 @@ from aider.coders.base_coder import Coder from aider.dump import dump # noqa from aider.io import InputOutput from aider.models import Model -from aider.reasoning_tags import remove_reasoning_content +from aider.reasoning_tags import ( + REASONING_END, + REASONING_START, + remove_reasoning_content, +) class TestReasoning(unittest.TestCase): @@ -52,8 +56,8 @@ class TestReasoning(unittest.TestCase): dump(output) # Output should contain formatted reasoning tags - self.assertIn("Thinking ...", output) - self.assertIn("... done thinking", output) + self.assertIn(REASONING_START, output) + self.assertIn(REASONING_END, output) # Output should include both reasoning and main content self.assertIn(reasoning_content, output) @@ -86,7 +90,9 @@ class TestReasoning(unittest.TestCase): # Mock streaming response chunks class MockStreamingChunk: - def __init__(self, content=None, reasoning_content=None, finish_reason=None): + def __init__( + self, content=None, reasoning_content=None, reasoning=None, finish_reason=None + ): self.choices = [MagicMock()] self.choices[0].delta = MagicMock() self.choices[0].finish_reason = finish_reason @@ -105,6 +111,13 @@ class TestReasoning(unittest.TestCase): # Need to handle attribute access that would raise AttributeError delattr(self.choices[0].delta, "reasoning_content") + # Set reasoning if provided + if reasoning is not None: + self.choices[0].delta.reasoning = reasoning + else: + # Need to handle attribute access that would raise AttributeError + delattr(self.choices[0].delta, "reasoning") + # Create chunks to simulate streaming chunks = [ # First chunk with reasoning content starts the tag @@ -157,9 +170,9 @@ class TestReasoning(unittest.TestCase): final_text = update_calls[-1][0][0] # The final text should include both reasoning and main content with proper formatting - self.assertIn("> Thinking ...", final_text) + self.assertIn(REASONING_START, final_text) self.assertIn("My step-by-step reasoning process", final_text) - self.assertIn("> ... done thinking", final_text) + self.assertIn(REASONING_END, final_text) self.assertIn("Final answer after reasoning", final_text) # Ensure proper order: reasoning first, then main content @@ -182,7 +195,7 @@ class TestReasoning(unittest.TestCase): # Setup model and coder model = Model("gpt-3.5-turbo") - model.remove_reasoning = "think" # Set to remove tags + model.reasoning_tag = "think" # Set to remove tags coder = Coder.create(model, None, io=io, stream=False) # Test data @@ -225,8 +238,8 @@ class TestReasoning(unittest.TestCase): dump(output) # Output should contain formatted reasoning tags - self.assertIn("Thinking ...", output) - self.assertIn("... done thinking", output) + self.assertIn(REASONING_START, output) + self.assertIn(REASONING_END, output) # Output should include both reasoning and main content self.assertIn(reasoning_content, output) @@ -252,7 +265,7 @@ class TestReasoning(unittest.TestCase): # Setup model and coder model = Model("gpt-3.5-turbo") - model.remove_reasoning = "think" # Set to remove tags + model.reasoning_tag = "think" # Set to remove tags coder = Coder.create(model, None, io=io, stream=True) # Ensure the coder shows pretty output @@ -260,7 +273,9 @@ class TestReasoning(unittest.TestCase): # Mock streaming response chunks class MockStreamingChunk: - def __init__(self, content=None, reasoning_content=None, finish_reason=None): + def __init__( + self, content=None, reasoning_content=None, reasoning=None, finish_reason=None + ): self.choices = [MagicMock()] self.choices[0].delta = MagicMock() self.choices[0].finish_reason = finish_reason @@ -279,6 +294,13 @@ class TestReasoning(unittest.TestCase): # Need to handle attribute access that would raise AttributeError delattr(self.choices[0].delta, "reasoning_content") + # Set reasoning if provided + if reasoning is not None: + self.choices[0].delta.reasoning = reasoning + else: + # Need to handle attribute access that would raise AttributeError + delattr(self.choices[0].delta, "reasoning") + # Create chunks to simulate streaming with think tags chunks = [ # Start with open think tag @@ -330,9 +352,9 @@ class TestReasoning(unittest.TestCase): final_text = update_calls[-1][0][0] # The final text should include both reasoning and main content with proper formatting - self.assertIn("> Thinking ...", final_text) + self.assertIn(REASONING_START, final_text) self.assertIn("My step-by-step reasoning process", final_text) - self.assertIn("> ... done thinking", final_text) + self.assertIn(REASONING_END, final_text) self.assertIn("Final answer after reasoning", final_text) # Ensure proper order: reasoning first, then main content @@ -377,10 +399,190 @@ End""" text = "Just regular text" self.assertEqual(remove_reasoning_content(text, "think"), text) + def test_send_with_reasoning(self): + """Test that reasoning content from the 'reasoning' attribute is properly formatted + and output.""" + # Setup IO with no pretty + io = InputOutput(pretty=False) + io.assistant_output = MagicMock() + + # Setup model and coder + model = Model("gpt-3.5-turbo") + coder = Coder.create(model, None, io=io, stream=False) + + # Test data + reasoning_content = "My step-by-step reasoning process" + main_content = "Final answer after reasoning" + + # Mock completion response with reasoning content + class MockCompletion: + def __init__(self, content, reasoning): + self.content = content + # Add required attributes expected by show_send_output + self.choices = [MagicMock()] + self.choices[0].message.content = content + self.choices[0].message.reasoning = ( + reasoning # Using reasoning instead of reasoning_content + ) + delattr(self.choices[0].message, "reasoning_content") + self.finish_reason = "stop" + + mock_completion = MockCompletion(main_content, reasoning_content) + + # Create a mock hash object + mock_hash = MagicMock() + mock_hash.hexdigest.return_value = "mock_hash_digest" + + # Mock the model's send_completion method to return the expected tuple format + with patch.object(model, "send_completion", return_value=(mock_hash, mock_completion)): + # Call send with a simple message + messages = [{"role": "user", "content": "test prompt"}] + list(coder.send(messages)) + + # Now verify ai_output was called with the right content + io.assistant_output.assert_called_once() + output = io.assistant_output.call_args[0][0] + + dump(output) + + # Output should contain formatted reasoning tags + self.assertIn(REASONING_START, output) + self.assertIn(REASONING_END, output) + + # Output should include both reasoning and main content + self.assertIn(reasoning_content, output) + self.assertIn(main_content, output) + + # Verify that partial_response_content only contains the main content + coder.remove_reasoning_content() + self.assertEqual(coder.partial_response_content.strip(), main_content.strip()) + + # Ensure proper order: reasoning first, then main content + reasoning_pos = output.find(reasoning_content) + main_pos = output.find(main_content) + self.assertLess( + reasoning_pos, main_pos, "Reasoning content should appear before main content" + ) + + def test_send_with_reasoning_stream(self): + """Test that streaming reasoning content from the 'reasoning' attribute is properly + formatted and output.""" + # Setup IO with pretty output for streaming + io = InputOutput(pretty=True) + mock_mdstream = MagicMock() + io.get_assistant_mdstream = MagicMock(return_value=mock_mdstream) + + # Setup model and coder + model = Model("gpt-3.5-turbo") + coder = Coder.create(model, None, io=io, stream=True) + + # Ensure the coder shows pretty output + coder.show_pretty = MagicMock(return_value=True) + + # Mock streaming response chunks + class MockStreamingChunk: + def __init__( + self, content=None, reasoning_content=None, reasoning=None, finish_reason=None + ): + self.choices = [MagicMock()] + self.choices[0].delta = MagicMock() + self.choices[0].finish_reason = finish_reason + + # Set content if provided + if content is not None: + self.choices[0].delta.content = content + else: + # Need to handle attribute access that would raise AttributeError + delattr(self.choices[0].delta, "content") + + # Set reasoning_content if provided + if reasoning_content is not None: + self.choices[0].delta.reasoning_content = reasoning_content + else: + # Need to handle attribute access that would raise AttributeError + delattr(self.choices[0].delta, "reasoning_content") + + # Set reasoning if provided + if reasoning is not None: + self.choices[0].delta.reasoning = reasoning + else: + # Need to handle attribute access that would raise AttributeError + delattr(self.choices[0].delta, "reasoning") + + # Create chunks to simulate streaming - using reasoning attribute instead of + # reasoning_content + chunks = [ + # First chunk with reasoning content starts the tag + MockStreamingChunk(reasoning="My step-by-step "), + # Additional reasoning content + MockStreamingChunk(reasoning="reasoning process"), + # Switch to main content - this will automatically end the reasoning tag + MockStreamingChunk(content="Final "), + # More main content + MockStreamingChunk(content="answer "), + MockStreamingChunk(content="after reasoning"), + # End the response + MockStreamingChunk(finish_reason="stop"), + ] + + # Create a mock hash object + mock_hash = MagicMock() + mock_hash.hexdigest.return_value = "mock_hash_digest" + + # Mock the model's send_completion to return the hash and completion + with ( + patch.object(model, "send_completion", return_value=(mock_hash, chunks)), + patch.object(model, "token_count", return_value=10), + ): # Mock token count to avoid serialization issues + # Set mdstream directly on the coder object + coder.mdstream = mock_mdstream + + # Call send with a simple message + messages = [{"role": "user", "content": "test prompt"}] + list(coder.send(messages)) + + # Verify mdstream.update was called multiple times + mock_mdstream.update.assert_called() + + coder.live_incremental_response(True) + + # Explicitly get all calls to update + update_calls = mock_mdstream.update.call_args_list + + # There should be at least two calls - one for streaming and one final + self.assertGreaterEqual( + len(update_calls), 2, "Should have at least two calls to update (streaming + final)" + ) + + # Check that at least one call has final=True (should be the last one) + has_final_true = any(call[1].get("final", False) for call in update_calls) + self.assertTrue(has_final_true, "At least one update call should have final=True") + + # Get the text from the last update call + final_text = update_calls[-1][0][0] + + # The final text should include both reasoning and main content with proper formatting + self.assertIn(REASONING_START, final_text) + self.assertIn("My step-by-step reasoning process", final_text) + self.assertIn(REASONING_END, final_text) + self.assertIn("Final answer after reasoning", final_text) + + # Ensure proper order: reasoning first, then main content + reasoning_pos = final_text.find("My step-by-step reasoning process") + main_pos = final_text.find("Final answer after reasoning") + self.assertLess( + reasoning_pos, main_pos, "Reasoning content should appear before main content" + ) + + # Verify that partial_response_content only contains the main content + coder.remove_reasoning_content() + expected_content = "Final answer after reasoning" + self.assertEqual(coder.partial_response_content.strip(), expected_content) + @patch("aider.models.litellm.completion") def test_simple_send_with_retries_removes_reasoning(self, mock_completion): """Test that simple_send_with_retries correctly removes reasoning content.""" - model = Model("deepseek-r1") # This model has remove_reasoning="think" + model = Model("deepseek-r1") # This model has reasoning_tag="think" # Mock the completion response mock_response = MagicMock() diff --git a/tests/basic/test_repo.py b/tests/basic/test_repo.py index d16bee2fd..aa863c570 100644 --- a/tests/basic/test_repo.py +++ b/tests/basic/test_repo.py @@ -405,3 +405,51 @@ class TestRepo(unittest.TestCase): git_repo = GitRepo(InputOutput(), None, None) git_repo.commit(fnames=[str(fname)]) + + def test_git_commit_verify(self): + """Test that git_commit_verify controls whether --no-verify is passed to git commit""" + # Skip on Windows as hook execution works differently + if platform.system() == "Windows": + return + + with GitTemporaryDirectory(): + # Create a new repo + raw_repo = git.Repo() + + # Create a file to commit + fname = Path("test_file.txt") + fname.write_text("initial content") + raw_repo.git.add(str(fname)) + + # Do the initial commit + raw_repo.git.commit("-m", "Initial commit") + + # Now create a pre-commit hook that always fails + hooks_dir = Path(raw_repo.git_dir) / "hooks" + hooks_dir.mkdir(exist_ok=True) + + pre_commit_hook = hooks_dir / "pre-commit" + pre_commit_hook.write_text("#!/bin/sh\nexit 1\n") # Always fail + pre_commit_hook.chmod(0o755) # Make executable + + # Modify the file + fname.write_text("modified content") + + # Create GitRepo with verify=True (default) + io = InputOutput() + git_repo_verify = GitRepo(io, None, None, git_commit_verify=True) + + # Attempt to commit - should fail due to pre-commit hook + commit_result = git_repo_verify.commit(fnames=[str(fname)], message="Should fail") + self.assertIsNone(commit_result) + + # Create GitRepo with verify=False + git_repo_no_verify = GitRepo(io, None, None, git_commit_verify=False) + + # Attempt to commit - should succeed by bypassing the hook + commit_result = git_repo_no_verify.commit(fnames=[str(fname)], message="Should succeed") + self.assertIsNotNone(commit_result) + + # Verify the commit was actually made + latest_commit_msg = raw_repo.head.commit.message + self.assertEqual(latest_commit_msg.strip(), "Should succeed") diff --git a/tests/basic/test_repomap.py b/tests/basic/test_repomap.py index c3920d846..17a5753c3 100644 --- a/tests/basic/test_repomap.py +++ b/tests/basic/test_repomap.py @@ -282,74 +282,145 @@ class TestRepoMapTypescript(unittest.TestCase): class TestRepoMapAllLanguages(unittest.TestCase): def setUp(self): self.GPT35 = Model("gpt-3.5-turbo") + self.fixtures_dir = Path(__file__).parent.parent / "fixtures" / "languages" - def test_get_repo_map_all_languages(self): - language_files = { - "c": ("c", "main"), - "cpp": ("cpp", "main"), - "elixir": ("ex", "Greeter"), - "java": ("java", "Greeting"), - "javascript": ("js", "Person"), - "kotlin": ("kt", "Greeting"), - # "ocaml": ("ml", "Greeter"), # not supported in tsl-pack (yet?) - "php": ("php", "greet"), - "python": ("py", "Person"), - # "ql": ("ql", "greet"), # not supported in tsl-pack (yet?) - "ruby": ("rb", "greet"), - "rust": ("rs", "Person"), - "typescript": ("ts", "greet"), - "tsx": ("tsx", "UserProps"), - "csharp": ("cs", "IGreeter"), - "elisp": ("el", "greeter"), - "elm": ("elm", "Person"), - "go": ("go", "Greeter"), - "hcl": ("tf", "aws_vpc"), - } + def test_language_c(self): + self._test_language_repo_map("c", "c", "main") - fixtures_dir = Path(__file__).parent.parent / "fixtures" / "languages" + def test_language_cpp(self): + self._test_language_repo_map("cpp", "cpp", "main") - for lang, key_symbol in language_files.items(): - # Get the fixture file path and name based on language - fixture_dir = fixtures_dir / lang - ext, key_symbol = language_files[lang] - filename = f"test.{ext}" - fixture_path = fixture_dir / filename - self.assertTrue( - fixture_path.exists(), f"Fixture file missing for {lang}: {fixture_path}" + def test_language_d(self): + self._test_language_repo_map("d", "d", "main") + + def test_language_dart(self): + self._test_language_repo_map("dart", "dart", "Person") + + def test_language_elixir(self): + self._test_language_repo_map("elixir", "ex", "Greeter") + + def test_language_gleam(self): + self._test_language_repo_map("gleam", "gleam", "greet") + + def test_language_java(self): + self._test_language_repo_map("java", "java", "Greeting") + + def test_language_javascript(self): + self._test_language_repo_map("javascript", "js", "Person") + + def test_language_kotlin(self): + self._test_language_repo_map("kotlin", "kt", "Greeting") + + def test_language_lua(self): + self._test_language_repo_map("lua", "lua", "greet") + + # "ocaml": ("ml", "Greeter"), # not supported in tsl-pack (yet?) + + def test_language_php(self): + self._test_language_repo_map("php", "php", "greet") + + def test_language_python(self): + self._test_language_repo_map("python", "py", "Person") + + # "ql": ("ql", "greet"), # not supported in tsl-pack (yet?) + + def test_language_ruby(self): + self._test_language_repo_map("ruby", "rb", "greet") + + def test_language_rust(self): + self._test_language_repo_map("rust", "rs", "Person") + + def test_language_typescript(self): + self._test_language_repo_map("typescript", "ts", "greet") + + def test_language_tsx(self): + self._test_language_repo_map("tsx", "tsx", "UserProps") + + def test_language_csharp(self): + self._test_language_repo_map("csharp", "cs", "IGreeter") + + def test_language_elisp(self): + self._test_language_repo_map("elisp", "el", "greeter") + + def test_language_elm(self): + self._test_language_repo_map("elm", "elm", "Person") + + def test_language_go(self): + self._test_language_repo_map("go", "go", "Greeter") + + def test_language_hcl(self): + self._test_language_repo_map("hcl", "tf", "aws_vpc") + + def test_language_arduino(self): + self._test_language_repo_map("arduino", "ino", "setup") + + def test_language_chatito(self): + self._test_language_repo_map("chatito", "chatito", "intent") + + def test_language_commonlisp(self): + self._test_language_repo_map("commonlisp", "lisp", "greet") + + def test_language_pony(self): + self._test_language_repo_map("pony", "pony", "Greeter") + + def test_language_properties(self): + self._test_language_repo_map("properties", "properties", "database.url") + + def test_language_r(self): + self._test_language_repo_map("r", "r", "calculate") + + def test_language_racket(self): + self._test_language_repo_map("racket", "rkt", "greet") + + def test_language_solidity(self): + self._test_language_repo_map("solidity", "sol", "SimpleStorage") + + def test_language_swift(self): + self._test_language_repo_map("swift", "swift", "Greeter") + + def test_language_udev(self): + self._test_language_repo_map("udev", "rules", "USB_DRIVER") + + def test_language_scala(self): + self._test_language_repo_map("scala", "scala", "Greeter") + + def _test_language_repo_map(self, lang, key, symbol): + """Helper method to test repo map generation for a specific language.""" + # Get the fixture file path and name based on language + fixture_dir = self.fixtures_dir / lang + filename = f"test.{key}" + fixture_path = fixture_dir / filename + self.assertTrue(fixture_path.exists(), f"Fixture file missing for {lang}: {fixture_path}") + + # Read the fixture content + with open(fixture_path, "r", encoding="utf-8") as f: + content = f.read() + with GitTemporaryDirectory() as temp_dir: + test_file = os.path.join(temp_dir, filename) + with open(test_file, "w", encoding="utf-8") as f: + f.write(content) + + io = InputOutput() + repo_map = RepoMap(main_model=self.GPT35, root=temp_dir, io=io) + other_files = [test_file] + result = repo_map.get_repo_map([], other_files) + dump(lang) + dump(result) + + self.assertGreater(len(result.strip().splitlines()), 1) + + # Check if the result contains all the expected files and symbols + self.assertIn( + filename, result, f"File for language {lang} not found in repo map: {result}" + ) + self.assertIn( + symbol, + result, + f"Key symbol '{symbol}' for language {lang} not found in repo map: {result}", ) - # Read the fixture content - with open(fixture_path, "r", encoding="utf-8") as f: - content = f.read() - with GitTemporaryDirectory() as temp_dir: - test_file = os.path.join(temp_dir, filename) - with open(test_file, "w", encoding="utf-8") as f: - f.write(content) - - io = InputOutput() - repo_map = RepoMap(main_model=self.GPT35, root=temp_dir, io=io) - other_files = [filename] - result = repo_map.get_repo_map([], other_files) - dump(lang) - dump(result) - - self.assertGreater(len(result.strip().splitlines()), 1) - - # Check if the result contains all the expected files and symbols - self.assertIn( - filename, result, f"File for language {lang} not found in repo map: {result}" - ) - self.assertIn( - key_symbol, - result, - ( - f"Key symbol '{key_symbol}' for language {lang} not found in repo map:" - f" {result}" - ), - ) - - # close the open cache files, so Windows won't error - del repo_map + # close the open cache files, so Windows won't error + del repo_map def test_repo_map_sample_code_base(self): # Path to the sample code base diff --git a/tests/basic/test_ssl_verification.py b/tests/basic/test_ssl_verification.py index 446596555..3a12f8581 100644 --- a/tests/basic/test_ssl_verification.py +++ b/tests/basic/test_ssl_verification.py @@ -24,8 +24,15 @@ class TestSSLVerification(TestCase): @patch("aider.llm.litellm._load_litellm") @patch("httpx.Client") @patch("httpx.AsyncClient") + @patch("aider.models.fuzzy_match_models", return_value=[]) def test_no_verify_ssl_flag_sets_model_info_manager( - self, mock_async_client, mock_client, mock_load_litellm, mock_set_verify_ssl, mock_offer_url + self, + mock_fuzzy_match, + mock_async_client, + mock_client, + mock_load_litellm, + mock_set_verify_ssl, + mock_offer_url, ): # Prevent actual URL opening mock_offer_url.return_value = False diff --git a/tests/basic/test_watch.py b/tests/basic/test_watch.py index 706fd1ade..524f80e08 100644 --- a/tests/basic/test_watch.py +++ b/tests/basic/test_watch.py @@ -155,3 +155,12 @@ def test_ai_comment_pattern(): assert ( question_js_has_bang == "?" ), "Expected at least one bang (!) comment in watch_question.js fixture" + + # Test Lisp fixture + lisp_path = fixtures_dir / "watch.lisp" + lisp_lines, lisp_comments, lisp_has_bang = watcher.get_ai_comments(str(lisp_path)) + lisp_expected = 7 + assert ( + len(lisp_lines) == lisp_expected + ), f"Expected {lisp_expected} AI comments in Lisp fixture, found {len(lisp_lines)}" + assert lisp_has_bang == "!", "Expected at least one bang (!) comment in Lisp fixture" diff --git a/tests/fixtures/languages/arduino/test.ino b/tests/fixtures/languages/arduino/test.ino new file mode 100644 index 000000000..524b91102 --- /dev/null +++ b/tests/fixtures/languages/arduino/test.ino @@ -0,0 +1,21 @@ +// Simple Arduino sketch + +void setup() { + // Initialize serial communication + Serial.begin(9600); + pinMode(LED_BUILTIN, OUTPUT); +} + +void loop() { + // Main code that runs repeatedly + digitalWrite(LED_BUILTIN, HIGH); + delay(1000); + digitalWrite(LED_BUILTIN, LOW); + delay(1000); + Serial.println("Blinking LED"); +} + +// A custom function +int calculateDelay(int baseDelay, int multiplier) { + return baseDelay * multiplier; +} diff --git a/tests/fixtures/languages/c/test.c b/tests/fixtures/languages/c/test.c index f26b97c98..8031a1f0b 100644 --- a/tests/fixtures/languages/c/test.c +++ b/tests/fixtures/languages/c/test.c @@ -4,3 +4,18 @@ int main() { printf("Hello, World!\n"); return 0; } +#include + +/** + * The main entry point of the program + * @return 0 on success + */ +int main(int argc, char **argv) { + printf("Hello, World!\n"); + return 0; +} + +// Helper function +void print_message(const char *message) { + printf("%s\n", message); +} diff --git a/tests/fixtures/languages/chatito/test.chatito b/tests/fixtures/languages/chatito/test.chatito new file mode 100644 index 000000000..9240ba459 --- /dev/null +++ b/tests/fixtures/languages/chatito/test.chatito @@ -0,0 +1,20 @@ +%[intent]('training': '60', 'testing': '40') + ~[greet] + ~[greet] @[name?] ~[endPolite?] + +%[name]('training': '50', 'testing': '50') + John + Anna + Bob + Sarah + +~[greet] + hi + hello + hey + greetings + +~[endPolite] + please + thanks + thank you diff --git a/tests/fixtures/languages/commonlisp/test.lisp b/tests/fixtures/languages/commonlisp/test.lisp new file mode 100644 index 000000000..5cf2173cd --- /dev/null +++ b/tests/fixtures/languages/commonlisp/test.lisp @@ -0,0 +1,17 @@ +;;; Simple Common Lisp example + +(defun greet (name) + "Return a greeting string for NAME." + (format nil "Hello, ~a!" name)) + +(defvar *greeting-style* 'formal + "Style to use for greetings.") + +(defclass person () + ((name :initarg :name :accessor person-name) + (age :initarg :age :accessor person-age)) + (:documentation "A class representing a person.")) + +(defmethod print-object ((obj person) stream) + (print-unreadable-object (obj stream :type t) + (format stream "~a, age ~a" (person-name obj) (person-age obj)))) diff --git a/tests/fixtures/languages/d/test.d b/tests/fixtures/languages/d/test.d new file mode 100644 index 000000000..6f4c57c75 --- /dev/null +++ b/tests/fixtures/languages/d/test.d @@ -0,0 +1,26 @@ +import std.stdio; + +/** + * Main function for the D language test file. + */ +void main() { + writeln("Hello, D language!"); + + auto greeter = new Greeter("World"); + writeln(greeter.greet()); +} + +/** + * A simple greeter class in D + */ +class Greeter { + private string name; + + this(string name) { + this.name = name; + } + + string greet() { + return "Hello, " ~ name ~ "!"; + } +} diff --git a/tests/fixtures/languages/dart/test.dart b/tests/fixtures/languages/dart/test.dart new file mode 100644 index 000000000..ae299df9d --- /dev/null +++ b/tests/fixtures/languages/dart/test.dart @@ -0,0 +1,21 @@ +// A simple Dart class for testing ctags detection +class Person { + String name; + int age; + + Person(this.name, this.age); + + void greet() { + print('Hello, my name is $name and I am $age years old.'); + } + + bool isAdult() { + return age >= 18; + } +} + +void main() { + var person = Person('John', 30); + person.greet(); + print('Is adult: ${person.isAdult()}'); +} diff --git a/tests/fixtures/languages/elm/test.elm b/tests/fixtures/languages/elm/test.elm index 7784f60eb..e78412b1a 100644 --- a/tests/fixtures/languages/elm/test.elm +++ b/tests/fixtures/languages/elm/test.elm @@ -36,3 +36,24 @@ main = div [ class "greeting" ] [ text (greet Formal defaultPerson) ] +module Main exposing (..) + +-- Define a Person type +type alias Person = + { name : String + , age : Int + } + +-- Create a person +newPerson : String -> Int -> Person +newPerson name age = + { name = name + , age = age + } + +-- Main function +main = + let + person = newPerson "John Doe" 30 + in + text ("Hello, " ++ person.name) diff --git a/tests/fixtures/languages/gleam/test.gleam b/tests/fixtures/languages/gleam/test.gleam new file mode 100644 index 000000000..f0c5aa32e --- /dev/null +++ b/tests/fixtures/languages/gleam/test.gleam @@ -0,0 +1,10 @@ +import gleam/io + +pub fn greet(name: String) -> String { + "Hello, " <> name <> "!" +} + +pub fn main() { + greet("World") + |> io.println +} diff --git a/tests/fixtures/languages/lua/test.lua b/tests/fixtures/languages/lua/test.lua new file mode 100644 index 000000000..7ef930f11 --- /dev/null +++ b/tests/fixtures/languages/lua/test.lua @@ -0,0 +1,25 @@ +-- Simple Lua module with a greeting function + +-- Person class definition +local Person = {} +Person.__index = Person + +function Person.new(name) + local self = setmetatable({}, Person) + self.name = name + return self +end + +-- Main greeting function to be detected by ctags +function greet(person) + return "Hello, " .. person.name .. "!" +end + +-- Example usage +local p = Person.new("World") +print(greet(p)) + +return { + Person = Person, + greet = greet +} diff --git a/tests/fixtures/languages/pony/test.pony b/tests/fixtures/languages/pony/test.pony new file mode 100644 index 000000000..799ad861b --- /dev/null +++ b/tests/fixtures/languages/pony/test.pony @@ -0,0 +1,8 @@ +class Greeter + fun greet(name: String): String => + "Hello, " + name + "!" + +actor Main + new create(env: Env) => + let greeter = Greeter + env.out.print(greeter.greet("Pony")) diff --git a/tests/fixtures/languages/properties/test.properties b/tests/fixtures/languages/properties/test.properties new file mode 100644 index 000000000..e41c40c47 --- /dev/null +++ b/tests/fixtures/languages/properties/test.properties @@ -0,0 +1,14 @@ +# Database Configuration +database.url=jdbc:mysql://localhost:3306/mydb +database.username=admin +database.password=secret + +# Application Settings +app.name=My Application +app.version=1.0.0 +app.debug=true + +# Server Configuration +server.port=8080 +server.host=localhost +server.maxConnections=100 diff --git a/tests/fixtures/languages/r/test.r b/tests/fixtures/languages/r/test.r new file mode 100644 index 000000000..191881e76 --- /dev/null +++ b/tests/fixtures/languages/r/test.r @@ -0,0 +1,17 @@ +# Simple R function for testing repository mapping +calculate <- function(x, y) { + # This function performs a simple calculation + result <- x * y + return(result) +} + +# Another function to test detection +process_data <- function(data) { + # Process some data + return(data * 2) +} + +# Example usage +sample_data <- c(1, 2, 3, 4, 5) +result <- calculate(10, 5) +processed <- process_data(sample_data) diff --git a/tests/fixtures/languages/racket/test.rkt b/tests/fixtures/languages/racket/test.rkt new file mode 100644 index 000000000..05be192cf --- /dev/null +++ b/tests/fixtures/languages/racket/test.rkt @@ -0,0 +1,8 @@ +#lang racket + +;; Define a simple greeting function +(define (greet name) + (string-append "Hello, " name "!")) + +;; Example usage +(greet "World") diff --git a/tests/fixtures/languages/scala/test.scala b/tests/fixtures/languages/scala/test.scala new file mode 100644 index 000000000..3300aa299 --- /dev/null +++ b/tests/fixtures/languages/scala/test.scala @@ -0,0 +1,61 @@ +package com.example.test + +// A trait definition +trait Greeter { + def greet(name: String): String +} + +// A class definition with parameters +class FormalGreeter(prefix: String) extends Greeter { + // A method definition + override def greet(name: String): String = { + s"$prefix, $name!" + } + + // A val definition + val defaultPrefix: String = "Hello" + + // A var definition + var counter: Int = 0 +} + +// An object definition +object GreeterFactory { + // A function definition + def createGreeter(formal: Boolean): Greeter = { + if (formal) { + new FormalGreeter("Good day") + } else { + new CasualGreeter + } + } + + // A type definition + type GreeterType = Greeter +} + +// An enum definition +enum Greeting { + // Simple enum cases + case Hello, Hi, Hey + + // Full enum case with parameters + case Custom(text: String) +} + +// A class that uses generics +class Container[T](val value: T) { + def map[U](f: T => U): Container[U] = new Container(f(value)) +} + +// A case class +case class Person(name: String, age: Int) { + def introduce(): String = { + val greeter = GreeterFactory.createGreeter(age > 30) + greeter.greet(name) + s" I am $age years old." + } +} + +class CasualGreeter extends Greeter { + override def greet(name: String): String = s"Hey, $name!" +} diff --git a/tests/fixtures/languages/solidity/test.sol b/tests/fixtures/languages/solidity/test.sol new file mode 100644 index 000000000..f78e64884 --- /dev/null +++ b/tests/fixtures/languages/solidity/test.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +contract SimpleStorage { + uint256 private value; + + event ValueChanged(uint256 newValue); + + constructor(uint256 initialValue) { + value = initialValue; + } + + function setValue(uint256 newValue) public { + value = newValue; + emit ValueChanged(newValue); + } + + function getValue() public view returns (uint256) { + return value; + } +} diff --git a/tests/fixtures/languages/swift/test.swift b/tests/fixtures/languages/swift/test.swift new file mode 100644 index 000000000..8e1fbb86f --- /dev/null +++ b/tests/fixtures/languages/swift/test.swift @@ -0,0 +1,18 @@ +// Swift greeting example +class Greeter { + let name: String + + init(name: String) { + self.name = name + } + + func greet() -> String { + return "Hello, \(name)!" + } +} + +// Example usage +func exampleGreeting() { + let greeter = Greeter(name: "World") + print(greeter.greet()) +} diff --git a/tests/fixtures/languages/udev/test.rules b/tests/fixtures/languages/udev/test.rules new file mode 100644 index 000000000..e6cbb91ec --- /dev/null +++ b/tests/fixtures/languages/udev/test.rules @@ -0,0 +1,22 @@ +# Define a label for a specific device +LABEL="my_usb_device", ATTRS{idVendor}=="1234", ATTRS{idProduct}=="5678" + +# Reference a label in a GOTO +SUBSYSTEM=="usb", GOTO="my_peripheral" + +# Define environment variables +ENV{DEVTYPE}="usb_device" +ENV{USB_DRIVER}="usb-storage" + +# Reference environment variables +ENV{DEVTYPE}=="usb_device", SYMLINK+="usb_storage_%k" + +# Variable substitution +SYMLINK+="disk/by-label/$env{ID_FS_LABEL}" + +# Label for a section of rules +LABEL="my_peripheral" +SUBSYSTEM=="usb", MODE="0666" + +# End label +LABEL="end_my_rules" diff --git a/tests/fixtures/sample-code-base-repo-map.txt b/tests/fixtures/sample-code-base-repo-map.txt index 29671525f..b6ddbfeab 100644 --- a/tests/fixtures/sample-code-base-repo-map.txt +++ b/tests/fixtures/sample-code-base-repo-map.txt @@ -1,32 +1,32 @@ tests/fixtures/sample-code-base/sample.js: -⋮... +⋮ │function greet(name) { │ return `Hello, ${name}!`; -⋮... +⋮ │function calculateCircleArea(radius) { │ return Math.PI * radius * radius; -⋮... +⋮ │function isPrime(number) { │ if (number <= 1) return false; │ for (let i = 2; i <= Math.sqrt(number); i++) { │ if (number % i === 0) return false; │ } │ return true; -⋮... +⋮ │function reverseString(str) { │ return str.split('').reverse().join(''); -⋮... +⋮ │function getRandomNumber(min, max) { │ return Math.floor(Math.random() * (max - min + 1)) + min; -⋮... +⋮ │function filterEvenNumbers(numbers) { │ return numbers.filter(num => num % 2 !== 0); -⋮... +⋮ │function factorial(n) { │ if (n === 0 || n === 1) return 1; │ return n * factorial(n - 1); -⋮... +⋮ tests/fixtures/sample-code-base/sample.py: │class Car: @@ -34,22 +34,22 @@ tests/fixtures/sample-code-base/sample.py: │ self.make = make │ self.model = model │ self.year = year -⋮... +⋮ │ def accelerate(self, increment): -⋮... +⋮ │ def brake(self, decrement): -⋮... +⋮ │ def honk(self): -⋮... +⋮ │class Garage: │ def __init__(self): -⋮... +⋮ │ def add_car(self, car): -⋮... +⋮ │ def remove_car(self, car): -⋮... +⋮ │ def list_cars(self): -⋮... +⋮ │def main(): -⋮... +⋮ diff --git a/tests/fixtures/watch.lisp b/tests/fixtures/watch.lisp new file mode 100644 index 000000000..1aae8fb8f --- /dev/null +++ b/tests/fixtures/watch.lisp @@ -0,0 +1,19 @@ +(defun hello-world () + ;; ai this is a simple hello world function + (format t "Hello, World!")) + +(defun add (a b) + ; ai! fix this function to handle nil values + (+ a b)) + +(defun multiply (a b) + ;;; ai? why is this function not working with large numbers? + (* a b)) + +; ai this is a single semicolon comment + +;; ai this is a double semicolon comment + +;;; ai this is a triple semicolon comment + +;;;; ai! this is a quadruple semicolon comment diff --git a/tests/help/test_help.py b/tests/help/test_help.py index 11102db28..a7222185e 100644 --- a/tests/help/test_help.py +++ b/tests/help/test_help.py @@ -1,6 +1,9 @@ +import time import unittest from unittest.mock import MagicMock +from requests.exceptions import ConnectionError, ReadTimeout + import aider from aider.coders import Coder from aider.commands import Commands @@ -10,6 +13,40 @@ from aider.models import Model class TestHelp(unittest.TestCase): + @staticmethod + def retry_with_backoff(func, max_time=60, initial_delay=1, backoff_factor=2): + """ + Execute a function with exponential backoff retry logic. + + Args: + func: Function to execute + max_time: Maximum time in seconds to keep retrying + initial_delay: Initial delay between retries in seconds + backoff_factor: Multiplier for delay after each retry + + Returns: + The result of the function if successful + + Raises: + The last exception encountered if all retries fail + """ + start_time = time.time() + delay = initial_delay + last_exception = None + + while time.time() - start_time < max_time: + try: + return func() + except (ReadTimeout, ConnectionError) as e: + last_exception = e + time.sleep(delay) + delay = min(delay * backoff_factor, 15) # Cap max delay at 15 seconds + + # If we've exhausted our retry time, raise the last exception + if last_exception: + raise last_exception + raise Exception("Retry timeout exceeded but no exception was caught") + @classmethod def setUpClass(cls): io = InputOutput(pretty=False, yes=True) @@ -22,13 +59,17 @@ class TestHelp(unittest.TestCase): help_coder_run = MagicMock(return_value="") aider.coders.HelpCoder.run = help_coder_run - try: - commands.cmd_help("hi") - except aider.commands.SwitchCoder: - pass - else: - # If no exception was raised, fail the test - assert False, "SwitchCoder exception was not raised" + def run_help_command(): + try: + commands.cmd_help("hi") + except aider.commands.SwitchCoder: + pass + else: + # If no exception was raised, fail the test + assert False, "SwitchCoder exception was not raised" + + # Use retry with backoff for the help command that loads models + cls.retry_with_backoff(run_help_command) help_coder_run.assert_called_once()