From c980fd0e775e2d61d4bd88f7cc85f29717b0d1e6 Mon Sep 17 00:00:00 2001 From: Jon Keys Date: Tue, 25 Feb 2025 18:26:36 -0800 Subject: [PATCH 01/85] use playwright if available when invoking scraper via cli --- aider/gui.py | 4 ++-- aider/scrape.py | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/aider/gui.py b/aider/gui.py index 7fa90bc38..6c5b012dc 100755 --- a/aider/gui.py +++ b/aider/gui.py @@ -11,7 +11,7 @@ from aider.coders import Coder from aider.dump import dump # noqa: F401 from aider.io import InputOutput from aider.main import main as cli_main -from aider.scrape import Scraper +from aider.scrape import Scraper, has_playwright class CaptureIO(InputOutput): @@ -484,7 +484,7 @@ class GUI: url = self.web_content if not self.state.scraper: - self.scraper = Scraper(print_error=self.info) + self.scraper = Scraper(print_error=self.info, playwright_available=has_playwright()) content = self.scraper.scrape(url) or "" if content.strip(): diff --git a/aider/scrape.py b/aider/scrape.py index 7977a8548..04e44bc81 100755 --- a/aider/scrape.py +++ b/aider/scrape.py @@ -14,7 +14,7 @@ aider_user_agent = f"Aider/{__version__} +{urls.website}" # platforms. -def install_playwright(io): +def check_env(): try: from playwright.sync_api import sync_playwright @@ -29,6 +29,16 @@ def install_playwright(io): except Exception: has_chromium = False + return has_pip, has_chromium + + +def has_playwright(): + has_pip, has_chromium = check_env() + return has_pip and has_chromium + + +def install_playwright(io): + has_pip, has_chromium = check_env() if has_pip and has_chromium: return True @@ -261,7 +271,7 @@ def slimdown_html(soup): def main(url): - scraper = Scraper() + scraper = Scraper(playwright_available=has_playwright()) content = scraper.scrape(url) print(content) From c1b2ff20de98236c3f2bff4af578619eec1003a2 Mon Sep 17 00:00:00 2001 From: "Stefan Hladnik (aider)" Date: Tue, 18 Mar 2025 03:02:19 +0700 Subject: [PATCH 02/85] feat: Add method to fetch model info from openrouter pages --- aider/models.py | 45 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/aider/models.py b/aider/models.py index cc54f03d3..8289a424a 100644 --- a/aider/models.py +++ b/aider/models.py @@ -211,7 +211,7 @@ class ModelInfoManager: def get_model_info(self, model): cached_info = self.get_model_from_cached_json_db(model) - + litellm_info = None if litellm._lazy_module or not cached_info: try: @@ -219,13 +219,52 @@ class ModelInfoManager: except Exception as ex: if "model_prices_and_context_window.json" not in str(ex): print(str(ex)) - + if litellm_info: return litellm_info - + + if not cached_info and model.startswith("openrouter/"): + openrouter_info = self.fetch_openrouter_model_info(model) + if openrouter_info: + return openrouter_info + return cached_info + def fetch_openrouter_model_info(self, model): + """ + Fetch model info by scraping the openrouter model page. + Expected URL: https://openrouter.ai/ + Example: openrouter/qwen/qwen-2.5-72b-instruct:free + Returns a dict with keys: max_input_tokens, input_cost, output_cost. + """ + url_part = model[len("openrouter/"):] + url = "https://openrouter.ai/" + url_part + import requests + try: + response = requests.get(url, timeout=5) + if response.status_code != 200: + return {} + html = response.text + from bs4 import BeautifulSoup + soup = BeautifulSoup(html, "html.parser") + text = soup.get_text() + import re + context_match = re.search(r"([\d,]+)\s*context", text) + if context_match: + context_str = context_match.group(1).replace(",", "") + context_size = int(context_str) + else: + context_size = None + input_cost_match = re.search(r"\$\s*0\s*/M input tokens", text, re.IGNORECASE) + output_cost_match = re.search(r"\$\s*0\s*/M output tokens", text, re.IGNORECASE) + input_cost = 0 if input_cost_match else None + output_cost = 0 if output_cost_match else None + return {"max_input_tokens": context_size, "input_cost": input_cost, "output_cost": output_cost} + except Exception as e: + print("Error fetching openrouter info:", str(e)) + return {} + model_info_manager = ModelInfoManager() From 4600dbcda5c991b9f630cfd571bb8f884c5e41ab Mon Sep 17 00:00:00 2001 From: "Stefan Hladnik (aider)" Date: Tue, 18 Mar 2025 03:05:55 +0700 Subject: [PATCH 03/85] feat: Print parsed model parameters in fetch_openrouter_model_info() method --- aider/models.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/aider/models.py b/aider/models.py index 8289a424a..108dd9a97 100644 --- a/aider/models.py +++ b/aider/models.py @@ -260,7 +260,9 @@ class ModelInfoManager: output_cost_match = re.search(r"\$\s*0\s*/M output tokens", text, re.IGNORECASE) input_cost = 0 if input_cost_match else None output_cost = 0 if output_cost_match else None - return {"max_input_tokens": context_size, "input_cost": input_cost, "output_cost": output_cost} + params = {"max_input_tokens": context_size, "input_cost": input_cost, "output_cost": output_cost} + print("Parsed model parameters:", params) + return params except Exception as e: print("Error fetching openrouter info:", str(e)) return {} From 08d48f42ad6c826ad108d5d3becef2c602c27fe3 Mon Sep 17 00:00:00 2001 From: "Stefan Hladnik (aider)" Date: Tue, 18 Mar 2025 03:08:57 +0700 Subject: [PATCH 04/85] refactor: Remove BeautifulSoup dependency and use regex to strip HTML tags --- aider/models.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/aider/models.py b/aider/models.py index 108dd9a97..28bc05f85 100644 --- a/aider/models.py +++ b/aider/models.py @@ -246,10 +246,8 @@ class ModelInfoManager: if response.status_code != 200: return {} html = response.text - from bs4 import BeautifulSoup - soup = BeautifulSoup(html, "html.parser") - text = soup.get_text() import re + text = re.sub(r'<[^>]+>', ' ', html) context_match = re.search(r"([\d,]+)\s*context", text) if context_match: context_str = context_match.group(1).replace(",", "") From 5e48f6898d17163e94a30c15df4507a6c23711cb Mon Sep 17 00:00:00 2001 From: "Stefan Hladnik (aider)" Date: Tue, 18 Mar 2025 03:10:23 +0700 Subject: [PATCH 05/85] fix: Improve print statement to include model name in parameters output --- aider/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aider/models.py b/aider/models.py index 28bc05f85..fbe6ed181 100644 --- a/aider/models.py +++ b/aider/models.py @@ -259,7 +259,7 @@ class ModelInfoManager: input_cost = 0 if input_cost_match else None output_cost = 0 if output_cost_match else None params = {"max_input_tokens": context_size, "input_cost": input_cost, "output_cost": output_cost} - print("Parsed model parameters:", params) + print(f"Model '{model}': Parsed parameters: {params}") return params except Exception as e: print("Error fetching openrouter info:", str(e)) From 44e5525e6f46f04b020b3feea19b63669d214dd7 Mon Sep 17 00:00:00 2001 From: Stefan Hladnik Date: Tue, 18 Mar 2025 03:17:56 +0700 Subject: [PATCH 06/85] style: Remove unnecessary blank lines in ModelInfoManager class --- aider/models.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/aider/models.py b/aider/models.py index fbe6ed181..1bf2168b6 100644 --- a/aider/models.py +++ b/aider/models.py @@ -211,7 +211,7 @@ class ModelInfoManager: def get_model_info(self, model): cached_info = self.get_model_from_cached_json_db(model) - + litellm_info = None if litellm._lazy_module or not cached_info: try: @@ -219,15 +219,15 @@ class ModelInfoManager: except Exception as ex: if "model_prices_and_context_window.json" not in str(ex): print(str(ex)) - + if litellm_info: return litellm_info - + if not cached_info and model.startswith("openrouter/"): openrouter_info = self.fetch_openrouter_model_info(model) if openrouter_info: return openrouter_info - + return cached_info @@ -264,7 +264,7 @@ class ModelInfoManager: except Exception as e: print("Error fetching openrouter info:", str(e)) return {} - + model_info_manager = ModelInfoManager() From 2651d9967681accad317e1b7023a7303e20c1a0a Mon Sep 17 00:00:00 2001 From: "Stefan Hladnik (aider)" Date: Tue, 18 Mar 2025 03:17:57 +0700 Subject: [PATCH 07/85] feat: Update cost extraction to capture non-zero input/output costs --- aider/models.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/aider/models.py b/aider/models.py index 1bf2168b6..53b99c772 100644 --- a/aider/models.py +++ b/aider/models.py @@ -254,10 +254,10 @@ class ModelInfoManager: context_size = int(context_str) else: context_size = None - input_cost_match = re.search(r"\$\s*0\s*/M input tokens", text, re.IGNORECASE) - output_cost_match = re.search(r"\$\s*0\s*/M output tokens", text, re.IGNORECASE) - input_cost = 0 if input_cost_match else None - output_cost = 0 if output_cost_match else None + input_cost_match = re.search(r"\$\s*([\d.]+)\s*/M input tokens", text, re.IGNORECASE) + output_cost_match = re.search(r"\$\s*([\d.]+)\s*/M output tokens", text, re.IGNORECASE) + input_cost = float(input_cost_match.group(1)) if input_cost_match else None + output_cost = float(output_cost_match.group(1)) if output_cost_match else None params = {"max_input_tokens": context_size, "input_cost": input_cost, "output_cost": output_cost} print(f"Model '{model}': Parsed parameters: {params}") return params From 29587cd07cc824ce2795f9b255540dd4c7f66575 Mon Sep 17 00:00:00 2001 From: "Stefan Hladnik (aider)" Date: Tue, 18 Mar 2025 03:24:04 +0700 Subject: [PATCH 08/85] fix: Update return keys in fetch_openrouter_model_info() to match JSON metadata --- aider/models.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/aider/models.py b/aider/models.py index 53b99c772..1ca6276fd 100644 --- a/aider/models.py +++ b/aider/models.py @@ -236,7 +236,7 @@ class ModelInfoManager: Fetch model info by scraping the openrouter model page. Expected URL: https://openrouter.ai/ Example: openrouter/qwen/qwen-2.5-72b-instruct:free - Returns a dict with keys: max_input_tokens, input_cost, output_cost. + Returns a dict with keys: max_tokens, max_input_tokens, max_output_tokens, input_cost_per_token, output_cost_per_token. """ url_part = model[len("openrouter/"):] url = "https://openrouter.ai/" + url_part @@ -258,7 +258,13 @@ class ModelInfoManager: output_cost_match = re.search(r"\$\s*([\d.]+)\s*/M output tokens", text, re.IGNORECASE) input_cost = float(input_cost_match.group(1)) if input_cost_match else None output_cost = float(output_cost_match.group(1)) if output_cost_match else None - params = {"max_input_tokens": context_size, "input_cost": input_cost, "output_cost": output_cost} + params = { + "max_input_tokens": context_size, + "max_tokens": context_size, + "max_output_tokens": context_size, + "input_cost_per_token": input_cost, + "output_cost_per_token": output_cost, + } print(f"Model '{model}': Parsed parameters: {params}") return params except Exception as e: From 4765a90f97722b124ea9166c7442b4baec6d48ef Mon Sep 17 00:00:00 2001 From: Stefan Hladnik Date: Tue, 18 Mar 2025 03:38:24 +0700 Subject: [PATCH 09/85] fix: Adjust input and output cost calculations to use million scale --- aider/models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aider/models.py b/aider/models.py index 1ca6276fd..3499e7820 100644 --- a/aider/models.py +++ b/aider/models.py @@ -256,8 +256,8 @@ class ModelInfoManager: context_size = None input_cost_match = re.search(r"\$\s*([\d.]+)\s*/M input tokens", text, re.IGNORECASE) output_cost_match = re.search(r"\$\s*([\d.]+)\s*/M output tokens", text, re.IGNORECASE) - input_cost = float(input_cost_match.group(1)) if input_cost_match else None - output_cost = float(output_cost_match.group(1)) if output_cost_match else None + input_cost = float(input_cost_match.group(1)) / 1000000 if input_cost_match else None + output_cost = float(output_cost_match.group(1)) / 1000000 if output_cost_match else None params = { "max_input_tokens": context_size, "max_tokens": context_size, From b37773c6300428c5d7ac277f927862431601b01b Mon Sep 17 00:00:00 2001 From: "Stefan Hladnik (aider)" Date: Tue, 18 Mar 2025 03:38:25 +0700 Subject: [PATCH 10/85] style: Update import location and add SSL verification in fetch_openrouter_model_info() --- aider/models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aider/models.py b/aider/models.py index 3499e7820..ed014bb54 100644 --- a/aider/models.py +++ b/aider/models.py @@ -240,9 +240,9 @@ class ModelInfoManager: """ url_part = model[len("openrouter/"):] url = "https://openrouter.ai/" + url_part - import requests try: - response = requests.get(url, timeout=5) + import requests + response = requests.get(url, timeout=5, verify=self.verify_ssl) if response.status_code != 200: return {} html = response.text From 87ccacb99f79aeab6d3747d3b6c05d55377d9e30 Mon Sep 17 00:00:00 2001 From: "Stefan Hladnik (aider)" Date: Tue, 18 Mar 2025 03:46:36 +0700 Subject: [PATCH 11/85] fix: Return empty dict if any required parameters are missing --- aider/models.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/aider/models.py b/aider/models.py index ed014bb54..749b2c79c 100644 --- a/aider/models.py +++ b/aider/models.py @@ -258,6 +258,8 @@ class ModelInfoManager: output_cost_match = re.search(r"\$\s*([\d.]+)\s*/M output tokens", text, re.IGNORECASE) input_cost = float(input_cost_match.group(1)) / 1000000 if input_cost_match else None output_cost = float(output_cost_match.group(1)) / 1000000 if output_cost_match else None + if context_size is None or input_cost is None or output_cost is None: + return {} params = { "max_input_tokens": context_size, "max_tokens": context_size, From d64427d726685f8687bd7400041b16fce2170c95 Mon Sep 17 00:00:00 2001 From: "Stefan Hladnik (aider)" Date: Tue, 18 Mar 2025 03:49:59 +0700 Subject: [PATCH 12/85] feat: Add error handling for unavailable model in response text --- aider/models.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/aider/models.py b/aider/models.py index 749b2c79c..dc55e0a8a 100644 --- a/aider/models.py +++ b/aider/models.py @@ -246,6 +246,9 @@ class ModelInfoManager: if response.status_code != 200: return {} html = response.text + if f'The model "{url_part}" is not available' in html: + print(f"Error: Model '{url_part}' is not available") + sys.exit(1) import re text = re.sub(r'<[^>]+>', ' ', html) context_match = re.search(r"([\d,]+)\s*context", text) From 21cca34392a8bac0bb6ffbc1226a8877578944ad Mon Sep 17 00:00:00 2001 From: "Stefan Hladnik (aider)" Date: Tue, 18 Mar 2025 03:53:27 +0700 Subject: [PATCH 13/85] fix: Allow arbitrary characters in model availability check regex --- aider/models.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aider/models.py b/aider/models.py index dc55e0a8a..fe92e8aa5 100644 --- a/aider/models.py +++ b/aider/models.py @@ -246,10 +246,10 @@ class ModelInfoManager: if response.status_code != 200: return {} html = response.text - if f'The model "{url_part}" is not available' in html: + import re + if re.search(rf'The model\s*.*{re.escape(url_part)}.* is not available', html, re.IGNORECASE): print(f"Error: Model '{url_part}' is not available") sys.exit(1) - import re text = re.sub(r'<[^>]+>', ' ', html) context_match = re.search(r"([\d,]+)\s*context", text) if context_match: From cdd730e627e7e9f2a18d77e72c96b1600706e6eb Mon Sep 17 00:00:00 2001 From: "Stefan Hladnik (aider)" Date: Tue, 18 Mar 2025 03:54:27 +0700 Subject: [PATCH 14/85] feat: Print error message in red for unavailable models --- aider/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aider/models.py b/aider/models.py index fe92e8aa5..f78376948 100644 --- a/aider/models.py +++ b/aider/models.py @@ -248,7 +248,7 @@ class ModelInfoManager: html = response.text import re if re.search(rf'The model\s*.*{re.escape(url_part)}.* is not available', html, re.IGNORECASE): - print(f"Error: Model '{url_part}' is not available") + print(f"\033[91mError: Model '{url_part}' is not available\033[0m") sys.exit(1) text = re.sub(r'<[^>]+>', ' ', html) context_match = re.search(r"([\d,]+)\s*context", text) From 7c3d96d0e7a9360f60e4148c585f6553bb73b2c5 Mon Sep 17 00:00:00 2001 From: Stefan Hladnik Date: Tue, 18 Mar 2025 04:13:40 +0700 Subject: [PATCH 15/85] fix: Remove debug print statement from ModelInfoManager class --- aider/models.py | 1 - 1 file changed, 1 deletion(-) diff --git a/aider/models.py b/aider/models.py index f78376948..a190f5f97 100644 --- a/aider/models.py +++ b/aider/models.py @@ -270,7 +270,6 @@ class ModelInfoManager: "input_cost_per_token": input_cost, "output_cost_per_token": output_cost, } - print(f"Model '{model}': Parsed parameters: {params}") return params except Exception as e: print("Error fetching openrouter info:", str(e)) From b3d9e0d1b058da0f9a560e3a6637b0cd446da7d8 Mon Sep 17 00:00:00 2001 From: "Stefan Hladnik (aider)" Date: Tue, 18 Mar 2025 12:18:48 +0700 Subject: [PATCH 16/85] fix: Return empty dict instead of exiting on model availability error --- aider/models.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aider/models.py b/aider/models.py index a190f5f97..bc1d54e12 100644 --- a/aider/models.py +++ b/aider/models.py @@ -249,7 +249,7 @@ class ModelInfoManager: import re if re.search(rf'The model\s*.*{re.escape(url_part)}.* is not available', html, re.IGNORECASE): print(f"\033[91mError: Model '{url_part}' is not available\033[0m") - sys.exit(1) + return {} text = re.sub(r'<[^>]+>', ' ', html) context_match = re.search(r"([\d,]+)\s*context", text) if context_match: From e980973621da2a20d95b6a477756cb01e3f8cca9 Mon Sep 17 00:00:00 2001 From: Andrey Popp <8mayday@gmail.com> Date: Sun, 30 Mar 2025 22:09:06 +0400 Subject: [PATCH 17/85] feat: add repomap support for ocaml/ocaml_interface --- .../tree-sitter-language-pack/ocaml-tags.scm | 115 ++++++++++++++++++ .../ocaml_interface-tags.scm | 98 +++++++++++++++ .../ocaml_interface-tags.scm | 98 +++++++++++++++ tests/basic/test_repomap.py | 9 +- .../languages/ocaml_interface/test.mli | 14 +++ 5 files changed, 332 insertions(+), 2 deletions(-) create mode 100644 aider/queries/tree-sitter-language-pack/ocaml-tags.scm create mode 100644 aider/queries/tree-sitter-language-pack/ocaml_interface-tags.scm create mode 100644 aider/queries/tree-sitter-languages/ocaml_interface-tags.scm create mode 100644 tests/fixtures/languages/ocaml_interface/test.mli diff --git a/aider/queries/tree-sitter-language-pack/ocaml-tags.scm b/aider/queries/tree-sitter-language-pack/ocaml-tags.scm new file mode 100644 index 000000000..52d5a857e --- /dev/null +++ b/aider/queries/tree-sitter-language-pack/ocaml-tags.scm @@ -0,0 +1,115 @@ +; Modules +;-------- + +( + (comment)? @doc . + (module_definition (module_binding (module_name) @name.definition.module) @definition.module) + (#strip! @doc "^\\(\\*\\*?\\s*|\\s\\*\\)$") +) + +(module_path (module_name) @name.reference.module) @reference.module + +; Module types +;-------------- + +( + (comment)? @doc . + (module_type_definition (module_type_name) @name.definition.interface) @definition.interface + (#strip! @doc "^\\(\\*\\*?\\s*|\\s\\*\\)$") +) + +(module_type_path (module_type_name) @name.reference.implementation) @reference.implementation + +; Functions +;---------- + +( + (comment)? @doc . + (value_definition + [ + (let_binding + pattern: (value_name) @name.definition.function + (parameter)) + (let_binding + pattern: (value_name) @name.definition.function + body: [(fun_expression) (function_expression)]) + ] @definition.function + ) + (#strip! @doc "^\\(\\*\\*?\\s*|\\s\\*\\)$") +) + +( + (comment)? @doc . + (external (value_name) @name.definition.function) @definition.function + (#strip! @doc "^\\(\\*\\*?\\s*|\\s\\*\\)$") +) + +(application_expression + function: (value_path (value_name) @name.reference.call)) @reference.call + +(infix_expression + left: (value_path (value_name) @name.reference.call) + operator: (concat_operator) @reference.call + (#eq? @reference.call "@@")) + +(infix_expression + operator: (rel_operator) @reference.call + right: (value_path (value_name) @name.reference.call) + (#eq? @reference.call "|>")) + +; Operator +;--------- + +( + (comment)? @doc . + (value_definition + (let_binding + pattern: (parenthesized_operator (_) @name.definition.function)) @definition.function) + (#strip! @doc "^\\(\\*\\*?\\s*|\\s\\*\\)$") +) + +[ + (prefix_operator) + (sign_operator) + (pow_operator) + (mult_operator) + (add_operator) + (concat_operator) + (rel_operator) + (and_operator) + (or_operator) + (assign_operator) + (hash_operator) + (indexing_operator) + (let_operator) + (let_and_operator) + (match_operator) +] @name.reference.call @reference.call + +; Classes +;-------- + +( + (comment)? @doc . + [ + (class_definition (class_binding (class_name) @name.definition.class) @definition.class) + (class_type_definition (class_type_binding (class_type_name) @name.definition.class) @definition.class) + ] + (#strip! @doc "^\\(\\*\\*?\\s*|\\s\\*\\)$") +) + +[ + (class_path (class_name) @name.reference.class) + (class_type_path (class_type_name) @name.reference.class) +] @reference.class + +; Methods +;-------- + +( + (comment)? @doc . + (method_definition (method_name) @name.definition.method) @definition.method + (#strip! @doc "^\\(\\*\\*?\\s*|\\s\\*\\)$") +) + +(method_invocation (method_name) @name.reference.call) @reference.call diff --git a/aider/queries/tree-sitter-language-pack/ocaml_interface-tags.scm b/aider/queries/tree-sitter-language-pack/ocaml_interface-tags.scm new file mode 100644 index 000000000..d7a8f8b97 --- /dev/null +++ b/aider/queries/tree-sitter-language-pack/ocaml_interface-tags.scm @@ -0,0 +1,98 @@ +; Modules +;-------- + +( + (comment)? @doc . + (module_definition + (module_binding (module_name) @name) @definition.module + ) + (#strip! @doc "^\\(\\*+\\s*|\\s*\\*+\\)$") +) + +(module_path (module_name) @name) @reference.module +(extended_module_path (module_name) @name) @reference.module + +( + (comment)? @doc . + (module_type_definition (module_type_name) @name) @definition.interface + (#strip! @doc "^\\(\\*+\\s*|\\s*\\*+\\)$") +) + +(module_type_path (module_type_name) @name) @reference.implementation + + +; Classes +;-------- + +( + (comment)? @doc . + [ + (class_definition + (class_binding (class_name) @name) @definition.class + ) + (class_type_definition + (class_type_binding (class_type_name) @name) @definition.class + ) + ] + (#strip! @doc "^\\(\\*+\\s*|\\s*\\*+\\)$") +) + +[ + (class_path (class_name) @name) + (class_type_path (class_type_name) @name) +] @reference.class + +( + (comment)? @doc . + (method_definition (method_name) @name) @definition.method + (#strip! @doc "^\\(\\*+\\s*|\\s*\\*+\\)$") +) + +(method_invocation (method_name) @name) @reference.call + + +; Types +;------ + +( + (comment)? @doc . + (type_definition + (type_binding + name: [ + (type_constructor) @name + (type_constructor_path (type_constructor) @name) + ] + ) @definition.type + ) + (#strip! @doc "^\\(\\*+\\s*|\\s*\\*+\\)$") +) + +(type_constructor_path (type_constructor) @name) @reference.type + +[ + (constructor_declaration (constructor_name) @name) + (tag_specification (tag) @name) +] @definition.enum_variant + +[ + (constructor_path (constructor_name) @name) + (tag) @name +] @reference.enum_variant + +(field_declaration (field_name) @name) @definition.field + +(field_path (field_name) @name) @reference.field + +( + (comment)? @doc . + (external (value_name) @name) @definition.function + (#strip! @doc "^\\(\\*+\\s*|\\s*\\*+\\)$") +) + +( + (comment)? @doc . + (value_specification + (value_name) @name.definition.function + ) @definition.function + (#strip! @doc "^\\(\\*+\\s*|\\s*\\*+\\)$") +) diff --git a/aider/queries/tree-sitter-languages/ocaml_interface-tags.scm b/aider/queries/tree-sitter-languages/ocaml_interface-tags.scm new file mode 100644 index 000000000..d7a8f8b97 --- /dev/null +++ b/aider/queries/tree-sitter-languages/ocaml_interface-tags.scm @@ -0,0 +1,98 @@ +; Modules +;-------- + +( + (comment)? @doc . + (module_definition + (module_binding (module_name) @name) @definition.module + ) + (#strip! @doc "^\\(\\*+\\s*|\\s*\\*+\\)$") +) + +(module_path (module_name) @name) @reference.module +(extended_module_path (module_name) @name) @reference.module + +( + (comment)? @doc . + (module_type_definition (module_type_name) @name) @definition.interface + (#strip! @doc "^\\(\\*+\\s*|\\s*\\*+\\)$") +) + +(module_type_path (module_type_name) @name) @reference.implementation + + +; Classes +;-------- + +( + (comment)? @doc . + [ + (class_definition + (class_binding (class_name) @name) @definition.class + ) + (class_type_definition + (class_type_binding (class_type_name) @name) @definition.class + ) + ] + (#strip! @doc "^\\(\\*+\\s*|\\s*\\*+\\)$") +) + +[ + (class_path (class_name) @name) + (class_type_path (class_type_name) @name) +] @reference.class + +( + (comment)? @doc . + (method_definition (method_name) @name) @definition.method + (#strip! @doc "^\\(\\*+\\s*|\\s*\\*+\\)$") +) + +(method_invocation (method_name) @name) @reference.call + + +; Types +;------ + +( + (comment)? @doc . + (type_definition + (type_binding + name: [ + (type_constructor) @name + (type_constructor_path (type_constructor) @name) + ] + ) @definition.type + ) + (#strip! @doc "^\\(\\*+\\s*|\\s*\\*+\\)$") +) + +(type_constructor_path (type_constructor) @name) @reference.type + +[ + (constructor_declaration (constructor_name) @name) + (tag_specification (tag) @name) +] @definition.enum_variant + +[ + (constructor_path (constructor_name) @name) + (tag) @name +] @reference.enum_variant + +(field_declaration (field_name) @name) @definition.field + +(field_path (field_name) @name) @reference.field + +( + (comment)? @doc . + (external (value_name) @name) @definition.function + (#strip! @doc "^\\(\\*+\\s*|\\s*\\*+\\)$") +) + +( + (comment)? @doc . + (value_specification + (value_name) @name.definition.function + ) @definition.function + (#strip! @doc "^\\(\\*+\\s*|\\s*\\*+\\)$") +) diff --git a/tests/basic/test_repomap.py b/tests/basic/test_repomap.py index 17a5753c3..322bac954 100644 --- a/tests/basic/test_repomap.py +++ b/tests/basic/test_repomap.py @@ -314,8 +314,6 @@ class TestRepoMapAllLanguages(unittest.TestCase): 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") @@ -384,6 +382,12 @@ class TestRepoMapAllLanguages(unittest.TestCase): def test_language_scala(self): self._test_language_repo_map("scala", "scala", "Greeter") + def test_language_ocaml(self): + self._test_language_repo_map("ocaml", "ml", "Greeter") + + def test_language_ocaml_interface(self): + self._test_language_repo_map("ocaml_interface", "mli", "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 @@ -407,6 +411,7 @@ class TestRepoMapAllLanguages(unittest.TestCase): dump(lang) dump(result) + print(result) self.assertGreater(len(result.strip().splitlines()), 1) # Check if the result contains all the expected files and symbols diff --git a/tests/fixtures/languages/ocaml_interface/test.mli b/tests/fixtures/languages/ocaml_interface/test.mli new file mode 100644 index 000000000..8289f9fc5 --- /dev/null +++ b/tests/fixtures/languages/ocaml_interface/test.mli @@ -0,0 +1,14 @@ +(* Module definition *) +module Greeter : sig + type person = { + name: string; + age: int + } + + val create_person : string -> int -> person + + val greet : person -> unit +end + +(* Outside the module *) +val main : unit -> unit From 67bb4f95524d1d4d47cf55f17be2189626784569 Mon Sep 17 00:00:00 2001 From: "Andrew Grigorev (aider)" Date: Sat, 12 Apr 2025 16:52:45 +0300 Subject: [PATCH 18/85] feat: add co-authored-by commit attribution --- aider/args.py | 6 +++ aider/coders/base_coder.py | 4 +- aider/repo.py | 76 +++++++++++++++++++++++++++++++------- 3 files changed, 70 insertions(+), 16 deletions(-) diff --git a/aider/args.py b/aider/args.py index 6df19778b..4f91a9cbd 100644 --- a/aider/args.py +++ b/aider/args.py @@ -448,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( + "--attribute-co-authored-by", + action=argparse.BooleanOptionalAction, + default=False, + help="Attribute aider edits using the Co-authored-by trailer in the commit message (default: False).", + ) group.add_argument( "--git-commit-verify", action=argparse.BooleanOptionalAction, diff --git a/aider/coders/base_coder.py b/aider/coders/base_coder.py index 19d375afb..5c64475eb 100755 --- a/aider/coders/base_coder.py +++ b/aider/coders/base_coder.py @@ -2248,7 +2248,7 @@ class Coder: context = self.get_context_from_history(self.cur_messages) try: - res = self.repo.commit(fnames=edited, context=context, aider_edits=True) + res = self.repo.commit(fnames=edited, context=context, aider_edits=True, coder=self) if res: self.show_auto_commit_outcome(res) commit_hash, commit_message = res @@ -2284,7 +2284,7 @@ class Coder: if not self.repo: return - self.repo.commit(fnames=self.need_commit_before_edits) + self.repo.commit(fnames=self.need_commit_before_edits, coder=self) # files changed, move cur messages back behind the files messages # self.move_back_cur_messages(self.gpt_prompts.files_content_local_edits) diff --git a/aider/repo.py b/aider/repo.py index 5ece5147c..999a07269 100644 --- a/aider/repo.py +++ b/aider/repo.py @@ -111,7 +111,7 @@ class GitRepo: if aider_ignore_file: self.aider_ignore_file = Path(aider_ignore_file) - def commit(self, fnames=None, context=None, message=None, aider_edits=False): + def commit(self, fnames=None, context=None, message=None, aider_edits=False, coder=None): if not fnames and not self.repo.is_dirty(): return @@ -124,15 +124,52 @@ class GitRepo: else: commit_message = self.get_commit_message(diffs, context) - if aider_edits and self.attribute_commit_message_author: - commit_message = "aider: " + commit_message - elif self.attribute_commit_message_committer: - commit_message = "aider: " + commit_message + commit_message_trailer = "" + if aider_edits: + # Use coder.args if available, otherwise default to config/defaults + attribute_author = ( + coder.args.attribute_author + if coder and hasattr(coder, "args") + else self.attribute_author + ) + attribute_committer = ( + coder.args.attribute_committer + if coder and hasattr(coder, "args") + else self.attribute_committer + ) + attribute_commit_message_author = ( + coder.args.attribute_commit_message_author + if coder and hasattr(coder, "args") + else self.attribute_commit_message_author + ) + attribute_commit_message_committer = ( + coder.args.attribute_commit_message_committer + if coder and hasattr(coder, "args") + else self.attribute_commit_message_committer + ) + attribute_co_authored_by = ( + coder.args.attribute_co_authored_by + if coder and hasattr(coder, "args") + else False # Default to False if not found + ) + + # Add Co-authored-by trailer if configured + if attribute_co_authored_by: + model_name = "unknown-model" + if coder and hasattr(coder, "main_model") and coder.main_model.name: + model_name = coder.main_model.name + commit_message_trailer = ( + f"\n\nCo-authored-by: aider ({model_name}) " + ) + + # Prefix commit message if configured + if attribute_commit_message_author or attribute_commit_message_committer: + commit_message = "aider: " + commit_message if not commit_message: commit_message = "(no commit message provided)" - full_commit_message = commit_message + full_commit_message = commit_message + commit_message_trailer # if context: # full_commit_message += "\n\n# Aider chat conversation:\n\n" + context @@ -152,13 +189,25 @@ class GitRepo: original_user_name = self.repo.git.config("--get", "user.name") original_committer_name_env = os.environ.get("GIT_COMMITTER_NAME") + original_author_name_env = os.environ.get("GIT_AUTHOR_NAME") committer_name = f"{original_user_name} (aider)" - if self.attribute_committer: + # Use coder.args if available, otherwise default to config/defaults + use_attribute_committer = ( + coder.args.attribute_committer + if coder and hasattr(coder, "args") + else self.attribute_committer + ) + use_attribute_author = ( + coder.args.attribute_author + if coder and hasattr(coder, "args") + else self.attribute_author + ) + + if use_attribute_committer: os.environ["GIT_COMMITTER_NAME"] = committer_name - if aider_edits and self.attribute_author: - original_author_name_env = os.environ.get("GIT_AUTHOR_NAME") + if aider_edits and use_attribute_author: os.environ["GIT_AUTHOR_NAME"] = committer_name try: @@ -170,17 +219,16 @@ class GitRepo: self.io.tool_error(f"Unable to commit: {err}") finally: # Restore the env - - if self.attribute_committer: + if use_attribute_committer: if original_committer_name_env is not None: os.environ["GIT_COMMITTER_NAME"] = original_committer_name_env - else: + elif "GIT_COMMITTER_NAME" in os.environ: del os.environ["GIT_COMMITTER_NAME"] - if aider_edits and self.attribute_author: + if aider_edits and use_attribute_author: if original_author_name_env is not None: os.environ["GIT_AUTHOR_NAME"] = original_author_name_env - else: + elif "GIT_AUTHOR_NAME" in os.environ: del os.environ["GIT_AUTHOR_NAME"] def get_rel_repo_dir(self): From b6b8f30378cae0cab844989142eec5efb39f6554 Mon Sep 17 00:00:00 2001 From: "Andrew Grigorev (aider)" Date: Sat, 12 Apr 2025 16:57:21 +0300 Subject: [PATCH 19/85] test: add tests for co-authored-by commit attribution --- tests/basic/test_repo.py | 83 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 1 deletion(-) diff --git a/tests/basic/test_repo.py b/tests/basic/test_repo.py index aa863c570..7e288e063 100644 --- a/tests/basic/test_repo.py +++ b/tests/basic/test_repo.py @@ -4,7 +4,7 @@ import tempfile import time import unittest from pathlib import Path -from unittest.mock import patch +from unittest.mock import MagicMock, patch import git @@ -211,6 +211,87 @@ class TestRepo(unittest.TestCase): original_author_name = os.environ.get("GIT_AUTHOR_NAME") self.assertIsNone(original_author_name) + def test_commit_with_co_authored_by(self): + # Cleanup of the git temp dir explodes on windows + if platform.system() == "Windows": + return + + with GitTemporaryDirectory(): + # new repo + raw_repo = git.Repo() + raw_repo.config_writer().set_value("user", "name", "Test User").release() + raw_repo.config_writer().set_value("user", "email", "test@example.com").release() + + # add a file and commit it + fname = Path("file.txt") + fname.touch() + raw_repo.git.add(str(fname)) + raw_repo.git.commit("-m", "initial commit") + + # Mock coder args + mock_coder = MagicMock() + mock_coder.args.attribute_co_authored_by = True + mock_coder.args.attribute_author = None # Explicitly None to test override + mock_coder.args.attribute_committer = None # Explicitly None to test override + mock_coder.args.attribute_commit_message_author = False + mock_coder.args.attribute_commit_message_committer = False + mock_coder.model.name = "gpt-test" + + io = InputOutput() + git_repo = GitRepo(io, None, None) + + # commit a change with aider_edits=True and co-authored-by flag + fname.write_text("new content") + git_repo.commit(fnames=[str(fname)], aider_edits=True, coder=mock_coder, message="Aider edit") + + # check the commit message and author/committer + commit = raw_repo.head.commit + self.assertIn("Co-authored-by: aider (gpt-test) ", commit.message) + self.assertEqual(commit.message.splitlines()[0], "Aider edit") + self.assertEqual(commit.author.name, "Test User") # Should NOT be modified + self.assertEqual(commit.committer.name, "Test User") # Should NOT be modified + + def test_commit_without_co_authored_by(self): + # Cleanup of the git temp dir explodes on windows + if platform.system() == "Windows": + return + + with GitTemporaryDirectory(): + # new repo + raw_repo = git.Repo() + raw_repo.config_writer().set_value("user", "name", "Test User").release() + raw_repo.config_writer().set_value("user", "email", "test@example.com").release() + + # add a file and commit it + fname = Path("file.txt") + fname.touch() + raw_repo.git.add(str(fname)) + raw_repo.git.commit("-m", "initial commit") + + # Mock coder args (default behavior) + mock_coder = MagicMock() + mock_coder.args.attribute_co_authored_by = False + mock_coder.args.attribute_author = True + mock_coder.args.attribute_committer = True + mock_coder.args.attribute_commit_message_author = False + mock_coder.args.attribute_commit_message_committer = False + mock_coder.model.name = "gpt-test" + + io = InputOutput() + git_repo = GitRepo(io, None, None) + + # commit a change with aider_edits=True and default flags + fname.write_text("new content") + git_repo.commit(fnames=[str(fname)], aider_edits=True, coder=mock_coder, message="Aider edit") + + # check the commit message and author/committer + commit = raw_repo.head.commit + self.assertNotIn("Co-authored-by:", commit.message) + self.assertEqual(commit.message.splitlines()[0], "Aider edit") + self.assertEqual(commit.author.name, "Test User (aider)") # Should be modified + self.assertEqual(commit.committer.name, "Test User (aider)") # Should be modified + + def test_get_tracked_files(self): # Create a temporary directory tempdir = Path(tempfile.mkdtemp()) From eb28e228913fdc0c90b62168bb4b57475a91e22c Mon Sep 17 00:00:00 2001 From: "Andrew Grigorev (aider)" Date: Sat, 12 Apr 2025 17:07:41 +0300 Subject: [PATCH 20/85] test: fix mock setup for model name in co-authored-by test --- tests/basic/test_repo.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/basic/test_repo.py b/tests/basic/test_repo.py index 7e288e063..4ff694714 100644 --- a/tests/basic/test_repo.py +++ b/tests/basic/test_repo.py @@ -235,7 +235,9 @@ class TestRepo(unittest.TestCase): mock_coder.args.attribute_committer = None # Explicitly None to test override mock_coder.args.attribute_commit_message_author = False mock_coder.args.attribute_commit_message_committer = False - mock_coder.model.name = "gpt-test" + # Set the model name correctly on the nested mock + mock_coder.model = MagicMock(name="gpt-test") + io = InputOutput() git_repo = GitRepo(io, None, None) From 192f8bec26ca0348cf43b1ec7bf00ac7e459f565 Mon Sep 17 00:00:00 2001 From: "Andrew Grigorev (aider)" Date: Sat, 12 Apr 2025 17:09:12 +0300 Subject: [PATCH 21/85] test: fix mock model name setup in co-authored-by test --- tests/basic/test_repo.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/basic/test_repo.py b/tests/basic/test_repo.py index 4ff694714..d0441a4da 100644 --- a/tests/basic/test_repo.py +++ b/tests/basic/test_repo.py @@ -236,7 +236,8 @@ class TestRepo(unittest.TestCase): mock_coder.args.attribute_commit_message_author = False mock_coder.args.attribute_commit_message_committer = False # Set the model name correctly on the nested mock - mock_coder.model = MagicMock(name="gpt-test") + mock_coder.model = MagicMock() + mock_coder.model.configure_mock(name="gpt-test") io = InputOutput() From a5327af5e9ef31b68a4345a6679b66b72a9c09fc Mon Sep 17 00:00:00 2001 From: "Andrew Grigorev (aider)" Date: Sat, 12 Apr 2025 17:12:30 +0300 Subject: [PATCH 22/85] test: fix mock setup for co-authored-by commit test --- tests/basic/test_repo.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/basic/test_repo.py b/tests/basic/test_repo.py index d0441a4da..631e6f606 100644 --- a/tests/basic/test_repo.py +++ b/tests/basic/test_repo.py @@ -236,8 +236,9 @@ class TestRepo(unittest.TestCase): mock_coder.args.attribute_commit_message_author = False mock_coder.args.attribute_commit_message_committer = False # Set the model name correctly on the nested mock - mock_coder.model = MagicMock() - mock_coder.model.configure_mock(name="gpt-test") + # The code uses coder.main_model.name for the co-authored-by line + mock_coder.main_model = MagicMock() + mock_coder.main_model.name = "gpt-test" io = InputOutput() From b22c9b8542cda2a5e45df0a919039d484378d2b9 Mon Sep 17 00:00:00 2001 From: "Andrew Grigorev (aider)" Date: Sat, 12 Apr 2025 17:32:15 +0300 Subject: [PATCH 23/85] feat: implement Co-authored-by attribution option --- aider/repo.py | 74 ++++++++++++++++++++-------------------- tests/basic/test_repo.py | 55 +++++++++++++++++++++++++++-- 2 files changed, 89 insertions(+), 40 deletions(-) diff --git a/aider/repo.py b/aider/repo.py index 999a07269..efa0fda8c 100644 --- a/aider/repo.py +++ b/aider/repo.py @@ -125,7 +125,41 @@ class GitRepo: commit_message = self.get_commit_message(diffs, context) commit_message_trailer = "" + attribute_author = self.attribute_author + attribute_committer = self.attribute_committer + attribute_commit_message_author = self.attribute_commit_message_author + attribute_commit_message_committer = self.attribute_commit_message_committer + attribute_co_authored_by = False # Default if coder or args not available + + if coder and hasattr(coder, "args"): + attribute_author = coder.args.attribute_author + attribute_committer = coder.args.attribute_committer + attribute_commit_message_author = coder.args.attribute_commit_message_author + attribute_commit_message_committer = coder.args.attribute_commit_message_committer + attribute_co_authored_by = coder.args.attribute_co_authored_by + if aider_edits: + # Add Co-authored-by trailer if configured + if attribute_co_authored_by: + model_name = "unknown-model" + if coder and hasattr(coder, "main_model") and coder.main_model.name: + model_name = coder.main_model.name + commit_message_trailer = ( + f"\n\nCo-authored-by: aider ({model_name}) " + ) + + # Prefix commit message if configured + if attribute_commit_message_author or attribute_commit_message_committer: + commit_message = "aider: " + commit_message + + # Prepare author/committer modification flags (used later) + use_attribute_author = attribute_author + use_attribute_committer = attribute_committer + else: + # Don't modify author/committer/message for non-aider edits + use_attribute_author = False + use_attribute_committer = self.attribute_committer # Keep committer modification for non-aider edits if configured + # Use coder.args if available, otherwise default to config/defaults attribute_author = ( coder.args.attribute_author @@ -143,29 +177,6 @@ class GitRepo: else self.attribute_commit_message_author ) attribute_commit_message_committer = ( - coder.args.attribute_commit_message_committer - if coder and hasattr(coder, "args") - else self.attribute_commit_message_committer - ) - attribute_co_authored_by = ( - coder.args.attribute_co_authored_by - if coder and hasattr(coder, "args") - else False # Default to False if not found - ) - - # Add Co-authored-by trailer if configured - if attribute_co_authored_by: - model_name = "unknown-model" - if coder and hasattr(coder, "main_model") and coder.main_model.name: - model_name = coder.main_model.name - commit_message_trailer = ( - f"\n\nCo-authored-by: aider ({model_name}) " - ) - - # Prefix commit message if configured - if attribute_commit_message_author or attribute_commit_message_committer: - commit_message = "aider: " + commit_message - if not commit_message: commit_message = "(no commit message provided)" @@ -192,22 +203,11 @@ class GitRepo: original_author_name_env = os.environ.get("GIT_AUTHOR_NAME") committer_name = f"{original_user_name} (aider)" - # Use coder.args if available, otherwise default to config/defaults - use_attribute_committer = ( - coder.args.attribute_committer - if coder and hasattr(coder, "args") - else self.attribute_committer - ) - use_attribute_author = ( - coder.args.attribute_author - if coder and hasattr(coder, "args") - else self.attribute_author - ) - + # Apply author/committer modifications based on flags determined earlier if use_attribute_committer: os.environ["GIT_COMMITTER_NAME"] = committer_name - if aider_edits and use_attribute_author: + if use_attribute_author: # Already checks for aider_edits implicitly os.environ["GIT_AUTHOR_NAME"] = committer_name try: @@ -225,7 +225,7 @@ class GitRepo: elif "GIT_COMMITTER_NAME" in os.environ: del os.environ["GIT_COMMITTER_NAME"] - if aider_edits and use_attribute_author: + if use_attribute_author: # Already checks for aider_edits implicitly if original_author_name_env is not None: os.environ["GIT_AUTHOR_NAME"] = original_author_name_env elif "GIT_AUTHOR_NAME" in os.environ: diff --git a/tests/basic/test_repo.py b/tests/basic/test_repo.py index 631e6f606..945de84f8 100644 --- a/tests/basic/test_repo.py +++ b/tests/basic/test_repo.py @@ -229,10 +229,11 @@ class TestRepo(unittest.TestCase): raw_repo.git.commit("-m", "initial commit") # Mock coder args + # Mock coder args: Co-authored-by enabled, author/committer modification disabled mock_coder = MagicMock() mock_coder.args.attribute_co_authored_by = True - mock_coder.args.attribute_author = None # Explicitly None to test override - mock_coder.args.attribute_committer = None # Explicitly None to test override + mock_coder.args.attribute_author = False # Explicitly disable name modification + mock_coder.args.attribute_committer = False # Explicitly disable name modification mock_coder.args.attribute_commit_message_author = False mock_coder.args.attribute_commit_message_committer = False # Set the model name correctly on the nested mock @@ -255,6 +256,51 @@ class TestRepo(unittest.TestCase): self.assertEqual(commit.author.name, "Test User") # Should NOT be modified self.assertEqual(commit.committer.name, "Test User") # Should NOT be modified + def test_commit_with_co_authored_by_and_name_modification(self): + # Test scenario where Co-authored-by is true AND author/committer modification is also true (default) + # Cleanup of the git temp dir explodes on windows + if platform.system() == "Windows": + return + + with GitTemporaryDirectory(): + # new repo + raw_repo = git.Repo() + raw_repo.config_writer().set_value("user", "name", "Test User").release() + raw_repo.config_writer().set_value("user", "email", "test@example.com").release() + + # add a file and commit it + fname = Path("file.txt") + fname.touch() + raw_repo.git.add(str(fname)) + raw_repo.git.commit("-m", "initial commit") + + # Mock coder args: Co-authored-by enabled, author/committer modification enabled (default) + mock_coder = MagicMock() + mock_coder.args.attribute_co_authored_by = True + mock_coder.args.attribute_author = True # Explicitly enable (or rely on default) + mock_coder.args.attribute_committer = True # Explicitly enable (or rely on default) + mock_coder.args.attribute_commit_message_author = False + mock_coder.args.attribute_commit_message_committer = False + # Set the model name correctly on the nested mock + mock_coder.main_model = MagicMock() + mock_coder.main_model.name = "gpt-test-combo" + + + io = InputOutput() + git_repo = GitRepo(io, None, None) + + # commit a change with aider_edits=True and combo flags + fname.write_text("new content combo") + git_repo.commit(fnames=[str(fname)], aider_edits=True, coder=mock_coder, message="Aider combo edit") + + # check the commit message and author/committer + commit = raw_repo.head.commit + self.assertIn("Co-authored-by: aider (gpt-test-combo) ", commit.message) + self.assertEqual(commit.message.splitlines()[0], "Aider combo edit") + self.assertEqual(commit.author.name, "Test User (aider)") # Should BE modified + self.assertEqual(commit.committer.name, "Test User (aider)") # Should BE modified + + def test_commit_without_co_authored_by(self): # Cleanup of the git temp dir explodes on windows if platform.system() == "Windows": @@ -279,7 +325,10 @@ class TestRepo(unittest.TestCase): mock_coder.args.attribute_committer = True mock_coder.args.attribute_commit_message_author = False mock_coder.args.attribute_commit_message_committer = False - mock_coder.model.name = "gpt-test" + # Set the model name correctly on the nested mock (though not used in this test assertion) + mock_coder.main_model = MagicMock() + mock_coder.main_model.name = "gpt-test-no-coauthor" + io = InputOutput() git_repo = GitRepo(io, None, None) From c73b987cd099cc73e1be17d3084df444b1e70491 Mon Sep 17 00:00:00 2001 From: "Andrew Grigorev (aider)" Date: Sat, 12 Apr 2025 17:32:57 +0300 Subject: [PATCH 24/85] fix: fix syntax error in commit logic --- aider/repo.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/aider/repo.py b/aider/repo.py index efa0fda8c..5ad84d36d 100644 --- a/aider/repo.py +++ b/aider/repo.py @@ -177,6 +177,10 @@ class GitRepo: else self.attribute_commit_message_author ) attribute_commit_message_committer = ( + coder.args.attribute_commit_message_committer + if coder and hasattr(coder, "args") + else self.attribute_commit_message_committer + ) if not commit_message: commit_message = "(no commit message provided)" From e9511643998d4868bc261b3ec0479e6a2a362b3a Mon Sep 17 00:00:00 2001 From: "Andrew Grigorev (aider)" Date: Sat, 12 Apr 2025 17:35:45 +0300 Subject: [PATCH 25/85] chore: Add test comment to dump function --- aider/dump.py | 1 + 1 file changed, 1 insertion(+) diff --git a/aider/dump.py b/aider/dump.py index 2c8bf31c2..6098d0b73 100644 --- a/aider/dump.py +++ b/aider/dump.py @@ -12,6 +12,7 @@ def cvt(s): def dump(*vals): + # This is a test comment # http://docs.python.org/library/traceback.html stack = traceback.extract_stack() vars = stack[-2][3] From 482e0c2d0b5cdfe60281f13bab2ead4aa540e9e6 Mon Sep 17 00:00:00 2001 From: "Andrew Grigorev (aider)" Date: Sat, 12 Apr 2025 17:37:00 +0300 Subject: [PATCH 26/85] chore: Add test comment --- aider/prompts.py | 1 + 1 file changed, 1 insertion(+) diff --git a/aider/prompts.py b/aider/prompts.py index 84ed75e9b..1dacf10d0 100644 --- a/aider/prompts.py +++ b/aider/prompts.py @@ -1,5 +1,6 @@ # flake8: noqa: E501 +# This is a test comment. # COMMIT From 4783ad3a73530c174f664505b65fe2e587ef27aa Mon Sep 17 00:00:00 2001 From: "Andrew Grigorev (aider)" Date: Sat, 12 Apr 2025 17:39:49 +0300 Subject: [PATCH 27/85] feat: add attribute-co-authored-by option for commit attribution --- aider/args.py | 2 +- aider/repo.py | 83 +++++++++++++++++++++++---------------------------- 2 files changed, 38 insertions(+), 47 deletions(-) diff --git a/aider/args.py b/aider/args.py index 4f91a9cbd..3571faa5e 100644 --- a/aider/args.py +++ b/aider/args.py @@ -428,7 +428,7 @@ def get_parser(default_config_files, git_root): "--attribute-author", action=argparse.BooleanOptionalAction, default=True, - help="Attribute aider code changes in the git author name (default: True)", + help="Attribute aider code changes in the git author name (default: True, ignored if attribute-co-authored-by is True unless explicitly set)", ) group.add_argument( "--attribute-committer", diff --git a/aider/repo.py b/aider/repo.py index 5ad84d36d..e0bcef2de 100644 --- a/aider/repo.py +++ b/aider/repo.py @@ -69,6 +69,8 @@ class GitRepo: self.attribute_committer = attribute_committer self.attribute_commit_message_author = attribute_commit_message_author self.attribute_commit_message_committer = attribute_commit_message_committer + # Ensure attribute_co_authored_by is initialized, default to False if not provided + self.attribute_co_authored_by = getattr(self, 'attribute_co_authored_by', False) self.commit_prompt = commit_prompt self.subtree_only = subtree_only self.git_commit_verify = git_commit_verify @@ -124,66 +126,56 @@ class GitRepo: else: commit_message = self.get_commit_message(diffs, context) - commit_message_trailer = "" - attribute_author = self.attribute_author - attribute_committer = self.attribute_committer - attribute_commit_message_author = self.attribute_commit_message_author - attribute_commit_message_committer = self.attribute_commit_message_committer - attribute_co_authored_by = False # Default if coder or args not available - + # Retrieve attribute settings, prioritizing coder.args if available if coder and hasattr(coder, "args"): attribute_author = coder.args.attribute_author attribute_committer = coder.args.attribute_committer attribute_commit_message_author = coder.args.attribute_commit_message_author attribute_commit_message_committer = coder.args.attribute_commit_message_committer attribute_co_authored_by = coder.args.attribute_co_authored_by + else: + # Fallback to self attributes (initialized from config/defaults) + attribute_author = self.attribute_author + attribute_committer = self.attribute_committer + attribute_commit_message_author = self.attribute_commit_message_author + attribute_commit_message_committer = self.attribute_commit_message_committer + attribute_co_authored_by = getattr(self, 'attribute_co_authored_by', False) + + commit_message_trailer = "" + prefix_commit_message = False + use_attribute_author = False + use_attribute_committer = False if aider_edits: - # Add Co-authored-by trailer if configured + # Determine commit message prefixing + if attribute_commit_message_author or attribute_commit_message_committer: + prefix_commit_message = True + + # Determine author/committer modification and trailer if attribute_co_authored_by: model_name = "unknown-model" if coder and hasattr(coder, "main_model") and coder.main_model.name: model_name = coder.main_model.name - commit_message_trailer = ( - f"\n\nCo-authored-by: aider ({model_name}) " - ) - - # Prefix commit message if configured - if attribute_commit_message_author or attribute_commit_message_committer: - commit_message = "aider: " + commit_message - - # Prepare author/committer modification flags (used later) - use_attribute_author = attribute_author - use_attribute_committer = attribute_committer - else: - # Don't modify author/committer/message for non-aider edits + commit_message_trailer = f"\n\nCo-authored-by: aider ({model_name}) " + # Only modify author/committer if explicitly requested alongside co-authored-by + use_attribute_author = attribute_author + use_attribute_committer = attribute_committer + else: + # Original behavior when co-authored-by is false + use_attribute_author = attribute_author + use_attribute_committer = attribute_committer + else: # not aider_edits + # Keep original behavior for non-aider edits use_attribute_author = False - use_attribute_committer = self.attribute_committer # Keep committer modification for non-aider edits if configured + use_attribute_committer = attribute_committer # Respect config for committer + prefix_commit_message = False # Don't prefix non-aider commits - # Use coder.args if available, otherwise default to config/defaults - attribute_author = ( - coder.args.attribute_author - if coder and hasattr(coder, "args") - else self.attribute_author - ) - attribute_committer = ( - coder.args.attribute_committer - if coder and hasattr(coder, "args") - else self.attribute_committer - ) - attribute_commit_message_author = ( - coder.args.attribute_commit_message_author - if coder and hasattr(coder, "args") - else self.attribute_commit_message_author - ) - attribute_commit_message_committer = ( - coder.args.attribute_commit_message_committer - if coder and hasattr(coder, "args") - else self.attribute_commit_message_committer - ) if not commit_message: commit_message = "(no commit message provided)" + if prefix_commit_message: + commit_message = "aider: " + commit_message + full_commit_message = commit_message + commit_message_trailer # if context: # full_commit_message += "\n\n# Aider chat conversation:\n\n" + context @@ -210,8 +202,7 @@ class GitRepo: # Apply author/committer modifications based on flags determined earlier if use_attribute_committer: os.environ["GIT_COMMITTER_NAME"] = committer_name - - if use_attribute_author: # Already checks for aider_edits implicitly + if use_attribute_author: os.environ["GIT_AUTHOR_NAME"] = committer_name try: @@ -229,7 +220,7 @@ class GitRepo: elif "GIT_COMMITTER_NAME" in os.environ: del os.environ["GIT_COMMITTER_NAME"] - if use_attribute_author: # Already checks for aider_edits implicitly + if use_attribute_author: if original_author_name_env is not None: os.environ["GIT_AUTHOR_NAME"] = original_author_name_env elif "GIT_AUTHOR_NAME" in os.environ: From 43cb4d68f7b6a31beddf130b9b09c5c448221005 Mon Sep 17 00:00:00 2001 From: "Andrew Grigorev (aider)" Date: Sat, 12 Apr 2025 17:45:48 +0300 Subject: [PATCH 28/85] test: Temporarily disable co-author attribution to verify test failure --- aider/repo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aider/repo.py b/aider/repo.py index e0bcef2de..aa6cffb4f 100644 --- a/aider/repo.py +++ b/aider/repo.py @@ -132,7 +132,7 @@ class GitRepo: attribute_committer = coder.args.attribute_committer attribute_commit_message_author = coder.args.attribute_commit_message_author attribute_commit_message_committer = coder.args.attribute_commit_message_committer - attribute_co_authored_by = coder.args.attribute_co_authored_by + # attribute_co_authored_by = coder.args.attribute_co_authored_by # <-- Intentionally commented out for testing else: # Fallback to self attributes (initialized from config/defaults) attribute_author = self.attribute_author From dede701423342f2dd40d1493c21874e92111a4ba Mon Sep 17 00:00:00 2001 From: "Andrew Grigorev (aider)" Date: Sat, 12 Apr 2025 17:47:20 +0300 Subject: [PATCH 29/85] test: intentionally break co-authored-by logic --- aider/repo.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/aider/repo.py b/aider/repo.py index aa6cffb4f..4ba96d920 100644 --- a/aider/repo.py +++ b/aider/repo.py @@ -132,7 +132,7 @@ class GitRepo: attribute_committer = coder.args.attribute_committer attribute_commit_message_author = coder.args.attribute_commit_message_author attribute_commit_message_committer = coder.args.attribute_commit_message_committer - # attribute_co_authored_by = coder.args.attribute_co_authored_by # <-- Intentionally commented out for testing + attribute_co_authored_by = coder.args.attribute_co_authored_by # <-- Restored else: # Fallback to self attributes (initialized from config/defaults) attribute_author = self.attribute_author @@ -152,7 +152,13 @@ class GitRepo: prefix_commit_message = True # Determine author/committer modification and trailer - if attribute_co_authored_by: + + # --- Intentionally break the behavior for testing --- + original_attribute_co_authored_by = attribute_co_authored_by # Keep original value if needed elsewhere + attribute_co_authored_by = False # Force to False to ignore the setting + # --- End intentional break --- + + if attribute_co_authored_by: # This condition will now always be false model_name = "unknown-model" if coder and hasattr(coder, "main_model") and coder.main_model.name: model_name = coder.main_model.name From 80114e7a24faa004d7131f47364a28f8fae8d694 Mon Sep 17 00:00:00 2001 From: "Andrew Grigorev (aider)" Date: Sat, 12 Apr 2025 17:48:52 +0300 Subject: [PATCH 30/85] chore: revert intentional break introduced for testing --- aider/repo.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/aider/repo.py b/aider/repo.py index 4ba96d920..7e04d89ee 100644 --- a/aider/repo.py +++ b/aider/repo.py @@ -153,12 +153,7 @@ class GitRepo: # Determine author/committer modification and trailer - # --- Intentionally break the behavior for testing --- - original_attribute_co_authored_by = attribute_co_authored_by # Keep original value if needed elsewhere - attribute_co_authored_by = False # Force to False to ignore the setting - # --- End intentional break --- - - if attribute_co_authored_by: # This condition will now always be false + if attribute_co_authored_by: model_name = "unknown-model" if coder and hasattr(coder, "main_model") and coder.main_model.name: model_name = coder.main_model.name From d5671c2879c85f581bd504a962e8b54b6567c776 Mon Sep 17 00:00:00 2001 From: "Andrew Grigorev (aider)" Date: Sat, 12 Apr 2025 17:50:16 +0300 Subject: [PATCH 31/85] chore: Add test comment --- tests/fixtures/sample-code-base/sample.js | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/fixtures/sample-code-base/sample.js b/tests/fixtures/sample-code-base/sample.js index f3f2eaf58..a934b428c 100644 --- a/tests/fixtures/sample-code-base/sample.js +++ b/tests/fixtures/sample-code-base/sample.js @@ -1,3 +1,4 @@ +// Aider test commit // Sample JavaScript script with 7 functions // 1. A simple greeting function From 48f89f226fac3d407d40574d921bf5df065cda71 Mon Sep 17 00:00:00 2001 From: "Andrew Grigorev (aider)" Date: Sat, 12 Apr 2025 17:51:58 +0300 Subject: [PATCH 32/85] fix: prevent name modification when using co-authored-by --- aider/repo.py | 10 +++++----- tests/basic/test_repo.py | 5 +++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/aider/repo.py b/aider/repo.py index 7e04d89ee..f0d436526 100644 --- a/aider/repo.py +++ b/aider/repo.py @@ -58,6 +58,7 @@ class GitRepo: commit_prompt=None, subtree_only=False, git_commit_verify=True, + attribute_co_authored_by=False, # Added parameter ): self.io = io self.models = models @@ -69,8 +70,7 @@ class GitRepo: self.attribute_committer = attribute_committer self.attribute_commit_message_author = attribute_commit_message_author self.attribute_commit_message_committer = attribute_commit_message_committer - # Ensure attribute_co_authored_by is initialized, default to False if not provided - self.attribute_co_authored_by = getattr(self, 'attribute_co_authored_by', False) + self.attribute_co_authored_by = attribute_co_authored_by # Assign from parameter self.commit_prompt = commit_prompt self.subtree_only = subtree_only self.git_commit_verify = git_commit_verify @@ -158,9 +158,9 @@ class GitRepo: if coder and hasattr(coder, "main_model") and coder.main_model.name: model_name = coder.main_model.name commit_message_trailer = f"\n\nCo-authored-by: aider ({model_name}) " - # Only modify author/committer if explicitly requested alongside co-authored-by - use_attribute_author = attribute_author - use_attribute_committer = attribute_committer + # If co-authored-by is used, disable author/committer name modification + use_attribute_author = False + use_attribute_committer = False else: # Original behavior when co-authored-by is false use_attribute_author = attribute_author diff --git a/tests/basic/test_repo.py b/tests/basic/test_repo.py index 945de84f8..2c68c8f00 100644 --- a/tests/basic/test_repo.py +++ b/tests/basic/test_repo.py @@ -297,8 +297,9 @@ class TestRepo(unittest.TestCase): commit = raw_repo.head.commit self.assertIn("Co-authored-by: aider (gpt-test-combo) ", commit.message) self.assertEqual(commit.message.splitlines()[0], "Aider combo edit") - self.assertEqual(commit.author.name, "Test User (aider)") # Should BE modified - self.assertEqual(commit.committer.name, "Test User (aider)") # Should BE modified + # When co-authored-by is true, name modification should be disabled + self.assertEqual(commit.author.name, "Test User") # Should NOT be modified + self.assertEqual(commit.committer.name, "Test User") # Should NOT be modified def test_commit_without_co_authored_by(self): From 072bd30443ce0b3bb8cb7df2f9550446b4edb240 Mon Sep 17 00:00:00 2001 From: "Andrew Grigorev (aider)" Date: Sat, 12 Apr 2025 17:53:11 +0300 Subject: [PATCH 33/85] test: add comment for testing --- tests/fixtures/sample-code-base/sample.js | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/fixtures/sample-code-base/sample.js b/tests/fixtures/sample-code-base/sample.js index a934b428c..31280539f 100644 --- a/tests/fixtures/sample-code-base/sample.js +++ b/tests/fixtures/sample-code-base/sample.js @@ -1,4 +1,5 @@ // Aider test commit +// Another test comment // Sample JavaScript script with 7 functions // 1. A simple greeting function From f648a018a2a738f03576acb4e4998e8b2be17341 Mon Sep 17 00:00:00 2001 From: "Andrew Grigorev (aider)" Date: Sat, 12 Apr 2025 17:55:13 +0300 Subject: [PATCH 34/85] fix: Pass attribute_co_authored_by arg to GitRepo constructor --- aider/main.py | 1 + 1 file changed, 1 insertion(+) diff --git a/aider/main.py b/aider/main.py index 9da90e161..a8535d02c 100644 --- a/aider/main.py +++ b/aider/main.py @@ -904,6 +904,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F commit_prompt=args.commit_prompt, subtree_only=args.subtree_only, git_commit_verify=args.git_commit_verify, + attribute_co_authored_by=args.attribute_co_authored_by, # Pass the arg ) except FileNotFoundError: pass From ff8e9850ba2dd61a5ff1cc6f5b2cb30d0469082e Mon Sep 17 00:00:00 2001 From: "Andrew Grigorev (aider)" Date: Sat, 12 Apr 2025 17:55:54 +0300 Subject: [PATCH 35/85] chore: add test comment to dump function --- aider/dump.py | 1 + 1 file changed, 1 insertion(+) diff --git a/aider/dump.py b/aider/dump.py index 6098d0b73..85065a97d 100644 --- a/aider/dump.py +++ b/aider/dump.py @@ -13,6 +13,7 @@ def cvt(s): def dump(*vals): # This is a test comment + # This is another test comment # http://docs.python.org/library/traceback.html stack = traceback.extract_stack() vars = stack[-2][3] From d1437b76665a4e4f51d6ea21200a0b817e6157c3 Mon Sep 17 00:00:00 2001 From: "Andrew Grigorev (aider)" Date: Sat, 12 Apr 2025 17:57:04 +0300 Subject: [PATCH 36/85] chore: add debug prints for attribute_co_authored_by --- aider/main.py | 2 ++ aider/repo.py | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/aider/main.py b/aider/main.py index a8535d02c..61100d14a 100644 --- a/aider/main.py +++ b/aider/main.py @@ -501,6 +501,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F # Parse again to include any arguments that might have been defined in .env args = parser.parse_args(argv) + print(f"DEBUG: After final parse, args.attribute_co_authored_by = {args.attribute_co_authored_by}") # DEBUG if git is None: args.git = False @@ -891,6 +892,7 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F repo = None if args.git: try: + print(f"DEBUG: Before GitRepo init, args.attribute_co_authored_by = {args.attribute_co_authored_by}") # DEBUG repo = GitRepo( io, fnames, diff --git a/aider/repo.py b/aider/repo.py index f0d436526..5a57ffb46 100644 --- a/aider/repo.py +++ b/aider/repo.py @@ -60,6 +60,7 @@ class GitRepo: git_commit_verify=True, attribute_co_authored_by=False, # Added parameter ): + print(f"DEBUG: GitRepo.__init__ received attribute_co_authored_by = {attribute_co_authored_by}") # DEBUG self.io = io self.models = models @@ -71,6 +72,7 @@ class GitRepo: self.attribute_commit_message_author = attribute_commit_message_author self.attribute_commit_message_committer = attribute_commit_message_committer self.attribute_co_authored_by = attribute_co_authored_by # Assign from parameter + print(f"DEBUG: GitRepo.__init__ set self.attribute_co_authored_by = {self.attribute_co_authored_by}") # DEBUG self.commit_prompt = commit_prompt self.subtree_only = subtree_only self.git_commit_verify = git_commit_verify @@ -117,6 +119,8 @@ class GitRepo: if not fnames and not self.repo.is_dirty(): return + print(f"DEBUG: GitRepo.commit start, self.attribute_co_authored_by = {self.attribute_co_authored_by}") # DEBUG + diffs = self.get_diffs(fnames) if not diffs: return @@ -141,6 +145,8 @@ class GitRepo: attribute_commit_message_committer = self.attribute_commit_message_committer attribute_co_authored_by = getattr(self, 'attribute_co_authored_by', False) + print(f"DEBUG: GitRepo.commit after retrieval, attribute_co_authored_by = {attribute_co_authored_by}") # DEBUG + commit_message_trailer = "" prefix_commit_message = False use_attribute_author = False @@ -153,6 +159,7 @@ class GitRepo: # Determine author/committer modification and trailer + print(f"DEBUG: GitRepo.commit before logic check, attribute_co_authored_by = {attribute_co_authored_by}") # DEBUG if attribute_co_authored_by: model_name = "unknown-model" if coder and hasattr(coder, "main_model") and coder.main_model.name: @@ -201,6 +208,7 @@ class GitRepo: committer_name = f"{original_user_name} (aider)" # Apply author/committer modifications based on flags determined earlier + print(f"DEBUG: GitRepo.commit before setting env, use_attribute_author={use_attribute_author}, use_attribute_committer={use_attribute_committer}") # DEBUG if use_attribute_committer: os.environ["GIT_COMMITTER_NAME"] = committer_name if use_attribute_author: From 15d623f2c085478e43ceafda98dffefcc44eec7d Mon Sep 17 00:00:00 2001 From: "Andrew Grigorev (aider)" Date: Sat, 12 Apr 2025 17:57:44 +0300 Subject: [PATCH 37/85] chore: add another test comment to prompts --- aider/prompts.py | 1 + 1 file changed, 1 insertion(+) diff --git a/aider/prompts.py b/aider/prompts.py index 1dacf10d0..87f14a5ec 100644 --- a/aider/prompts.py +++ b/aider/prompts.py @@ -1,6 +1,7 @@ # flake8: noqa: E501 # This is a test comment. +# This is another test comment. # COMMIT From 316d8f8e9bf919fa431cda7250ea33d4f5b230bd Mon Sep 17 00:00:00 2001 From: Andrew Grigorev Date: Sat, 12 Apr 2025 18:06:09 +0300 Subject: [PATCH 38/85] chore: add third test comment Co-authored-by: aider (vertex_ai/gemini-2.5-pro-exp-03-25) --- aider/prompts.py | 1 + 1 file changed, 1 insertion(+) diff --git a/aider/prompts.py b/aider/prompts.py index 87f14a5ec..50830978a 100644 --- a/aider/prompts.py +++ b/aider/prompts.py @@ -2,6 +2,7 @@ # This is a test comment. # This is another test comment. +# This is a third test comment. # COMMIT From 66fdeceb3b39f1ca25ed9cd7cf2a041b9d1e5f66 Mon Sep 17 00:00:00 2001 From: Andrew Grigorev Date: Sat, 12 Apr 2025 18:14:06 +0300 Subject: [PATCH 39/85] Revert "chore: add third test comment" This reverts commit 316d8f8e9bf919fa431cda7250ea33d4f5b230bd. --- aider/prompts.py | 1 - 1 file changed, 1 deletion(-) diff --git a/aider/prompts.py b/aider/prompts.py index 50830978a..87f14a5ec 100644 --- a/aider/prompts.py +++ b/aider/prompts.py @@ -2,7 +2,6 @@ # This is a test comment. # This is another test comment. -# This is a third test comment. # COMMIT From 0a59c38f31ff82137b219013693386efd4a13b96 Mon Sep 17 00:00:00 2001 From: Andrew Grigorev Date: Sat, 12 Apr 2025 18:14:07 +0300 Subject: [PATCH 40/85] Revert "chore: add another test comment to prompts" This reverts commit 15d623f2c085478e43ceafda98dffefcc44eec7d. --- aider/prompts.py | 1 - 1 file changed, 1 deletion(-) diff --git a/aider/prompts.py b/aider/prompts.py index 87f14a5ec..1dacf10d0 100644 --- a/aider/prompts.py +++ b/aider/prompts.py @@ -1,7 +1,6 @@ # flake8: noqa: E501 # This is a test comment. -# This is another test comment. # COMMIT From e1820522db7eb006306d6396e09f5f1b94b633f2 Mon Sep 17 00:00:00 2001 From: Andrew Grigorev Date: Sat, 12 Apr 2025 18:14:07 +0300 Subject: [PATCH 41/85] Revert "chore: add debug prints for attribute_co_authored_by" This reverts commit d1437b76665a4e4f51d6ea21200a0b817e6157c3. --- aider/main.py | 2 -- aider/repo.py | 8 -------- 2 files changed, 10 deletions(-) diff --git a/aider/main.py b/aider/main.py index 61100d14a..a8535d02c 100644 --- a/aider/main.py +++ b/aider/main.py @@ -501,7 +501,6 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F # Parse again to include any arguments that might have been defined in .env args = parser.parse_args(argv) - print(f"DEBUG: After final parse, args.attribute_co_authored_by = {args.attribute_co_authored_by}") # DEBUG if git is None: args.git = False @@ -892,7 +891,6 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F repo = None if args.git: try: - print(f"DEBUG: Before GitRepo init, args.attribute_co_authored_by = {args.attribute_co_authored_by}") # DEBUG repo = GitRepo( io, fnames, diff --git a/aider/repo.py b/aider/repo.py index 5a57ffb46..f0d436526 100644 --- a/aider/repo.py +++ b/aider/repo.py @@ -60,7 +60,6 @@ class GitRepo: git_commit_verify=True, attribute_co_authored_by=False, # Added parameter ): - print(f"DEBUG: GitRepo.__init__ received attribute_co_authored_by = {attribute_co_authored_by}") # DEBUG self.io = io self.models = models @@ -72,7 +71,6 @@ class GitRepo: self.attribute_commit_message_author = attribute_commit_message_author self.attribute_commit_message_committer = attribute_commit_message_committer self.attribute_co_authored_by = attribute_co_authored_by # Assign from parameter - print(f"DEBUG: GitRepo.__init__ set self.attribute_co_authored_by = {self.attribute_co_authored_by}") # DEBUG self.commit_prompt = commit_prompt self.subtree_only = subtree_only self.git_commit_verify = git_commit_verify @@ -119,8 +117,6 @@ class GitRepo: if not fnames and not self.repo.is_dirty(): return - print(f"DEBUG: GitRepo.commit start, self.attribute_co_authored_by = {self.attribute_co_authored_by}") # DEBUG - diffs = self.get_diffs(fnames) if not diffs: return @@ -145,8 +141,6 @@ class GitRepo: attribute_commit_message_committer = self.attribute_commit_message_committer attribute_co_authored_by = getattr(self, 'attribute_co_authored_by', False) - print(f"DEBUG: GitRepo.commit after retrieval, attribute_co_authored_by = {attribute_co_authored_by}") # DEBUG - commit_message_trailer = "" prefix_commit_message = False use_attribute_author = False @@ -159,7 +153,6 @@ class GitRepo: # Determine author/committer modification and trailer - print(f"DEBUG: GitRepo.commit before logic check, attribute_co_authored_by = {attribute_co_authored_by}") # DEBUG if attribute_co_authored_by: model_name = "unknown-model" if coder and hasattr(coder, "main_model") and coder.main_model.name: @@ -208,7 +201,6 @@ class GitRepo: committer_name = f"{original_user_name} (aider)" # Apply author/committer modifications based on flags determined earlier - print(f"DEBUG: GitRepo.commit before setting env, use_attribute_author={use_attribute_author}, use_attribute_committer={use_attribute_committer}") # DEBUG if use_attribute_committer: os.environ["GIT_COMMITTER_NAME"] = committer_name if use_attribute_author: From 02bc9a85c026ab4dd8aadea73156247f0d5d3131 Mon Sep 17 00:00:00 2001 From: Andrew Grigorev Date: Sat, 12 Apr 2025 18:14:08 +0300 Subject: [PATCH 42/85] Revert "chore: add test comment to dump function" This reverts commit ff8e9850ba2dd61a5ff1cc6f5b2cb30d0469082e. --- aider/dump.py | 1 - 1 file changed, 1 deletion(-) diff --git a/aider/dump.py b/aider/dump.py index 85065a97d..6098d0b73 100644 --- a/aider/dump.py +++ b/aider/dump.py @@ -13,7 +13,6 @@ def cvt(s): def dump(*vals): # This is a test comment - # This is another test comment # http://docs.python.org/library/traceback.html stack = traceback.extract_stack() vars = stack[-2][3] From cf7b35f90d45766f33327d7dbcd31c5a90c130d1 Mon Sep 17 00:00:00 2001 From: Andrew Grigorev Date: Sat, 12 Apr 2025 18:14:08 +0300 Subject: [PATCH 43/85] Revert "test: add comment for testing" This reverts commit 072bd30443ce0b3bb8cb7df2f9550446b4edb240. --- tests/fixtures/sample-code-base/sample.js | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/fixtures/sample-code-base/sample.js b/tests/fixtures/sample-code-base/sample.js index 31280539f..a934b428c 100644 --- a/tests/fixtures/sample-code-base/sample.js +++ b/tests/fixtures/sample-code-base/sample.js @@ -1,5 +1,4 @@ // Aider test commit -// Another test comment // Sample JavaScript script with 7 functions // 1. A simple greeting function From 7b8c7edfd5a122967ee03eefa0c5077ae1031d90 Mon Sep 17 00:00:00 2001 From: Andrew Grigorev Date: Sat, 12 Apr 2025 18:14:08 +0300 Subject: [PATCH 44/85] Revert "chore: Add test comment" This reverts commit d5671c2879c85f581bd504a962e8b54b6567c776. --- tests/fixtures/sample-code-base/sample.js | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/fixtures/sample-code-base/sample.js b/tests/fixtures/sample-code-base/sample.js index a934b428c..f3f2eaf58 100644 --- a/tests/fixtures/sample-code-base/sample.js +++ b/tests/fixtures/sample-code-base/sample.js @@ -1,4 +1,3 @@ -// Aider test commit // Sample JavaScript script with 7 functions // 1. A simple greeting function From aa07e16f1833fb78269286f114e2eb2ccb07b2e9 Mon Sep 17 00:00:00 2001 From: Andrew Grigorev Date: Sat, 12 Apr 2025 18:14:09 +0300 Subject: [PATCH 45/85] Revert "chore: Add test comment" This reverts commit 482e0c2d0b5cdfe60281f13bab2ead4aa540e9e6. --- aider/prompts.py | 1 - 1 file changed, 1 deletion(-) diff --git a/aider/prompts.py b/aider/prompts.py index 1dacf10d0..84ed75e9b 100644 --- a/aider/prompts.py +++ b/aider/prompts.py @@ -1,6 +1,5 @@ # flake8: noqa: E501 -# This is a test comment. # COMMIT From 427f9c5b00fb3964d71344e86452209df1422616 Mon Sep 17 00:00:00 2001 From: Andrew Grigorev Date: Sat, 12 Apr 2025 18:14:09 +0300 Subject: [PATCH 46/85] Revert "chore: Add test comment to dump function" This reverts commit e9511643998d4868bc261b3ec0479e6a2a362b3a. --- aider/dump.py | 1 - 1 file changed, 1 deletion(-) diff --git a/aider/dump.py b/aider/dump.py index 6098d0b73..2c8bf31c2 100644 --- a/aider/dump.py +++ b/aider/dump.py @@ -12,7 +12,6 @@ def cvt(s): def dump(*vals): - # This is a test comment # http://docs.python.org/library/traceback.html stack = traceback.extract_stack() vars = stack[-2][3] From c56e836d22be0139adb3d976ac49ed4db8a45ab8 Mon Sep 17 00:00:00 2001 From: Andrew Grigorev Date: Sat, 12 Apr 2025 18:19:55 +0300 Subject: [PATCH 47/85] refactor: simplify commit logic and use context manager for git env Co-authored-by: aider (vertex_ai/gemini-2.5-pro-exp-03-25) --- aider/args.py | 5 ++- aider/repo.py | 105 +++++++++++++++++++++++++------------------------- 2 files changed, 56 insertions(+), 54 deletions(-) diff --git a/aider/args.py b/aider/args.py index 3571faa5e..6d62b6dbf 100644 --- a/aider/args.py +++ b/aider/args.py @@ -428,7 +428,10 @@ def get_parser(default_config_files, git_root): "--attribute-author", action=argparse.BooleanOptionalAction, default=True, - help="Attribute aider code changes in the git author name (default: True, ignored if attribute-co-authored-by is True unless explicitly set)", + help=( + "Attribute aider code changes in the git author name (default: True). This is ignored" + " if --attribute-co-authored-by is True." + ), ) group.add_argument( "--attribute-committer", diff --git a/aider/repo.py b/aider/repo.py index f0d436526..f8a5cacfc 100644 --- a/aider/repo.py +++ b/aider/repo.py @@ -1,3 +1,4 @@ +import contextlib import os import time from pathlib import Path, PurePosixPath @@ -34,6 +35,19 @@ ANY_GIT_ERROR += [ ANY_GIT_ERROR = tuple(ANY_GIT_ERROR) +@contextlib.contextmanager +def set_git_env(var_name, value, original_value): + """Temporarily set a Git environment variable.""" + os.environ[var_name] = value + try: + yield + finally: + if original_value is not None: + os.environ[var_name] = original_value + elif var_name in os.environ: + del os.environ[var_name] + + class GitRepo: repo = None aider_ignore_file = None @@ -139,37 +153,29 @@ class GitRepo: attribute_committer = self.attribute_committer attribute_commit_message_author = self.attribute_commit_message_author attribute_commit_message_committer = self.attribute_commit_message_committer - attribute_co_authored_by = getattr(self, 'attribute_co_authored_by', False) + attribute_co_authored_by = getattr(self, "attribute_co_authored_by", False) + # Determine commit message prefixing + prefix_commit_message = aider_edits and ( + attribute_commit_message_author or attribute_commit_message_committer + ) + + # Determine Co-authored-by trailer commit_message_trailer = "" - prefix_commit_message = False - use_attribute_author = False - use_attribute_committer = False + if aider_edits and attribute_co_authored_by: + model_name = "unknown-model" + if coder and hasattr(coder, "main_model") and coder.main_model.name: + model_name = coder.main_model.name + commit_message_trailer = ( + f"\n\nCo-authored-by: aider ({model_name}) " + ) - if aider_edits: - # Determine commit message prefixing - if attribute_commit_message_author or attribute_commit_message_committer: - prefix_commit_message = True - - # Determine author/committer modification and trailer - - if attribute_co_authored_by: - model_name = "unknown-model" - if coder and hasattr(coder, "main_model") and coder.main_model.name: - model_name = coder.main_model.name - commit_message_trailer = f"\n\nCo-authored-by: aider ({model_name}) " - # If co-authored-by is used, disable author/committer name modification - use_attribute_author = False - use_attribute_committer = False - else: - # Original behavior when co-authored-by is false - use_attribute_author = attribute_author - use_attribute_committer = attribute_committer - else: # not aider_edits - # Keep original behavior for non-aider edits - use_attribute_author = False - use_attribute_committer = attribute_committer # Respect config for committer - prefix_commit_message = False # Don't prefix non-aider commits + # Determine if author/committer names should be modified + # If co-authored-by is used for aider edits, it takes precedence over direct name modification. + use_attribute_author = attribute_author and aider_edits and not attribute_co_authored_by + use_attribute_committer = attribute_committer and not ( + aider_edits and attribute_co_authored_by + ) if not commit_message: commit_message = "(no commit message provided)" @@ -178,8 +184,6 @@ class GitRepo: commit_message = "aider: " + commit_message full_commit_message = commit_message + commit_message_trailer - # if context: - # full_commit_message += "\n\n# Aider chat conversation:\n\n" + context cmd = ["-m", full_commit_message] if not self.git_commit_verify: @@ -200,32 +204,27 @@ class GitRepo: original_author_name_env = os.environ.get("GIT_AUTHOR_NAME") committer_name = f"{original_user_name} (aider)" - # Apply author/committer modifications based on flags determined earlier - if use_attribute_committer: - os.environ["GIT_COMMITTER_NAME"] = committer_name - if use_attribute_author: - os.environ["GIT_AUTHOR_NAME"] = committer_name - try: - self.repo.git.commit(cmd) - commit_hash = self.get_head_commit_sha(short=True) - self.io.tool_output(f"Commit {commit_hash} {commit_message}", bold=True) - return commit_hash, commit_message + # Use context managers to handle environment variables + with contextlib.ExitStack() as stack: + if use_attribute_committer: + stack.enter_context( + set_git_env("GIT_COMMITTER_NAME", committer_name, original_committer_name_env) + ) + if use_attribute_author: + stack.enter_context( + set_git_env("GIT_AUTHOR_NAME", committer_name, original_author_name_env) + ) + + # Perform the commit + self.repo.git.commit(cmd) + commit_hash = self.get_head_commit_sha(short=True) + self.io.tool_output(f"Commit {commit_hash} {commit_message}", bold=True) + return commit_hash, commit_message + except ANY_GIT_ERROR as err: self.io.tool_error(f"Unable to commit: {err}") - finally: - # Restore the env - if use_attribute_committer: - if original_committer_name_env is not None: - os.environ["GIT_COMMITTER_NAME"] = original_committer_name_env - elif "GIT_COMMITTER_NAME" in os.environ: - del os.environ["GIT_COMMITTER_NAME"] - - if use_attribute_author: - if original_author_name_env is not None: - os.environ["GIT_AUTHOR_NAME"] = original_author_name_env - elif "GIT_AUTHOR_NAME" in os.environ: - del os.environ["GIT_AUTHOR_NAME"] + # No return here, implicitly returns None def get_rel_repo_dir(self): try: From dd4b61da207dfe45cca6e9dee16490b048b3ed8e Mon Sep 17 00:00:00 2001 From: Andrew Grigorev Date: Sat, 12 Apr 2025 18:26:46 +0300 Subject: [PATCH 48/85] test: add test for co-authored-by precedence over author/committer Co-authored-by: aider (vertex_ai/gemini-2.5-pro-exp-03-25) --- tests/basic/test_repo.py | 54 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/tests/basic/test_repo.py b/tests/basic/test_repo.py index 2c68c8f00..57bad6625 100644 --- a/tests/basic/test_repo.py +++ b/tests/basic/test_repo.py @@ -301,6 +301,60 @@ class TestRepo(unittest.TestCase): self.assertEqual(commit.author.name, "Test User") # Should NOT be modified self.assertEqual(commit.committer.name, "Test User") # Should NOT be modified + def test_commit_co_authored_by_precedence(self): + # Test that co-authored-by takes precedence over name modification when both are enabled + if platform.system() == "Windows": + return + + with GitTemporaryDirectory(): + # new repo + raw_repo = git.Repo() + raw_repo.config_writer().set_value("user", "name", "Test User").release() + raw_repo.config_writer().set_value("user", "email", "test@example.com").release() + + # add a file and commit it + fname = Path("file.txt") + fname.touch() + raw_repo.git.add(str(fname)) + raw_repo.git.commit("-m", "initial commit") + + # Mock coder args: All relevant flags enabled + mock_coder = MagicMock() + mock_coder.args.attribute_co_authored_by = True + mock_coder.args.attribute_author = True # Explicitly enable (or rely on default) + mock_coder.args.attribute_committer = True # Explicitly enable (or rely on default) + mock_coder.args.attribute_commit_message_author = False + mock_coder.args.attribute_commit_message_committer = False + mock_coder.main_model = MagicMock() + mock_coder.main_model.name = "gpt-precedence" + + io = InputOutput() + # Initialize GitRepo directly with flags, simulating config/defaults if coder wasn't passed + # This ensures the test covers the case where coder might not provide args + git_repo = GitRepo( + io, + None, + None, + attribute_co_authored_by=True, + attribute_author=True, + attribute_committer=True, + ) + + + # commit a change with aider_edits=True and conflicting flags + fname.write_text("new content precedence") + # Pass the coder object here to ensure its args are used if available, + # but the GitRepo init already set the fallback values. + git_repo.commit(fnames=[str(fname)], aider_edits=True, coder=mock_coder, message="Aider precedence edit") + + # check the commit message and author/committer + commit = raw_repo.head.commit + self.assertIn("Co-authored-by: aider (gpt-precedence) ", commit.message) + self.assertEqual(commit.message.splitlines()[0], "Aider precedence edit") + # Co-authored-by should take precedence, names should NOT be modified + self.assertEqual(commit.author.name, "Test User") + self.assertEqual(commit.committer.name, "Test User") + def test_commit_without_co_authored_by(self): # Cleanup of the git temp dir explodes on windows From ea74f31b3e98550611e95e7108a9a63c0dd8d5c5 Mon Sep 17 00:00:00 2001 From: Andrew Grigorev Date: Sat, 12 Apr 2025 19:09:46 +0300 Subject: [PATCH 49/85] feat: Explicit author/committer flags override co-authored-by Co-authored-by: aider (vertex_ai/gemini-2.5-pro-exp-03-25) --- aider/args.py | 13 +++--- aider/repo.py | 28 ++++++++++--- tests/basic/test_repo.py | 87 +++++++++++++++++++++------------------- 3 files changed, 77 insertions(+), 51 deletions(-) diff --git a/aider/args.py b/aider/args.py index 6d62b6dbf..7aaf10f2a 100644 --- a/aider/args.py +++ b/aider/args.py @@ -427,17 +427,20 @@ def get_parser(default_config_files, git_root): group.add_argument( "--attribute-author", action=argparse.BooleanOptionalAction, - default=True, + default=None, help=( - "Attribute aider code changes in the git author name (default: True). This is ignored" - " if --attribute-co-authored-by is True." + "Attribute aider code changes in the git author name (default: True). If explicitly set" + " to True, overrides --attribute-co-authored-by precedence." ), ) group.add_argument( "--attribute-committer", action=argparse.BooleanOptionalAction, - default=True, - help="Attribute aider commits in the git committer name (default: True)", + default=None, + help=( + "Attribute aider commits in the git committer name (default: True). If explicitly set" + " to True, overrides --attribute-co-authored-by precedence for aider edits." + ), ) group.add_argument( "--attribute-commit-message-author", diff --git a/aider/repo.py b/aider/repo.py index f8a5cacfc..31bcc7957 100644 --- a/aider/repo.py +++ b/aider/repo.py @@ -153,7 +153,16 @@ class GitRepo: attribute_committer = self.attribute_committer attribute_commit_message_author = self.attribute_commit_message_author attribute_commit_message_committer = self.attribute_commit_message_committer - attribute_co_authored_by = getattr(self, "attribute_co_authored_by", False) + attribute_co_authored_by = getattr(self, "attribute_co_authored_by", False) # Should be False if not set + + # Determine explicit settings (None means use default behavior) + author_explicit = attribute_author is not None + committer_explicit = attribute_committer is not None + + # Determine effective settings (apply default True if not explicit) + effective_author = True if attribute_author is None else attribute_author + effective_committer = True if attribute_committer is None else attribute_committer + # Determine commit message prefixing prefix_commit_message = aider_edits and ( @@ -171,12 +180,21 @@ class GitRepo: ) # Determine if author/committer names should be modified - # If co-authored-by is used for aider edits, it takes precedence over direct name modification. - use_attribute_author = attribute_author and aider_edits and not attribute_co_authored_by - use_attribute_committer = attribute_committer and not ( - aider_edits and attribute_co_authored_by + # Author modification applies only to aider edits. + # It's used if effective_author is True AND (co-authored-by is False OR author was explicitly set). + use_attribute_author = ( + aider_edits + and effective_author + and (not attribute_co_authored_by or author_explicit) ) + # Committer modification applies regardless of aider_edits (based on tests). + # It's used if effective_committer is True AND (it's not an aider edit with co-authored-by OR committer was explicitly set). + use_attribute_committer = effective_committer and ( + not (aider_edits and attribute_co_authored_by) or committer_explicit + ) + + if not commit_message: commit_message = "(no commit message provided)" diff --git a/tests/basic/test_repo.py b/tests/basic/test_repo.py index 57bad6625..e7026a242 100644 --- a/tests/basic/test_repo.py +++ b/tests/basic/test_repo.py @@ -185,26 +185,35 @@ class TestRepo(unittest.TestCase): raw_repo.git.commit("-m", "initial commit") io = InputOutput() - git_repo = GitRepo(io, None, None) + # Initialize GitRepo with default None values for attributes + git_repo = GitRepo(io, None, None, attribute_author=None, attribute_committer=None) - # commit a change + # commit a change with aider_edits=True (using default attributes) fname.write_text("new content") git_repo.commit(fnames=[str(fname)], aider_edits=True) - # check the committer name + # check the committer name (defaults interpreted as True) commit = raw_repo.head.commit self.assertEqual(commit.author.name, "Test User (aider)") self.assertEqual(commit.committer.name, "Test User (aider)") - # commit a change without aider_edits + # commit a change without aider_edits (using default attributes) fname.write_text("new content again!") git_repo.commit(fnames=[str(fname)], aider_edits=False) - # check the committer name + # check the committer name (author not modified, committer still modified by default) commit = raw_repo.head.commit self.assertEqual(commit.author.name, "Test User") self.assertEqual(commit.committer.name, "Test User (aider)") + # Now test with explicit False + git_repo_explicit_false = GitRepo(io, None, None, attribute_author=False, attribute_committer=False) + fname.write_text("explicit false content") + git_repo_explicit_false.commit(fnames=[str(fname)], aider_edits=True) + commit = raw_repo.head.commit + self.assertEqual(commit.author.name, "Test User") # Explicit False + self.assertEqual(commit.committer.name, "Test User") # Explicit False + # check that the original committer name is restored original_committer_name = os.environ.get("GIT_COMMITTER_NAME") self.assertIsNone(original_committer_name) @@ -228,15 +237,13 @@ class TestRepo(unittest.TestCase): raw_repo.git.add(str(fname)) raw_repo.git.commit("-m", "initial commit") - # Mock coder args - # Mock coder args: Co-authored-by enabled, author/committer modification disabled + # Mock coder args: Co-authored-by enabled, author/committer use default (None) mock_coder = MagicMock() mock_coder.args.attribute_co_authored_by = True - mock_coder.args.attribute_author = False # Explicitly disable name modification - mock_coder.args.attribute_committer = False # Explicitly disable name modification + mock_coder.args.attribute_author = None # Default + mock_coder.args.attribute_committer = None # Default mock_coder.args.attribute_commit_message_author = False mock_coder.args.attribute_commit_message_committer = False - # Set the model name correctly on the nested mock # The code uses coder.main_model.name for the co-authored-by line mock_coder.main_model = MagicMock() mock_coder.main_model.name = "gpt-test" @@ -253,16 +260,17 @@ class TestRepo(unittest.TestCase): commit = raw_repo.head.commit self.assertIn("Co-authored-by: aider (gpt-test) ", commit.message) self.assertEqual(commit.message.splitlines()[0], "Aider edit") + # With default (None), co-authored-by takes precedence self.assertEqual(commit.author.name, "Test User") # Should NOT be modified self.assertEqual(commit.committer.name, "Test User") # Should NOT be modified - def test_commit_with_co_authored_by_and_name_modification(self): - # Test scenario where Co-authored-by is true AND author/committer modification is also true (default) - # Cleanup of the git temp dir explodes on windows + def test_commit_co_authored_by_with_explicit_name_modification(self): + # Test scenario where Co-authored-by is true AND author/committer modification are explicitly True if platform.system() == "Windows": return with GitTemporaryDirectory(): + # Setup repo... # new repo raw_repo = git.Repo() raw_repo.config_writer().set_value("user", "name", "Test User").release() @@ -274,14 +282,13 @@ class TestRepo(unittest.TestCase): raw_repo.git.add(str(fname)) raw_repo.git.commit("-m", "initial commit") - # Mock coder args: Co-authored-by enabled, author/committer modification enabled (default) + # Mock coder args: Co-authored-by enabled, author/committer modification explicitly enabled mock_coder = MagicMock() mock_coder.args.attribute_co_authored_by = True - mock_coder.args.attribute_author = True # Explicitly enable (or rely on default) - mock_coder.args.attribute_committer = True # Explicitly enable (or rely on default) + mock_coder.args.attribute_author = True # Explicitly enable + mock_coder.args.attribute_committer = True # Explicitly enable mock_coder.args.attribute_commit_message_author = False mock_coder.args.attribute_commit_message_committer = False - # Set the model name correctly on the nested mock mock_coder.main_model = MagicMock() mock_coder.main_model.name = "gpt-test-combo" @@ -297,12 +304,12 @@ class TestRepo(unittest.TestCase): commit = raw_repo.head.commit self.assertIn("Co-authored-by: aider (gpt-test-combo) ", commit.message) self.assertEqual(commit.message.splitlines()[0], "Aider combo edit") - # When co-authored-by is true, name modification should be disabled - self.assertEqual(commit.author.name, "Test User") # Should NOT be modified - self.assertEqual(commit.committer.name, "Test User") # Should NOT be modified + # When co-authored-by is true BUT author/committer are explicit True, modification SHOULD happen + self.assertEqual(commit.author.name, "Test User (aider)") # Should be modified + self.assertEqual(commit.committer.name, "Test User (aider)") # Should be modified - def test_commit_co_authored_by_precedence(self): - # Test that co-authored-by takes precedence over name modification when both are enabled + def test_commit_co_authored_by_precedence_over_default(self): + # Test that co-authored-by takes precedence over default (None) name modification if platform.system() == "Windows": return @@ -318,30 +325,29 @@ class TestRepo(unittest.TestCase): raw_repo.git.add(str(fname)) raw_repo.git.commit("-m", "initial commit") - # Mock coder args: All relevant flags enabled + # Mock coder args: Co-authored-by enabled, author/committer use default (None) mock_coder = MagicMock() mock_coder.args.attribute_co_authored_by = True - mock_coder.args.attribute_author = True # Explicitly enable (or rely on default) - mock_coder.args.attribute_committer = True # Explicitly enable (or rely on default) + mock_coder.args.attribute_author = None # Default + mock_coder.args.attribute_committer = None # Default mock_coder.args.attribute_commit_message_author = False mock_coder.args.attribute_commit_message_committer = False - mock_coder.main_model = MagicMock() + mock_coder.main_model = MagicMock() # Define main_model before accessing name mock_coder.main_model.name = "gpt-precedence" io = InputOutput() - # Initialize GitRepo directly with flags, simulating config/defaults if coder wasn't passed - # This ensures the test covers the case where coder might not provide args + # Initialize GitRepo directly with flags, simulating config/defaults + # Use None for author/committer to test default behavior git_repo = GitRepo( io, None, None, attribute_co_authored_by=True, - attribute_author=True, - attribute_committer=True, + attribute_author=None, # Default + attribute_committer=None, # Default ) - - # commit a change with aider_edits=True and conflicting flags + # commit a change with aider_edits=True and default flags fname.write_text("new content precedence") # Pass the coder object here to ensure its args are used if available, # but the GitRepo init already set the fallback values. @@ -351,13 +357,13 @@ class TestRepo(unittest.TestCase): commit = raw_repo.head.commit self.assertIn("Co-authored-by: aider (gpt-precedence) ", commit.message) self.assertEqual(commit.message.splitlines()[0], "Aider precedence edit") - # Co-authored-by should take precedence, names should NOT be modified + # Co-authored-by should take precedence over default (None), names should NOT be modified self.assertEqual(commit.author.name, "Test User") self.assertEqual(commit.committer.name, "Test User") def test_commit_without_co_authored_by(self): - # Cleanup of the git temp dir explodes on windows + # Test standard name modification when co-authored-by is False if platform.system() == "Windows": return @@ -373,14 +379,13 @@ class TestRepo(unittest.TestCase): raw_repo.git.add(str(fname)) raw_repo.git.commit("-m", "initial commit") - # Mock coder args (default behavior) + # Mock coder args (co-authored-by False, author/committer default None) mock_coder = MagicMock() mock_coder.args.attribute_co_authored_by = False - mock_coder.args.attribute_author = True - mock_coder.args.attribute_committer = True + mock_coder.args.attribute_author = None # Default + mock_coder.args.attribute_committer = None # Default mock_coder.args.attribute_commit_message_author = False mock_coder.args.attribute_commit_message_committer = False - # Set the model name correctly on the nested mock (though not used in this test assertion) mock_coder.main_model = MagicMock() mock_coder.main_model.name = "gpt-test-no-coauthor" @@ -392,12 +397,12 @@ class TestRepo(unittest.TestCase): fname.write_text("new content") git_repo.commit(fnames=[str(fname)], aider_edits=True, coder=mock_coder, message="Aider edit") - # check the commit message and author/committer + # check the commit message and author/committer (defaults interpreted as True) commit = raw_repo.head.commit self.assertNotIn("Co-authored-by:", commit.message) self.assertEqual(commit.message.splitlines()[0], "Aider edit") - self.assertEqual(commit.author.name, "Test User (aider)") # Should be modified - self.assertEqual(commit.committer.name, "Test User (aider)") # Should be modified + self.assertEqual(commit.author.name, "Test User (aider)") # Should be modified (default True) + self.assertEqual(commit.committer.name, "Test User (aider)") # Should be modified (default True) def test_get_tracked_files(self): From 278a596bfafd8f9e596f64732d83194271bc0e4d Mon Sep 17 00:00:00 2001 From: Andrew Grigorev Date: Sat, 12 Apr 2025 19:21:03 +0300 Subject: [PATCH 50/85] docs: clarify commit author/committer/co-authored-by logic Co-authored-by: aider (vertex_ai/gemini-2.5-pro-exp-03-25) --- aider/repo.py | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/aider/repo.py b/aider/repo.py index 31bcc7957..ad87a379a 100644 --- a/aider/repo.py +++ b/aider/repo.py @@ -128,6 +128,70 @@ class GitRepo: self.aider_ignore_file = Path(aider_ignore_file) def commit(self, fnames=None, context=None, message=None, aider_edits=False, coder=None): + """ + Commit the specified files or all dirty files if none are specified. + + Args: + fnames (list, optional): List of filenames to commit. Defaults to None (commit all + dirty files). + context (str, optional): Context for generating the commit message. Defaults to None. + message (str, optional): Explicit commit message. Defaults to None (generate message). + aider_edits (bool, optional): Whether the changes were made by Aider. Defaults to False. + This affects attribution logic. + coder (Coder, optional): The Coder instance, used to access config and model info. + Defaults to None. + + Returns: + tuple(str, str) or None: The commit hash and commit message if successful, else None. + + Attribution Logic: + ------------------ + This method handles Git commit attribution based on configuration flags and whether + Aider generated the changes (`aider_edits`). + + Key Concepts: + - Author: The person who originally wrote the code changes. + - Committer: The person who last applied the commit to the repository. + - aider_edits=True: Changes were generated by Aider (LLM). + - aider_edits=False: Commit is user-driven (e.g., /commit manually staged changes). + - Explicit Setting: A flag (--attribute-...) is set to True or False via command line + or config file. + - Implicit Default: A flag is not explicitly set, defaulting to None in args, which is + interpreted as True unless overridden by other logic. + + Flags: + - --attribute-author: Modify Author name to "User Name (aider)". + - --attribute-committer: Modify Committer name to "User Name (aider)". + - --attribute-co-authored-by: Add "Co-authored-by: aider () " + trailer to the commit message. + + Behavior Summary: + + 1. When aider_edits = True (AI Changes): + - If --attribute-co-authored-by=True: + - Co-authored-by trailer IS ADDED. + - Author/Committer names are NOT modified by default (co-authored-by takes precedence). + - EXCEPTION: If --attribute-author/--attribute-committer is EXPLICITLY True, + the respective name IS modified (explicit overrides precedence). + - If --attribute-co-authored-by=False: + - Co-authored-by trailer is NOT added. + - Author/Committer names ARE modified by default (implicit True). + - EXCEPTION: If --attribute-author/--attribute-committer is EXPLICITLY False, + the respective name is NOT modified. + + 2. When aider_edits = False (User Changes): + - --attribute-co-authored-by is IGNORED (trailer never added). + - Author name is NEVER modified (--attribute-author ignored). + - Committer name IS modified by default (implicit True, as Aider runs `git commit`). + - EXCEPTION: If --attribute-committer is EXPLICITLY False, the name is NOT modified. + + Resulting Scenarios: + - Standard AI edit (defaults): Co-authored-by=False -> Author=You(aider), Committer=You(aider) + - AI edit with Co-authored-by (default): Co-authored-by=True -> Author=You, Committer=You, Trailer added + - AI edit with Co-authored-by + Explicit Author: Co-authored-by=True, --attribute-author -> Author=You(aider), Committer=You, Trailer added + - User commit (defaults): aider_edits=False -> Author=You, Committer=You(aider) + - User commit with explicit no-committer: aider_edits=False, --no-attribute-committer -> Author=You, Committer=You + """ if not fnames and not self.repo.is_dirty(): return From 5664b5b195aa53f507376efc407dc49e204f3a0b Mon Sep 17 00:00:00 2001 From: Andrew Grigorev Date: Sat, 12 Apr 2025 19:41:24 +0300 Subject: [PATCH 51/85] test: Assert commit return value in more tests Co-authored-by: aider (vertex_ai/gemini-2.0-flash-lite-001) --- tests/basic/test_repo.py | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/tests/basic/test_repo.py b/tests/basic/test_repo.py index e7026a242..287d5ea16 100644 --- a/tests/basic/test_repo.py +++ b/tests/basic/test_repo.py @@ -190,7 +190,8 @@ class TestRepo(unittest.TestCase): # commit a change with aider_edits=True (using default attributes) fname.write_text("new content") - git_repo.commit(fnames=[str(fname)], aider_edits=True) + commit_result = git_repo.commit(fnames=[str(fname)], aider_edits=True) + self.assertIsNotNone(commit_result) # check the committer name (defaults interpreted as True) commit = raw_repo.head.commit @@ -199,7 +200,8 @@ class TestRepo(unittest.TestCase): # commit a change without aider_edits (using default attributes) fname.write_text("new content again!") - git_repo.commit(fnames=[str(fname)], aider_edits=False) + commit_result = git_repo.commit(fnames=[str(fname)], aider_edits=False) + self.assertIsNotNone(commit_result) # check the committer name (author not modified, committer still modified by default) commit = raw_repo.head.commit @@ -209,7 +211,8 @@ class TestRepo(unittest.TestCase): # Now test with explicit False git_repo_explicit_false = GitRepo(io, None, None, attribute_author=False, attribute_committer=False) fname.write_text("explicit false content") - git_repo_explicit_false.commit(fnames=[str(fname)], aider_edits=True) + commit_result = git_repo_explicit_false.commit(fnames=[str(fname)], aider_edits=True) + self.assertIsNotNone(commit_result) commit = raw_repo.head.commit self.assertEqual(commit.author.name, "Test User") # Explicit False self.assertEqual(commit.committer.name, "Test User") # Explicit False @@ -254,7 +257,8 @@ class TestRepo(unittest.TestCase): # commit a change with aider_edits=True and co-authored-by flag fname.write_text("new content") - git_repo.commit(fnames=[str(fname)], aider_edits=True, coder=mock_coder, message="Aider edit") + commit_result = git_repo.commit(fnames=[str(fname)], aider_edits=True, coder=mock_coder, message="Aider edit") + self.assertIsNotNone(commit_result) # check the commit message and author/committer commit = raw_repo.head.commit @@ -298,7 +302,8 @@ class TestRepo(unittest.TestCase): # commit a change with aider_edits=True and combo flags fname.write_text("new content combo") - git_repo.commit(fnames=[str(fname)], aider_edits=True, coder=mock_coder, message="Aider combo edit") + commit_result = git_repo.commit(fnames=[str(fname)], aider_edits=True, coder=mock_coder, message="Aider combo edit") + self.assertIsNotNone(commit_result) # check the commit message and author/committer commit = raw_repo.head.commit @@ -351,7 +356,8 @@ class TestRepo(unittest.TestCase): fname.write_text("new content precedence") # Pass the coder object here to ensure its args are used if available, # but the GitRepo init already set the fallback values. - git_repo.commit(fnames=[str(fname)], aider_edits=True, coder=mock_coder, message="Aider precedence edit") + commit_result = git_repo.commit(fnames=[str(fname)], aider_edits=True, coder=mock_coder, message="Aider precedence edit") + self.assertIsNotNone(commit_result) # check the commit message and author/committer commit = raw_repo.head.commit @@ -395,7 +401,8 @@ class TestRepo(unittest.TestCase): # commit a change with aider_edits=True and default flags fname.write_text("new content") - git_repo.commit(fnames=[str(fname)], aider_edits=True, coder=mock_coder, message="Aider edit") + commit_result = git_repo.commit(fnames=[str(fname)], aider_edits=True, coder=mock_coder, message="Aider edit") + self.assertIsNotNone(commit_result) # check the commit message and author/committer (defaults interpreted as True) commit = raw_repo.head.commit @@ -598,7 +605,8 @@ class TestRepo(unittest.TestCase): git_repo = GitRepo(InputOutput(), None, None) - git_repo.commit(fnames=[str(fname)]) + commit_result = git_repo.commit(fnames=[str(fname)]) + self.assertIsNotNone(commit_result) def test_git_commit_verify(self): """Test that git_commit_verify controls whether --no-verify is passed to git commit""" From 37a252748a68bb26398ea38e92472e94166abbb5 Mon Sep 17 00:00:00 2001 From: Andrew Grigorev Date: Sat, 12 Apr 2025 19:45:01 +0300 Subject: [PATCH 52/85] test: Fix commit result assertion in test_noop_commit --- tests/basic/test_repo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/basic/test_repo.py b/tests/basic/test_repo.py index 287d5ea16..88c4b4edf 100644 --- a/tests/basic/test_repo.py +++ b/tests/basic/test_repo.py @@ -606,7 +606,7 @@ class TestRepo(unittest.TestCase): git_repo = GitRepo(InputOutput(), None, None) commit_result = git_repo.commit(fnames=[str(fname)]) - self.assertIsNotNone(commit_result) + self.assertIsNone(commit_result) def test_git_commit_verify(self): """Test that git_commit_verify controls whether --no-verify is passed to git commit""" From d991cb67219e0728679bf5d00773f12619c97279 Mon Sep 17 00:00:00 2001 From: Andrew Grigorev Date: Sat, 12 Apr 2025 19:54:56 +0300 Subject: [PATCH 53/85] test: cover user commit with no committer attribution Co-authored-by: aider (vertex_ai/gemini-2.5-pro-exp-03-25) --- tests/basic/test_repo.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/basic/test_repo.py b/tests/basic/test_repo.py index 88c4b4edf..9633ec208 100644 --- a/tests/basic/test_repo.py +++ b/tests/basic/test_repo.py @@ -223,6 +223,15 @@ class TestRepo(unittest.TestCase): original_author_name = os.environ.get("GIT_AUTHOR_NAME") self.assertIsNone(original_author_name) + # Test user commit with explicit no-committer attribution + git_repo_user_no_committer = GitRepo(io, None, None, attribute_committer=False) + fname.write_text("user no committer content") + commit_result = git_repo_user_no_committer.commit(fnames=[str(fname)], aider_edits=False) + self.assertIsNotNone(commit_result) + commit = raw_repo.head.commit + self.assertEqual(commit.author.name, "Test User") # Author never modified for user commits + self.assertEqual(commit.committer.name, "Test User") # Explicit False prevents modification + def test_commit_with_co_authored_by(self): # Cleanup of the git temp dir explodes on windows if platform.system() == "Windows": From 3e1bc77bf20ceec54699fc1141b6d90aaf1adc1a Mon Sep 17 00:00:00 2001 From: Andrew Grigorev Date: Sat, 12 Apr 2025 19:56:18 +0300 Subject: [PATCH 54/85] test: add tests for commit author/committer attribution logic Co-authored-by: aider (vertex_ai/gemini-2.5-pro-exp-03-25) --- tests/basic/test_repo.py | 115 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) diff --git a/tests/basic/test_repo.py b/tests/basic/test_repo.py index 9633ec208..5d1ff335b 100644 --- a/tests/basic/test_repo.py +++ b/tests/basic/test_repo.py @@ -420,6 +420,121 @@ class TestRepo(unittest.TestCase): self.assertEqual(commit.author.name, "Test User (aider)") # Should be modified (default True) self.assertEqual(commit.committer.name, "Test User (aider)") # Should be modified (default True) + def test_commit_ai_edits_no_coauthor_explicit_false(self): + # Test AI edits (aider_edits=True) when co-authored-by is False, + # but author or committer attribution is explicitly disabled. + if platform.system() == "Windows": + return + + with GitTemporaryDirectory(): + # Setup repo + raw_repo = git.Repo() + raw_repo.config_writer().set_value("user", "name", "Test User").release() + raw_repo.config_writer().set_value("user", "email", "test@example.com").release() + fname = Path("file.txt") + fname.touch() + raw_repo.git.add(str(fname)) + raw_repo.git.commit("-m", "initial commit") + + io = InputOutput() + + # Case 1: attribute_author = False, attribute_committer = None (default True) + mock_coder_no_author = MagicMock() + mock_coder_no_author.args.attribute_co_authored_by = False + mock_coder_no_author.args.attribute_author = False # Explicit False + mock_coder_no_author.args.attribute_committer = None # Default True + mock_coder_no_author.args.attribute_commit_message_author = False + mock_coder_no_author.args.attribute_commit_message_committer = False + mock_coder_no_author.main_model = MagicMock() + mock_coder_no_author.main_model.name = "gpt-test-no-author" + + git_repo_no_author = GitRepo(io, None, None) + fname.write_text("no author content") + commit_result = git_repo_no_author.commit(fnames=[str(fname)], aider_edits=True, coder=mock_coder_no_author, message="Aider no author") + self.assertIsNotNone(commit_result) + commit = raw_repo.head.commit + self.assertNotIn("Co-authored-by:", commit.message) + self.assertEqual(commit.author.name, "Test User") # Explicit False + self.assertEqual(commit.committer.name, "Test User (aider)") # Default True + + # Case 2: attribute_author = None (default True), attribute_committer = False + mock_coder_no_committer = MagicMock() + mock_coder_no_committer.args.attribute_co_authored_by = False + mock_coder_no_committer.args.attribute_author = None # Default True + mock_coder_no_committer.args.attribute_committer = False # Explicit False + mock_coder_no_committer.args.attribute_commit_message_author = False + mock_coder_no_committer.args.attribute_commit_message_committer = False + mock_coder_no_committer.main_model = MagicMock() + mock_coder_no_committer.main_model.name = "gpt-test-no-committer" + + git_repo_no_committer = GitRepo(io, None, None) + fname.write_text("no committer content") + commit_result = git_repo_no_committer.commit(fnames=[str(fname)], aider_edits=True, coder=mock_coder_no_committer, message="Aider no committer") + self.assertIsNotNone(commit_result) + commit = raw_repo.head.commit + self.assertNotIn("Co-authored-by:", commit.message) + self.assertEqual(commit.author.name, "Test User (aider)") # Default True + self.assertEqual(commit.committer.name, "Test User") # Explicit False + + + def test_commit_user_edits_ignores_co_author(self): + # Test user edits (aider_edits=False) behavior regarding co-author and name attribution. + # Co-author should be ignored, Author never modified, Committer follows flag. + if platform.system() == "Windows": + return + + with GitTemporaryDirectory(): + # Setup repo + raw_repo = git.Repo() + raw_repo.config_writer().set_value("user", "name", "Test User").release() + raw_repo.config_writer().set_value("user", "email", "test@example.com").release() + fname = Path("file.txt") + fname.touch() + raw_repo.git.add(str(fname)) + raw_repo.git.commit("-m", "initial commit") + + io = InputOutput() + + # Case 1: co_author=True, committer=None (default True) + mock_coder_user_default = MagicMock() + mock_coder_user_default.args.attribute_co_authored_by = True # Should be ignored + mock_coder_user_default.args.attribute_author = True # Should be ignored + mock_coder_user_default.args.attribute_committer = None # Default True + mock_coder_user_default.args.attribute_commit_message_author = False + mock_coder_user_default.args.attribute_commit_message_committer = False + mock_coder_user_default.main_model = MagicMock() + mock_coder_user_default.main_model.name = "gpt-user-default" + + git_repo_user_default = GitRepo(io, None, None) + fname.write_text("user default content") + commit_result = git_repo_user_default.commit(fnames=[str(fname)], aider_edits=False, coder=mock_coder_user_default, message="User default") + self.assertIsNotNone(commit_result) + commit = raw_repo.head.commit + self.assertNotIn("Co-authored-by:", commit.message) # Ignored + self.assertEqual(commit.author.name, "Test User") # Never modified + self.assertEqual(commit.committer.name, "Test User (aider)") # Default True + + # Case 2: co_author=True, committer=False + mock_coder_user_no_committer = MagicMock() + mock_coder_user_no_committer.args.attribute_co_authored_by = True # Should be ignored + mock_coder_user_no_committer.args.attribute_author = True # Should be ignored + mock_coder_user_no_committer.args.attribute_committer = False # Explicit False + mock_coder_user_no_committer.args.attribute_commit_message_author = False + mock_coder_user_no_committer.args.attribute_commit_message_committer = False + mock_coder_user_no_committer.main_model = MagicMock() + mock_coder_user_no_committer.main_model.name = "gpt-user-no-committer" + + # Need to init GitRepo with attribute_committer=False for this case + git_repo_user_no_committer = GitRepo(io, None, None, attribute_committer=False) + fname.write_text("user no committer content") + # Pass coder to simulate args being present, though GitRepo init matters more here + commit_result = git_repo_user_no_committer.commit(fnames=[str(fname)], aider_edits=False, coder=mock_coder_user_no_committer, message="User no committer") + self.assertIsNotNone(commit_result) + commit = raw_repo.head.commit + self.assertNotIn("Co-authored-by:", commit.message) # Ignored + self.assertEqual(commit.author.name, "Test User") # Never modified + self.assertEqual(commit.committer.name, "Test User") # Explicit False + def test_get_tracked_files(self): # Create a temporary directory From 9e91e8f1b2d2a0b13567da85da85fbfe046314bb Mon Sep 17 00:00:00 2001 From: Andrew Grigorev Date: Sat, 12 Apr 2025 19:58:06 +0300 Subject: [PATCH 55/85] test: remove redundant commit attribution tests Co-authored-by: aider (vertex_ai/gemini-2.5-pro-exp-03-25) --- tests/basic/test_repo.py | 104 --------------------------------------- 1 file changed, 104 deletions(-) diff --git a/tests/basic/test_repo.py b/tests/basic/test_repo.py index 5d1ff335b..a1224ce02 100644 --- a/tests/basic/test_repo.py +++ b/tests/basic/test_repo.py @@ -376,50 +376,6 @@ class TestRepo(unittest.TestCase): self.assertEqual(commit.author.name, "Test User") self.assertEqual(commit.committer.name, "Test User") - - def test_commit_without_co_authored_by(self): - # Test standard name modification when co-authored-by is False - if platform.system() == "Windows": - return - - with GitTemporaryDirectory(): - # new repo - raw_repo = git.Repo() - raw_repo.config_writer().set_value("user", "name", "Test User").release() - raw_repo.config_writer().set_value("user", "email", "test@example.com").release() - - # add a file and commit it - fname = Path("file.txt") - fname.touch() - raw_repo.git.add(str(fname)) - raw_repo.git.commit("-m", "initial commit") - - # Mock coder args (co-authored-by False, author/committer default None) - mock_coder = MagicMock() - mock_coder.args.attribute_co_authored_by = False - mock_coder.args.attribute_author = None # Default - mock_coder.args.attribute_committer = None # Default - mock_coder.args.attribute_commit_message_author = False - mock_coder.args.attribute_commit_message_committer = False - mock_coder.main_model = MagicMock() - mock_coder.main_model.name = "gpt-test-no-coauthor" - - - io = InputOutput() - git_repo = GitRepo(io, None, None) - - # commit a change with aider_edits=True and default flags - fname.write_text("new content") - commit_result = git_repo.commit(fnames=[str(fname)], aider_edits=True, coder=mock_coder, message="Aider edit") - self.assertIsNotNone(commit_result) - - # check the commit message and author/committer (defaults interpreted as True) - commit = raw_repo.head.commit - self.assertNotIn("Co-authored-by:", commit.message) - self.assertEqual(commit.message.splitlines()[0], "Aider edit") - self.assertEqual(commit.author.name, "Test User (aider)") # Should be modified (default True) - self.assertEqual(commit.committer.name, "Test User (aider)") # Should be modified (default True) - def test_commit_ai_edits_no_coauthor_explicit_false(self): # Test AI edits (aider_edits=True) when co-authored-by is False, # but author or committer attribution is explicitly disabled. @@ -476,66 +432,6 @@ class TestRepo(unittest.TestCase): self.assertEqual(commit.author.name, "Test User (aider)") # Default True self.assertEqual(commit.committer.name, "Test User") # Explicit False - - def test_commit_user_edits_ignores_co_author(self): - # Test user edits (aider_edits=False) behavior regarding co-author and name attribution. - # Co-author should be ignored, Author never modified, Committer follows flag. - if platform.system() == "Windows": - return - - with GitTemporaryDirectory(): - # Setup repo - raw_repo = git.Repo() - raw_repo.config_writer().set_value("user", "name", "Test User").release() - raw_repo.config_writer().set_value("user", "email", "test@example.com").release() - fname = Path("file.txt") - fname.touch() - raw_repo.git.add(str(fname)) - raw_repo.git.commit("-m", "initial commit") - - io = InputOutput() - - # Case 1: co_author=True, committer=None (default True) - mock_coder_user_default = MagicMock() - mock_coder_user_default.args.attribute_co_authored_by = True # Should be ignored - mock_coder_user_default.args.attribute_author = True # Should be ignored - mock_coder_user_default.args.attribute_committer = None # Default True - mock_coder_user_default.args.attribute_commit_message_author = False - mock_coder_user_default.args.attribute_commit_message_committer = False - mock_coder_user_default.main_model = MagicMock() - mock_coder_user_default.main_model.name = "gpt-user-default" - - git_repo_user_default = GitRepo(io, None, None) - fname.write_text("user default content") - commit_result = git_repo_user_default.commit(fnames=[str(fname)], aider_edits=False, coder=mock_coder_user_default, message="User default") - self.assertIsNotNone(commit_result) - commit = raw_repo.head.commit - self.assertNotIn("Co-authored-by:", commit.message) # Ignored - self.assertEqual(commit.author.name, "Test User") # Never modified - self.assertEqual(commit.committer.name, "Test User (aider)") # Default True - - # Case 2: co_author=True, committer=False - mock_coder_user_no_committer = MagicMock() - mock_coder_user_no_committer.args.attribute_co_authored_by = True # Should be ignored - mock_coder_user_no_committer.args.attribute_author = True # Should be ignored - mock_coder_user_no_committer.args.attribute_committer = False # Explicit False - mock_coder_user_no_committer.args.attribute_commit_message_author = False - mock_coder_user_no_committer.args.attribute_commit_message_committer = False - mock_coder_user_no_committer.main_model = MagicMock() - mock_coder_user_no_committer.main_model.name = "gpt-user-no-committer" - - # Need to init GitRepo with attribute_committer=False for this case - git_repo_user_no_committer = GitRepo(io, None, None, attribute_committer=False) - fname.write_text("user no committer content") - # Pass coder to simulate args being present, though GitRepo init matters more here - commit_result = git_repo_user_no_committer.commit(fnames=[str(fname)], aider_edits=False, coder=mock_coder_user_no_committer, message="User no committer") - self.assertIsNotNone(commit_result) - commit = raw_repo.head.commit - self.assertNotIn("Co-authored-by:", commit.message) # Ignored - self.assertEqual(commit.author.name, "Test User") # Never modified - self.assertEqual(commit.committer.name, "Test User") # Explicit False - - def test_get_tracked_files(self): # Create a temporary directory tempdir = Path(tempfile.mkdtemp()) From 6a970c35152c350797bf44ee10f69ca23cd61dfa Mon Sep 17 00:00:00 2001 From: Andrew Grigorev Date: Sat, 12 Apr 2025 19:58:29 +0300 Subject: [PATCH 56/85] test: remove redundant co-authored-by precedence test Co-authored-by: aider (vertex_ai/gemini-2.5-pro-exp-03-25) --- tests/basic/test_repo.py | 54 ---------------------------------------- 1 file changed, 54 deletions(-) diff --git a/tests/basic/test_repo.py b/tests/basic/test_repo.py index a1224ce02..11523996f 100644 --- a/tests/basic/test_repo.py +++ b/tests/basic/test_repo.py @@ -322,60 +322,6 @@ class TestRepo(unittest.TestCase): self.assertEqual(commit.author.name, "Test User (aider)") # Should be modified self.assertEqual(commit.committer.name, "Test User (aider)") # Should be modified - def test_commit_co_authored_by_precedence_over_default(self): - # Test that co-authored-by takes precedence over default (None) name modification - if platform.system() == "Windows": - return - - with GitTemporaryDirectory(): - # new repo - raw_repo = git.Repo() - raw_repo.config_writer().set_value("user", "name", "Test User").release() - raw_repo.config_writer().set_value("user", "email", "test@example.com").release() - - # add a file and commit it - fname = Path("file.txt") - fname.touch() - raw_repo.git.add(str(fname)) - raw_repo.git.commit("-m", "initial commit") - - # Mock coder args: Co-authored-by enabled, author/committer use default (None) - mock_coder = MagicMock() - mock_coder.args.attribute_co_authored_by = True - mock_coder.args.attribute_author = None # Default - mock_coder.args.attribute_committer = None # Default - mock_coder.args.attribute_commit_message_author = False - mock_coder.args.attribute_commit_message_committer = False - mock_coder.main_model = MagicMock() # Define main_model before accessing name - mock_coder.main_model.name = "gpt-precedence" - - io = InputOutput() - # Initialize GitRepo directly with flags, simulating config/defaults - # Use None for author/committer to test default behavior - git_repo = GitRepo( - io, - None, - None, - attribute_co_authored_by=True, - attribute_author=None, # Default - attribute_committer=None, # Default - ) - - # commit a change with aider_edits=True and default flags - fname.write_text("new content precedence") - # Pass the coder object here to ensure its args are used if available, - # but the GitRepo init already set the fallback values. - commit_result = git_repo.commit(fnames=[str(fname)], aider_edits=True, coder=mock_coder, message="Aider precedence edit") - self.assertIsNotNone(commit_result) - - # check the commit message and author/committer - commit = raw_repo.head.commit - self.assertIn("Co-authored-by: aider (gpt-precedence) ", commit.message) - self.assertEqual(commit.message.splitlines()[0], "Aider precedence edit") - # Co-authored-by should take precedence over default (None), names should NOT be modified - self.assertEqual(commit.author.name, "Test User") - self.assertEqual(commit.committer.name, "Test User") - def test_commit_ai_edits_no_coauthor_explicit_false(self): # Test AI edits (aider_edits=True) when co-authored-by is False, # but author or committer attribution is explicitly disabled. From 5851d66174af65ffea837c57c22e51893898b229 Mon Sep 17 00:00:00 2001 From: Andrew Grigorev Date: Sat, 12 Apr 2025 20:00:44 +0300 Subject: [PATCH 57/85] test: improve test clarity with skipIf and assertion messages Co-authored-by: aider (vertex_ai/gemini-2.5-pro-exp-03-25) --- tests/basic/test_repo.py | 39 +++++++++++++-------------------------- 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/tests/basic/test_repo.py b/tests/basic/test_repo.py index 11523996f..4d5abac86 100644 --- a/tests/basic/test_repo.py +++ b/tests/basic/test_repo.py @@ -165,14 +165,11 @@ class TestRepo(unittest.TestCase): args = mock_send.call_args[0] # Get positional args self.assertEqual(args[0][0]["content"], custom_prompt) # Check first message content + @unittest.skipIf(platform.system() == "Windows", "Git env var behavior differs on Windows") @patch("aider.repo.GitRepo.get_commit_message") def test_commit_with_custom_committer_name(self, mock_send): mock_send.return_value = '"a good commit message"' - # Cleanup of the git temp dir explodes on windows - if platform.system() == "Windows": - return - with GitTemporaryDirectory(): # new repo raw_repo = git.Repo() @@ -229,14 +226,11 @@ class TestRepo(unittest.TestCase): commit_result = git_repo_user_no_committer.commit(fnames=[str(fname)], aider_edits=False) self.assertIsNotNone(commit_result) commit = raw_repo.head.commit - self.assertEqual(commit.author.name, "Test User") # Author never modified for user commits - self.assertEqual(commit.committer.name, "Test User") # Explicit False prevents modification + self.assertEqual(commit.author.name, "Test User", msg="Author name should not be modified for user commits") + self.assertEqual(commit.committer.name, "Test User", msg="Committer name should not be modified when attribute_committer=False") + @unittest.skipIf(platform.system() == "Windows", "Git env var behavior differs on Windows") def test_commit_with_co_authored_by(self): - # Cleanup of the git temp dir explodes on windows - if platform.system() == "Windows": - return - with GitTemporaryDirectory(): # new repo raw_repo = git.Repo() @@ -274,14 +268,12 @@ class TestRepo(unittest.TestCase): self.assertIn("Co-authored-by: aider (gpt-test) ", commit.message) self.assertEqual(commit.message.splitlines()[0], "Aider edit") # With default (None), co-authored-by takes precedence - self.assertEqual(commit.author.name, "Test User") # Should NOT be modified - self.assertEqual(commit.committer.name, "Test User") # Should NOT be modified + self.assertEqual(commit.author.name, "Test User", msg="Author name should not be modified when co-authored-by takes precedence") + self.assertEqual(commit.committer.name, "Test User", msg="Committer name should not be modified when co-authored-by takes precedence") + @unittest.skipIf(platform.system() == "Windows", "Git env var behavior differs on Windows") def test_commit_co_authored_by_with_explicit_name_modification(self): # Test scenario where Co-authored-by is true AND author/committer modification are explicitly True - if platform.system() == "Windows": - return - with GitTemporaryDirectory(): # Setup repo... # new repo @@ -319,15 +311,13 @@ class TestRepo(unittest.TestCase): self.assertIn("Co-authored-by: aider (gpt-test-combo) ", commit.message) self.assertEqual(commit.message.splitlines()[0], "Aider combo edit") # When co-authored-by is true BUT author/committer are explicit True, modification SHOULD happen - self.assertEqual(commit.author.name, "Test User (aider)") # Should be modified - self.assertEqual(commit.committer.name, "Test User (aider)") # Should be modified + self.assertEqual(commit.author.name, "Test User (aider)", msg="Author name should be modified when explicitly True, even with co-author") + self.assertEqual(commit.committer.name, "Test User (aider)", msg="Committer name should be modified when explicitly True, even with co-author") + @unittest.skipIf(platform.system() == "Windows", "Git env var behavior differs on Windows") def test_commit_ai_edits_no_coauthor_explicit_false(self): # Test AI edits (aider_edits=True) when co-authored-by is False, # but author or committer attribution is explicitly disabled. - if platform.system() == "Windows": - return - with GitTemporaryDirectory(): # Setup repo raw_repo = git.Repo() @@ -375,8 +365,8 @@ class TestRepo(unittest.TestCase): self.assertIsNotNone(commit_result) commit = raw_repo.head.commit self.assertNotIn("Co-authored-by:", commit.message) - self.assertEqual(commit.author.name, "Test User (aider)") # Default True - self.assertEqual(commit.committer.name, "Test User") # Explicit False + self.assertEqual(commit.author.name, "Test User (aider)", msg="Author name should be modified (default True) when co-author=False") + self.assertEqual(commit.committer.name, "Test User", msg="Committer name should not be modified (explicit False) when co-author=False") def test_get_tracked_files(self): # Create a temporary directory @@ -574,12 +564,9 @@ class TestRepo(unittest.TestCase): commit_result = git_repo.commit(fnames=[str(fname)]) self.assertIsNone(commit_result) + @unittest.skipIf(platform.system() == "Windows", "Git hook execution differs on Windows") 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() From 38dfd6f4f96110d0e9bb5fcd9fcea044f744b3c5 Mon Sep 17 00:00:00 2001 From: Andrew Grigorev Date: Sat, 12 Apr 2025 20:07:33 +0300 Subject: [PATCH 58/85] docs: clarify --attribute-co-authored-by precedence --- aider/args.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/aider/args.py b/aider/args.py index 7aaf10f2a..dfa84b6c2 100644 --- a/aider/args.py +++ b/aider/args.py @@ -458,7 +458,11 @@ def get_parser(default_config_files, git_root): "--attribute-co-authored-by", action=argparse.BooleanOptionalAction, default=False, - help="Attribute aider edits using the Co-authored-by trailer in the commit message (default: False).", + help=( + "Attribute aider edits using the Co-authored-by trailer in the commit message" + " (default: False). If True, this takes precedence over default --attribute-author and" + " --attribute-committer behavior unless they are explicitly set to True." + ), ) group.add_argument( "--git-commit-verify", From 165e237be78c36437d1f2b5f0101546a1f4e2026 Mon Sep 17 00:00:00 2001 From: Andrew Grigorev Date: Sat, 12 Apr 2025 20:25:01 +0300 Subject: [PATCH 59/85] chore: remove unnecessary comment in repo.py Co-authored-by: aider (vertex_ai/gemini-2.5-pro-exp-03-25) --- aider/repo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aider/repo.py b/aider/repo.py index ad87a379a..85130e105 100644 --- a/aider/repo.py +++ b/aider/repo.py @@ -210,7 +210,7 @@ class GitRepo: attribute_committer = coder.args.attribute_committer attribute_commit_message_author = coder.args.attribute_commit_message_author attribute_commit_message_committer = coder.args.attribute_commit_message_committer - attribute_co_authored_by = coder.args.attribute_co_authored_by # <-- Restored + attribute_co_authored_by = coder.args.attribute_co_authored_by else: # Fallback to self attributes (initialized from config/defaults) attribute_author = self.attribute_author From 3f94fd5e4edd2205a24d5716c4dec3e9075f3b56 Mon Sep 17 00:00:00 2001 From: Andrew Grigorev Date: Sat, 12 Apr 2025 20:38:25 +0300 Subject: [PATCH 60/85] refactor: Simplify access to attribute_co_authored_by Co-authored-by: aider (vertex_ai/gemini-2.5-pro-exp-03-25) --- aider/repo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aider/repo.py b/aider/repo.py index 85130e105..0fa58ab7d 100644 --- a/aider/repo.py +++ b/aider/repo.py @@ -217,7 +217,7 @@ class GitRepo: attribute_committer = self.attribute_committer attribute_commit_message_author = self.attribute_commit_message_author attribute_commit_message_committer = self.attribute_commit_message_committer - attribute_co_authored_by = getattr(self, "attribute_co_authored_by", False) # Should be False if not set + attribute_co_authored_by = self.attribute_co_authored_by # Determine explicit settings (None means use default behavior) author_explicit = attribute_author is not None From 1d42690824f4208c612210b73b6d002830aa7882 Mon Sep 17 00:00:00 2001 From: Andrew Grigorev Date: Sat, 12 Apr 2025 20:50:29 +0300 Subject: [PATCH 61/85] fix: update co-authored-by domain to aider.chat Co-authored-by: aider (vertex_ai/gemini-2.5-pro-exp-03-25) --- aider/repo.py | 4 ++-- tests/basic/test_repo.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/aider/repo.py b/aider/repo.py index 0fa58ab7d..aa2d525f7 100644 --- a/aider/repo.py +++ b/aider/repo.py @@ -162,7 +162,7 @@ class GitRepo: Flags: - --attribute-author: Modify Author name to "User Name (aider)". - --attribute-committer: Modify Committer name to "User Name (aider)". - - --attribute-co-authored-by: Add "Co-authored-by: aider () " + - --attribute-co-authored-by: Add "Co-authored-by: aider () " trailer to the commit message. Behavior Summary: @@ -240,7 +240,7 @@ class GitRepo: if coder and hasattr(coder, "main_model") and coder.main_model.name: model_name = coder.main_model.name commit_message_trailer = ( - f"\n\nCo-authored-by: aider ({model_name}) " + f"\n\nCo-authored-by: aider ({model_name}) " ) # Determine if author/committer names should be modified diff --git a/tests/basic/test_repo.py b/tests/basic/test_repo.py index 4d5abac86..400c307a8 100644 --- a/tests/basic/test_repo.py +++ b/tests/basic/test_repo.py @@ -265,7 +265,7 @@ class TestRepo(unittest.TestCase): # check the commit message and author/committer commit = raw_repo.head.commit - self.assertIn("Co-authored-by: aider (gpt-test) ", commit.message) + self.assertIn("Co-authored-by: aider (gpt-test) ", commit.message) self.assertEqual(commit.message.splitlines()[0], "Aider edit") # With default (None), co-authored-by takes precedence self.assertEqual(commit.author.name, "Test User", msg="Author name should not be modified when co-authored-by takes precedence") @@ -308,7 +308,7 @@ class TestRepo(unittest.TestCase): # check the commit message and author/committer commit = raw_repo.head.commit - self.assertIn("Co-authored-by: aider (gpt-test-combo) ", commit.message) + self.assertIn("Co-authored-by: aider (gpt-test-combo) ", commit.message) self.assertEqual(commit.message.splitlines()[0], "Aider combo edit") # When co-authored-by is true BUT author/committer are explicit True, modification SHOULD happen self.assertEqual(commit.author.name, "Test User (aider)", msg="Author name should be modified when explicitly True, even with co-author") From f106993cd1704a20e102c3e987031b7becee0a56 Mon Sep 17 00:00:00 2001 From: Andrew Grigorev Date: Tue, 15 Apr 2025 01:35:00 +0300 Subject: [PATCH 62/85] fix: add --disable-playwright option to suppress Playwright prompts and usage Co-authored-by: aider (openai/gpt-4.1) --- aider/args.py | 6 ++ aider/commands.py | 14 ++- tests/scrape/test_playwright_disable.py | 120 ++++++++++++++++++++++++ 3 files changed, 136 insertions(+), 4 deletions(-) create mode 100644 tests/scrape/test_playwright_disable.py diff --git a/aider/args.py b/aider/args.py index 6df19778b..1bc1aaed2 100644 --- a/aider/args.py +++ b/aider/args.py @@ -670,6 +670,12 @@ def get_parser(default_config_files, git_root): ###### group = parser.add_argument_group("Other settings") + group.add_argument( + "--disable-playwright", + action="store_true", + help="Never prompt for or attempt to install Playwright for web scraping (default: False).", + default=False, + ) group.add_argument( "--file", action="append", diff --git a/aider/commands.py b/aider/commands.py index 81fc80093..29f20a976 100644 --- a/aider/commands.py +++ b/aider/commands.py @@ -220,12 +220,18 @@ class Commands: self.io.tool_output(f"Scraping {url}...") if not self.scraper: - res = install_playwright(self.io) - if not res: - self.io.tool_warning("Unable to initialize playwright.") + disable_playwright = getattr(self.args, "disable_playwright", False) + if disable_playwright: + res = False + else: + res = install_playwright(self.io) + if not res: + self.io.tool_warning("Unable to initialize playwright.") self.scraper = Scraper( - print_error=self.io.tool_error, playwright_available=res, verify_ssl=self.verify_ssl + print_error=self.io.tool_error, + playwright_available=res, + verify_ssl=self.verify_ssl, ) content = self.scraper.scrape(url) or "" diff --git a/tests/scrape/test_playwright_disable.py b/tests/scrape/test_playwright_disable.py new file mode 100644 index 000000000..df777752b --- /dev/null +++ b/tests/scrape/test_playwright_disable.py @@ -0,0 +1,120 @@ +import pytest +from unittest.mock import MagicMock + +from aider.scrape import install_playwright, Scraper + +class DummyIO: + def __init__(self): + self.outputs = [] + self.confirmed = False + + def tool_output(self, msg): + self.outputs.append(msg) + + def confirm_ask(self, msg, default="y"): + self.outputs.append(f"confirm: {msg}") + return self.confirmed + + def tool_error(self, msg): + self.outputs.append(f"error: {msg}") + + +def test_scraper_disable_playwright_flag(monkeypatch): + io = DummyIO() + # Simulate that playwright is not available (disable_playwright just means playwright_available=False) + scraper = Scraper(print_error=io.tool_error, playwright_available=False) + # Patch scrape_with_httpx to check it is called + called = {} + def fake_httpx(url): + called['called'] = True + return "plain text", "text/plain" + scraper.scrape_with_httpx = fake_httpx + content = scraper.scrape("http://example.com") + assert content == "plain text" + assert called['called'] + +def test_scraper_enable_playwright(monkeypatch): + io = DummyIO() + # Simulate that playwright is available and should be used + scraper = Scraper(print_error=io.tool_error, playwright_available=True) + # Patch scrape_with_playwright to check it is called + called = {} + def fake_playwright(url): + called['called'] = True + return "hi", "text/html" + scraper.scrape_with_playwright = fake_playwright + content = scraper.scrape("http://example.com") + assert content.startswith("hi") or "" in content + assert called['called'] + +def test_commands_web_disable_playwright(monkeypatch): + """ + Test that Commands.cmd_web does not emit a misleading warning when --disable-playwright is set. + """ + from aider.commands import Commands + + # Dummy IO to capture outputs and warnings + class DummyIO: + def __init__(self): + self.outputs = [] + self.warnings = [] + self.errors = [] + def tool_output(self, msg, *a, **k): + self.outputs.append(msg) + def tool_warning(self, msg, *a, **k): + self.warnings.append(msg) + def tool_error(self, msg, *a, **k): + self.errors.append(msg) + def read_text(self, filename, silent=False): + return "" + def confirm_ask(self, *a, **k): + return True + def print(self, *a, **k): + pass + + # Dummy coder to satisfy Commands + class DummyCoder: + def __init__(self): + self.cur_messages = [] + self.main_model = type("M", (), {"edit_format": "code", "name": "dummy", "info": {}}) + def get_rel_fname(self, fname): + return fname + def get_inchat_relative_files(self): + return [] + def abs_root_path(self, fname): + return fname + def get_all_abs_files(self): + return [] + def get_announcements(self): + return [] + def format_chat_chunks(self): + return type("Chunks", (), {"repo": [], "readonly_files": [], "chat_files": []})() + def event(self, *a, **k): + pass + + # Patch install_playwright to always return False (simulate not available) + monkeypatch.setattr("aider.scrape.install_playwright", lambda io: False) + + # Patch Scraper to always use scrape_with_httpx and never warn + class DummyScraper: + def __init__(self, **kwargs): + self.called = False + def scrape(self, url): + self.called = True + return "dummy content" + + monkeypatch.setattr("aider.commands.Scraper", DummyScraper) + + io = DummyIO() + coder = DummyCoder() + args = type("Args", (), {"disable_playwright": True})() + commands = Commands(io, coder, args=args) + + commands.cmd_web("http://example.com") + # Should not emit a warning about playwright + assert not io.warnings + # Should not contain message "For the best web scraping, install Playwright:" + assert all("install Playwright:" not in msg for msg in io.outputs) + # Should output scraping and added to chat + assert any("Scraping" in msg for msg in io.outputs) + assert any("added to chat" in msg for msg in io.outputs) From 6df2c1595fdbb02f0e99b27cdca07f42ff5f0345 Mon Sep 17 00:00:00 2001 From: Titusz Pan Date: Wed, 23 Apr 2025 11:20:08 +0200 Subject: [PATCH 63/85] fix: remove branch filter from Windows tests workflow --- .github/workflows/windows-tests.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/windows-tests.yml b/.github/workflows/windows-tests.yml index 21799563e..78fb1f3b7 100644 --- a/.github/workflows/windows-tests.yml +++ b/.github/workflows/windows-tests.yml @@ -8,8 +8,6 @@ on: - 'HISTORY.md' - '.github/workflows/*' - '!.github/workflows/windows-tests.yml' - branches: - - main pull_request: paths-ignore: - 'aider/website/**' From 5251a2452cf9c9c139774d50c6308cf78b8d4ba3 Mon Sep 17 00:00:00 2001 From: Titusz Pan Date: Wed, 23 Apr 2025 14:18:23 +0200 Subject: [PATCH 64/85] Add test to reproduce linting failure on windows --- tests/basic/test_linter.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/basic/test_linter.py b/tests/basic/test_linter.py index 9dce56355..ace4a9311 100644 --- a/tests/basic/test_linter.py +++ b/tests/basic/test_linter.py @@ -1,3 +1,4 @@ +import os import unittest from unittest.mock import MagicMock, patch @@ -36,6 +37,15 @@ class TestLinter(unittest.TestCase): result = self.linter.run_cmd("test_cmd", "test_file.py", "code") self.assertIsNone(result) + def test_run_cmd_win(self): + if os.name != "nt": + self.skipTest("This test only runs on Windows") + from pathlib import Path + root = Path(__file__).parent.parent.parent.absolute().as_posix() + linter = Linter(encoding="utf-8", root=root) + result = linter.run_cmd("dir", "tests/basic", "code") + self.assertIsNone(result) + @patch("subprocess.Popen") def test_run_cmd_with_errors(self, mock_popen): mock_process = MagicMock() From d9aa3cb2d43f38632dd85dd7311616b7e5c0fb02 Mon Sep 17 00:00:00 2001 From: Titusz Pan Date: Wed, 23 Apr 2025 14:33:01 +0200 Subject: [PATCH 65/85] Replace shlex with cross-platform oslex --- aider/linter.py | 4 ++-- aider/utils.py | 7 ++----- requirements.txt | 6 +++++- requirements/requirements.in | 1 + tests/basic/test_linter.py | 2 +- 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/aider/linter.py b/aider/linter.py index 920a8b7c6..51ed40b70 100644 --- a/aider/linter.py +++ b/aider/linter.py @@ -4,7 +4,7 @@ import subprocess import sys import traceback import warnings -import shlex +import oslex from dataclasses import dataclass from pathlib import Path @@ -45,7 +45,7 @@ class Linter: return fname def run_cmd(self, cmd, rel_fname, code): - cmd += " " + shlex.quote(rel_fname) + cmd += " " + oslex.quote(rel_fname) returncode = 0 stdout = "" diff --git a/aider/utils.py b/aider/utils.py index c6773f140..8ab8184a3 100644 --- a/aider/utils.py +++ b/aider/utils.py @@ -1,7 +1,7 @@ import itertools import os import platform -import shlex +import oslex import subprocess import sys import tempfile @@ -384,10 +384,7 @@ def printable_shell_command(cmd_list): Returns: str: Shell-escaped command string. """ - if platform.system() == "Windows": - return subprocess.list2cmdline(cmd_list) - else: - return shlex.join(cmd_list) + return oslex.join(cmd_list) def main(): diff --git a/requirements.txt b/requirements.txt index 44dbe2956..62832718b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -184,6 +184,8 @@ monotonic==1.6 # via # -c requirements/common-constraints.txt # posthog +mslex==1.3.0 + # via oslex multidict==6.4.3 # via # -c requirements/common-constraints.txt @@ -202,6 +204,8 @@ openai==1.73.0 # via # -c requirements/common-constraints.txt # litellm +oslex==0.1.3 + # via -r requirements/requirements.in packaging==24.2 # via # -c requirements/common-constraints.txt @@ -423,6 +427,6 @@ zipp==3.21.0 # via # -c requirements/common-constraints.txt # importlib-metadata - + tree-sitter==0.23.2; python_version < "3.10" tree-sitter==0.24.0; python_version >= "3.10" diff --git a/requirements/requirements.in b/requirements/requirements.in index 101f16988..5d75f3fa7 100644 --- a/requirements/requirements.in +++ b/requirements/requirements.in @@ -28,6 +28,7 @@ watchfiles socksio pip pillow +oslex # The proper dependency is networkx[default], but this brings # in matplotlib and a bunch of other deps diff --git a/tests/basic/test_linter.py b/tests/basic/test_linter.py index ace4a9311..60132b565 100644 --- a/tests/basic/test_linter.py +++ b/tests/basic/test_linter.py @@ -43,7 +43,7 @@ class TestLinter(unittest.TestCase): from pathlib import Path root = Path(__file__).parent.parent.parent.absolute().as_posix() linter = Linter(encoding="utf-8", root=root) - result = linter.run_cmd("dir", "tests/basic", "code") + result = linter.run_cmd("dir", "tests\\basic", "code") self.assertIsNone(result) @patch("subprocess.Popen") From 8ffe4662571ffdcebd3ac62cab1833e4a3cad888 Mon Sep 17 00:00:00 2001 From: Titusz Pan Date: Wed, 23 Apr 2025 14:40:43 +0200 Subject: [PATCH 66/85] Replace shlex with cross-platform oslex - fixes Aider-AI/aider#3746 --- .github/workflows/windows-tests.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/windows-tests.yml b/.github/workflows/windows-tests.yml index 78fb1f3b7..21799563e 100644 --- a/.github/workflows/windows-tests.yml +++ b/.github/workflows/windows-tests.yml @@ -8,6 +8,8 @@ on: - 'HISTORY.md' - '.github/workflows/*' - '!.github/workflows/windows-tests.yml' + branches: + - main pull_request: paths-ignore: - 'aider/website/**' From eabc98b64ad10fea3df08a4cf22b3436876c0420 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Wed, 7 May 2025 13:57:24 -0700 Subject: [PATCH 67/85] copy --- aider/website/_posts/2025-05-07-gemini-cost.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/aider/website/_posts/2025-05-07-gemini-cost.md b/aider/website/_posts/2025-05-07-gemini-cost.md index ca3fd877e..c54c18e05 100644 --- a/aider/website/_posts/2025-05-07-gemini-cost.md +++ b/aider/website/_posts/2025-05-07-gemini-cost.md @@ -63,9 +63,9 @@ commit [0282574](https://github.com/Aider-AI/aider/commit/0282574). Additional runs of the benchmark from that build verified that the error in litellm's model cost database appears not to have been a factor: -- Aider's local model database correctly overrides the litellm database, which contained an incorrect token cost at the time. -- The correct pricing is loaded from aider's local model database and produces similar (incorrect) costs as the original run. -- Updating aider's local model database with an absurdly high token cost resulted in an appropriately high benchmark cost report, demonstrating that the local database costs were in effect. +- Aider's internal model database correctly overrides the litellm database, which contained an incorrect token cost at the time. +- The correct pricing is loaded from aider's internal model database and produces similar (incorrect) costs as the original run. +- Updating aider's internal model database with an absurdly high token cost resulted in an appropriately high benchmark cost report, demonstrating that the internal database costs were in effect. This specific build of aider was then updated with various versions of litellm using `git biset` to identify the first litellm commit where reasoning tokens counts were correctly reported. From 9660d95ceb04be4611ed1cdb0415c3a36a755b6c Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Wed, 7 May 2025 16:04:57 -0700 Subject: [PATCH 68/85] feat: Support thinking_tokens and reasoning_effort for OpenRouter models --- aider/models.py | 41 ++++++++++++++++++++++++++++++----------- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/aider/models.py b/aider/models.py index dd0abd452..3c790c644 100644 --- a/aider/models.py +++ b/aider/models.py @@ -332,6 +332,15 @@ class Model(ModelSettings): # For non-dict values, simply update self.extra_params[key] = value + # Ensure OpenRouter models accept thinking_tokens and reasoning_effort + if self.name.startswith("openrouter/"): + if self.accepts_settings is None: + self.accepts_settings = [] + if "thinking_tokens" not in self.accepts_settings: + self.accepts_settings.append("thinking_tokens") + if "reasoning_effort" not in self.accepts_settings: + self.accepts_settings.append("reasoning_effort") + def apply_generic_model_settings(self, model): if "/o3-mini" in model: self.edit_format = "diff" @@ -659,11 +668,16 @@ class Model(ModelSettings): 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 + if self.name.startswith("openrouter/"): + if not self.extra_params: + self.extra_params = {} + self.extra_params["reasoning"] = {"effort": effort} + else: + 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): """ @@ -750,12 +764,17 @@ class Model(ModelSettings): def get_reasoning_effort(self): """Get reasoning effort value if available""" - if ( - self.extra_params - and "extra_body" in self.extra_params - and "reasoning_effort" in self.extra_params["extra_body"] - ): - return self.extra_params["extra_body"]["reasoning_effort"] + if self.extra_params: + # Check for OpenRouter reasoning format + if self.name.startswith("openrouter/"): + if "reasoning" in self.extra_params and "effort" in self.extra_params["reasoning"]: + return self.extra_params["reasoning"]["effort"] + # Check for standard reasoning_effort format (e.g. in extra_body) + elif ( + "extra_body" in self.extra_params + and "reasoning_effort" in self.extra_params["extra_body"] + ): + return self.extra_params["extra_body"]["reasoning_effort"] return None def is_deepseek_r1(self): From a61fb1e23bcc14c143c6545199ebf6559e784ce8 Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Wed, 7 May 2025 16:07:19 -0700 Subject: [PATCH 69/85] refactor: Move OpenRouter reasoning params to extra_body --- aider/models.py | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/aider/models.py b/aider/models.py index 3c790c644..62e807e8b 100644 --- a/aider/models.py +++ b/aider/models.py @@ -671,14 +671,15 @@ class Model(ModelSettings): if self.name.startswith("openrouter/"): if not self.extra_params: self.extra_params = {} - self.extra_params["reasoning"] = {"effort": effort} + if "extra_body" not in self.extra_params: + self.extra_params["extra_body"] = {} + self.extra_params["extra_body"]["reasoning"] = {"effort": effort} else: 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. @@ -723,7 +724,9 @@ class Model(ModelSettings): # OpenRouter models use 'reasoning' instead of 'thinking' if self.name.startswith("openrouter/"): - self.extra_params["reasoning"] = {"max_tokens": num_tokens} + if "extra_body" not in self.extra_params: + self.extra_params["extra_body"] = {} + self.extra_params["extra_body"]["reasoning"] = {"max_tokens": num_tokens} else: self.extra_params["thinking"] = {"type": "enabled", "budget_tokens": num_tokens} @@ -733,8 +736,13 @@ class Model(ModelSettings): if self.extra_params: # Check for OpenRouter reasoning format - if "reasoning" in self.extra_params and "max_tokens" in self.extra_params["reasoning"]: - budget = self.extra_params["reasoning"]["max_tokens"] + if self.name.startswith("openrouter/"): + if ( + "extra_body" in self.extra_params + and "reasoning" in self.extra_params["extra_body"] + and "max_tokens" in self.extra_params["extra_body"]["reasoning"] + ): + budget = self.extra_params["extra_body"]["reasoning"]["max_tokens"] # Check for standard thinking format elif ( "thinking" in self.extra_params and "budget_tokens" in self.extra_params["thinking"] @@ -767,8 +775,12 @@ class Model(ModelSettings): if self.extra_params: # Check for OpenRouter reasoning format if self.name.startswith("openrouter/"): - if "reasoning" in self.extra_params and "effort" in self.extra_params["reasoning"]: - return self.extra_params["reasoning"]["effort"] + if ( + "extra_body" in self.extra_params + and "reasoning" in self.extra_params["extra_body"] + and "effort" in self.extra_params["extra_body"]["reasoning"] + ): + return self.extra_params["extra_body"]["reasoning"]["effort"] # Check for standard reasoning_effort format (e.g. in extra_body) elif ( "extra_body" in self.extra_params From c756b080e851fbdd1f4483a6f50c24c8a06911e3 Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Wed, 7 May 2025 16:07:23 -0700 Subject: [PATCH 70/85] style: Run linter on aider/models.py --- aider/models.py | 1 + 1 file changed, 1 insertion(+) diff --git a/aider/models.py b/aider/models.py index 62e807e8b..6c5562cd9 100644 --- a/aider/models.py +++ b/aider/models.py @@ -680,6 +680,7 @@ class Model(ModelSettings): 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. From 96899a140bb60b30dd6e030f670bd470c3e18abb Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Wed, 7 May 2025 16:19:19 -0700 Subject: [PATCH 71/85] bump deps --- requirements.txt | 12 ++++++++---- requirements/common-constraints.txt | 14 ++++++++------ requirements/requirements-dev.txt | 6 +++--- requirements/requirements-help.txt | 8 ++++++-- 4 files changed, 25 insertions(+), 15 deletions(-) diff --git a/requirements.txt b/requirements.txt index 8fdd901f4..31a3c058f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -116,7 +116,7 @@ google-api-python-client==2.169.0 # via # -c requirements/common-constraints.txt # google-generativeai -google-auth==2.40.0 +google-auth==2.40.1 # via # -c requirements/common-constraints.txt # google-ai-generativelanguage @@ -154,6 +154,10 @@ h11==0.16.0 # via # -c requirements/common-constraints.txt # httpcore +hf-xet==1.1.0 + # via + # -c requirements/common-constraints.txt + # huggingface-hub httpcore==1.0.9 # via # -c requirements/common-constraints.txt @@ -168,7 +172,7 @@ httpx==0.28.1 # -c requirements/common-constraints.txt # litellm # openai -huggingface-hub==0.30.2 +huggingface-hub==0.31.1 # via # -c requirements/common-constraints.txt # tokenizers @@ -209,7 +213,7 @@ jsonschema-specifications==2025.4.1 # via # -c requirements/common-constraints.txt # jsonschema -litellm==1.68.0 +litellm==1.68.1 # via # -c requirements/common-constraints.txt # -r requirements/requirements.in @@ -462,7 +466,7 @@ tree-sitter-embedded-template==0.23.2 # via # -c requirements/common-constraints.txt # tree-sitter-language-pack -tree-sitter-language-pack==0.7.2 +tree-sitter-language-pack==0.7.3 # via # -c requirements/common-constraints.txt # grep-ast diff --git a/requirements/common-constraints.txt b/requirements/common-constraints.txt index 0f0d09910..dff981b3e 100644 --- a/requirements/common-constraints.txt +++ b/requirements/common-constraints.txt @@ -131,7 +131,7 @@ google-api-core[grpc]==2.24.2 # google-generativeai google-api-python-client==2.169.0 # via google-generativeai -google-auth==2.40.0 +google-auth==2.40.1 # via # google-ai-generativelanguage # google-api-core @@ -172,6 +172,8 @@ grpcio-status==1.71.0 # via google-api-core h11==0.16.0 # via httpcore +hf-xet==1.1.0 + # via huggingface-hub httpcore==1.0.9 # via httpx httplib2==0.22.0 @@ -183,7 +185,7 @@ httpx==0.28.1 # litellm # llama-index-core # openai -huggingface-hub[inference]==0.30.2 +huggingface-hub[inference]==0.31.1 # via # llama-index-embeddings-huggingface # sentence-transformers @@ -231,7 +233,7 @@ jsonschema-specifications==2025.4.1 # via jsonschema kiwisolver==1.4.8 # via matplotlib -litellm==1.68.0 +litellm==1.68.1 # via -r requirements/requirements.in llama-index-core==0.12.26 # via @@ -330,7 +332,7 @@ pip==25.1.1 # pip-tools pip-tools==7.4.1 # via -r requirements/requirements-dev.in -platformdirs==4.3.7 +platformdirs==4.3.8 # via # banks # virtualenv @@ -546,7 +548,7 @@ 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.7.2 +tree-sitter-language-pack==0.7.3 # via grep-ast tree-sitter-yaml==0.7.0 # via tree-sitter-language-pack @@ -586,7 +588,7 @@ urllib3==2.4.0 # via # mixpanel # requests -uv==0.7.2 +uv==0.7.3 # via -r requirements/requirements-dev.in virtualenv==20.31.1 # via pre-commit diff --git a/requirements/requirements-dev.txt b/requirements/requirements-dev.txt index b0cf358d1..fc05acc51 100644 --- a/requirements/requirements-dev.txt +++ b/requirements/requirements-dev.txt @@ -63,7 +63,7 @@ google-api-core[grpc]==2.24.2 # -c requirements/common-constraints.txt # google-cloud-bigquery # google-cloud-core -google-auth==2.40.0 +google-auth==2.40.1 # via # -c requirements/common-constraints.txt # google-api-core @@ -176,7 +176,7 @@ pip-tools==7.4.1 # via # -c requirements/common-constraints.txt # -r requirements/requirements-dev.in -platformdirs==4.3.7 +platformdirs==4.3.8 # via # -c requirements/common-constraints.txt # virtualenv @@ -297,7 +297,7 @@ urllib3==2.4.0 # via # -c requirements/common-constraints.txt # requests -uv==0.7.2 +uv==0.7.3 # via # -c requirements/common-constraints.txt # -r requirements/requirements-dev.in diff --git a/requirements/requirements-help.txt b/requirements/requirements-help.txt index 8305671fb..b930a01ff 100644 --- a/requirements/requirements-help.txt +++ b/requirements/requirements-help.txt @@ -93,6 +93,10 @@ h11==0.16.0 # via # -c requirements/common-constraints.txt # httpcore +hf-xet==1.1.0 + # via + # -c requirements/common-constraints.txt + # huggingface-hub httpcore==1.0.9 # via # -c requirements/common-constraints.txt @@ -101,7 +105,7 @@ httpx==0.28.1 # via # -c requirements/common-constraints.txt # llama-index-core -huggingface-hub[inference]==0.30.2 +huggingface-hub[inference]==0.31.1 # via # -c requirements/common-constraints.txt # llama-index-embeddings-huggingface @@ -187,7 +191,7 @@ pillow==11.2.1 # -c requirements/common-constraints.txt # llama-index-core # sentence-transformers -platformdirs==4.3.7 +platformdirs==4.3.8 # via # -c requirements/common-constraints.txt # banks From 94197cb25d24cdbe59a43935addbb1db4148eb94 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Wed, 7 May 2025 16:32:57 -0700 Subject: [PATCH 72/85] feat: Add model settings for openrouter/google/gemini-2.5-pro-preview-03-25 --- aider/resources/model-settings.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/aider/resources/model-settings.yml b/aider/resources/model-settings.yml index 273e77621..8a7567d49 100644 --- a/aider/resources/model-settings.yml +++ b/aider/resources/model-settings.yml @@ -1386,3 +1386,9 @@ edit_format: diff use_repo_map: true accepts_settings: ["thinking_tokens"] + +- name: openrouter/google/gemini-2.5-pro-preview-03-25 + edit_format: diff-fenced + use_repo_map: true + weak_model_name: openrouter/google/gemini-2.0-flash-001 + \ No newline at end of file From 60a1a3a8c80fc39cde1a0890fb6f0b82ac1bdf10 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Wed, 7 May 2025 16:44:15 -0700 Subject: [PATCH 73/85] drop pip, bump deps --- requirements.txt | 16 ++++++---------- requirements/common-constraints.txt | 8 +++++--- requirements/requirements.in | 1 - 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/requirements.txt b/requirements.txt index 6aebb7322..52137b7e8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -237,12 +237,10 @@ mixpanel==4.10.1 # via # -c requirements/common-constraints.txt # -r requirements/requirements.in -monotonic==1.6 +mslex==1.3.0 # via # -c requirements/common-constraints.txt - # posthog -mslex==1.3.0 - # via oslex + # oslex multidict==6.4.3 # via # -c requirements/common-constraints.txt @@ -262,7 +260,9 @@ openai==1.75.0 # -c requirements/common-constraints.txt # litellm oslex==0.1.3 - # via -r requirements/requirements.in + # via + # -c requirements/common-constraints.txt + # -r requirements/requirements.in packaging==24.2 # via # -c requirements/common-constraints.txt @@ -281,10 +281,6 @@ pillow==11.2.1 # via # -c requirements/common-constraints.txt # -r requirements/requirements.in -pip==25.1.1 - # via - # -c requirements/common-constraints.txt - # -r requirements/requirements.in posthog==4.0.1 # via # -c requirements/common-constraints.txt @@ -523,6 +519,6 @@ zipp==3.21.0 # via # -c requirements/common-constraints.txt # importlib-metadata - + tree-sitter==0.23.2; python_version < "3.10" tree-sitter==0.24.0; python_version >= "3.10" diff --git a/requirements/common-constraints.txt b/requirements/common-constraints.txt index dff981b3e..aaf158695 100644 --- a/requirements/common-constraints.txt +++ b/requirements/common-constraints.txt @@ -259,6 +259,8 @@ mixpanel==4.10.1 # via -r requirements/requirements.in mpmath==1.3.0 # via sympy +mslex==1.3.0 + # via oslex multidict==6.4.3 # via # aiohttp @@ -295,6 +297,8 @@ numpy==1.26.4 # transformers openai==1.75.0 # via litellm +oslex==0.1.3 + # via -r requirements/requirements.in packaging==24.2 # via # -r requirements/requirements.in @@ -327,9 +331,7 @@ pillow==11.2.1 # sentence-transformers # streamlit pip==25.1.1 - # via - # -r requirements/requirements.in - # pip-tools + # via pip-tools pip-tools==7.4.1 # via -r requirements/requirements-dev.in platformdirs==4.3.8 diff --git a/requirements/requirements.in b/requirements/requirements.in index 1d3e7d895..6ddde184b 100644 --- a/requirements/requirements.in +++ b/requirements/requirements.in @@ -26,7 +26,6 @@ json5 psutil watchfiles socksio -pip pillow oslex google-generativeai From 4ec075d29082d5b8f9084f786f596de119b67cc5 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Wed, 7 May 2025 16:44:40 -0700 Subject: [PATCH 74/85] copy --- aider/website/assets/sample-analytics.jsonl | 224 +++++++++--------- .../website/docs/config/adv-model-settings.md | 5 + aider/website/docs/faq.md | 13 +- 3 files changed, 123 insertions(+), 119 deletions(-) diff --git a/aider/website/assets/sample-analytics.jsonl b/aider/website/assets/sample-analytics.jsonl index 6be794fac..5127072c9 100644 --- a/aider/website/assets/sample-analytics.jsonl +++ b/aider/website/assets/sample-analytics.jsonl @@ -1,115 +1,3 @@ -{"event": "cli session", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745163405} -{"event": "exit", "properties": {"reason": "Control-C"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745163407} -{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff", "prompt_tokens": 5399, "completion_tokens": 256, "total_tokens": 5655, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745163408} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745163408} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745163508} -{"event": "repo", "properties": {"num_files": 611}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745163513} -{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745163513} -{"event": "cli session", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745163513} -{"event": "exit", "properties": {"reason": "Completed main CLI coder.run"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745163518} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745169424} -{"event": "repo", "properties": {"num_files": 611}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745169425} -{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745169425} -{"event": "cli session", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745169425} -{"event": "exit", "properties": {"reason": "Completed main CLI coder.run"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745169504} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745169513} -{"event": "repo", "properties": {"num_files": 611}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745169513} -{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745169513} -{"event": "cli session", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745169515} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745169818} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745169922} -{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff", "prompt_tokens": 12540, "completion_tokens": 4598, "total_tokens": 17138, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745169961} -{"event": "command_undo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745169983} -{"event": "command_clear", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745169986} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745169991} -{"event": "command_drop", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745170026} -{"event": "command_clear", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745170032} -{"event": "command_drop", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745170033} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745170035} -{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff", "prompt_tokens": 11415, "completion_tokens": 3674, "total_tokens": 15089, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745170079} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745170445} -{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff", "prompt_tokens": 15533, "completion_tokens": 259, "total_tokens": 15792, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745170451} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745171263} -{"event": "repo", "properties": {"num_files": 612}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745171263} -{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745171263} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745171264} -{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff", "prompt_tokens": 8867, "completion_tokens": 17, "total_tokens": 8884, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745171269} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745171269} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745171274} -{"event": "model warning", "properties": {"main_model": "None", "weak_model": "None", "editor_model": "None"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745171276} -{"event": "exit", "properties": {"reason": "Keyboard interrupt during model warnings"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745171302} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745171306} -{"event": "repo", "properties": {"num_files": 612}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745171307} -{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745171307} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745171307} -{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff", "prompt_tokens": 9113, "completion_tokens": 17, "total_tokens": 9130, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745171312} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745171312} -{"event": "exit", "properties": {"reason": "Control-C"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745171723} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745171757} -{"event": "repo", "properties": {"num_files": 612}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745171758} -{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745171758} -{"event": "cli session", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745171758} -{"event": "exit", "properties": {"reason": "Completed main CLI coder.run"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745171761} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745171764} -{"event": "repo", "properties": {"num_files": 612}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745171765} -{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745171765} -{"event": "cli session", "properties": {"main_model": "gemini/gemini-2.5-pro-preview-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-preview-03-25", "edit_format": "diff-fenced"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745171765} -{"event": "exit", "properties": {"reason": "Completed main CLI coder.run"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745171829} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745171854} -{"event": "repo", "properties": {"num_files": 612}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745171854} -{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745171854} -{"event": "cli session", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745171854} -{"event": "command_read-only", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745171874} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745171909} -{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff", "prompt_tokens": 12362, "completion_tokens": 445, "total_tokens": 12807, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745171917} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745171960} -{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff", "prompt_tokens": 13269, "completion_tokens": 262, "total_tokens": 13531, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745171970} -{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745171985} -{"event": "command_read-only", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745171988} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745171994} -{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff", "prompt_tokens": 20636, "completion_tokens": 177, "total_tokens": 20813, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745171998} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745172037} -{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff", "prompt_tokens": 20894, "completion_tokens": 496, "total_tokens": 21390, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745172048} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745172095} -{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff", "prompt_tokens": 21739, "completion_tokens": 251, "total_tokens": 21990, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745172099} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745172115} -{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff", "prompt_tokens": 22364, "completion_tokens": 155, "total_tokens": 22519, "cost": 0.0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745172119} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745172137} -{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff", "prompt_tokens": 22589, "completion_tokens": 696, "total_tokens": 23285, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745172157} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745172200} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745172211} -{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff", "prompt_tokens": 23740, "completion_tokens": 695, "total_tokens": 24435, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745172220} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745172282} -{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff", "prompt_tokens": 24460, "completion_tokens": 1797, "total_tokens": 26257, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745172335} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745172348} -{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff", "prompt_tokens": 27939, "completion_tokens": 314, "total_tokens": 28253, "cost": 0.0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745172356} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745172356} -{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff", "prompt_tokens": 28199, "completion_tokens": 1732, "total_tokens": 29931, "cost": 0.0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745172379} -{"event": "command_clear", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745172493} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745172522} -{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff", "prompt_tokens": 19352, "completion_tokens": 467, "total_tokens": 19819, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745172532} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745172581} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745172586} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745172594} -{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff", "prompt_tokens": 20067, "completion_tokens": 327, "total_tokens": 20394, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745172610} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745172650} -{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff", "prompt_tokens": 22284, "completion_tokens": 426, "total_tokens": 22710, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745172657} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745172722} -{"event": "repo", "properties": {"num_files": 613}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745172724} -{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745172724} -{"event": "cli session", "properties": {"main_model": "xai/grok-3-fast-beta", "weak_model": "xai/grok-3-fast-beta", "editor_model": "xai/grok-3-fast-beta", "edit_format": "diff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745172724} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745172725} -{"event": "message_send", "properties": {"main_model": "xai/grok-3-fast-beta", "weak_model": "xai/grok-3-fast-beta", "editor_model": "xai/grok-3-fast-beta", "edit_format": "diff", "prompt_tokens": 10210, "completion_tokens": 78, "total_tokens": 10288, "cost": 0.053000000000000005, "total_cost": 0.053000000000000005}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745172729} -{"event": "command_exit", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745172730} -{"event": "exit", "properties": {"reason": "/exit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745172730} -{"event": "exit", "properties": {"reason": "Control-C"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745172883} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173009} -{"event": "repo", "properties": {"num_files": 613}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173009} -{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173009} -{"event": "cli session", "properties": {"main_model": "gemini/gemini-2.5-flash-preview-04-17", "weak_model": "gemini/gemini-2.5-flash-preview-04-17", "editor_model": "gemini/gemini-2.5-flash-preview-04-17", "edit_format": "whole"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173009} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173017} -{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-flash-preview-04-17", "weak_model": "gemini/gemini-2.5-flash-preview-04-17", "editor_model": "gemini/gemini-2.5-flash-preview-04-17", "edit_format": "whole", "prompt_tokens": 8315, "completion_tokens": 25, "total_tokens": 8340, "cost": 0.00126225, "total_cost": 0.00126225}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173024} -{"event": "exit", "properties": {"reason": "Control-C"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173227} {"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173231} {"event": "model warning", "properties": {"main_model": "gemini/REDACTED", "weak_model": "gemini/REDACTED", "editor_model": "gemini/REDACTED"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173234} {"event": "exit", "properties": {"reason": "Keyboard interrupt during model warnings"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173235} @@ -998,3 +886,115 @@ {"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746645861} {"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff-simple", "prompt_tokens": 6524, "completion_tokens": 387, "total_tokens": 6911, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746645888} {"event": "exit", "properties": {"reason": "Completed main CLI coder.run"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746646177} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746648919} +{"event": "repo", "properties": {"num_files": 617}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746648919} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746648919} +{"event": "cli session", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff-simple"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746648919} +{"event": "command_ask", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746648920} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746648930} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "ask", "prompt_tokens": 6568, "completion_tokens": 1043, "total_tokens": 7611, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746648961} +{"event": "command_clear", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746649323} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746649324} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "ask", "prompt_tokens": 6657, "completion_tokens": 916, "total_tokens": 7573, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746649392} +{"event": "exit", "properties": {"reason": "Completed main CLI coder.run"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746649626} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746649652} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746649652} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746649652} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746649652} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-preview-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-preview-03-25", "edit_format": "ask", "prompt_tokens": 8704, "completion_tokens": 336, "total_tokens": 9040, "cost": 0.014240000000000001, "total_cost": 0.014240000000000001}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746649669} +{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746649669} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746650326} +{"event": "repo", "properties": {"num_files": 617}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746650327} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746650327} +{"event": "exit", "properties": {"reason": "Completed lint/test/commit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746650330} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746650397} +{"event": "model warning", "properties": {"main_model": "gemini/REDACTED", "weak_model": "gemini/REDACTED", "editor_model": "gemini/REDACTED"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746650399} +{"event": "repo", "properties": {"num_files": 617}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746650401} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746650401} +{"event": "cli session", "properties": {"main_model": "gemini/REDACTED", "weak_model": "gemini/REDACTED", "editor_model": "gemini/REDACTED", "edit_format": "whole"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746650401} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746650403} +{"event": "exit", "properties": {"reason": "Completed main CLI coder.run"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746650416} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746650421} +{"event": "repo", "properties": {"num_files": 617}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746650422} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746650422} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746650422} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff-simple", "prompt_tokens": 8240, "completion_tokens": 10, "total_tokens": 8250, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746650427} +{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746650427} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746650437} +{"event": "repo", "properties": {"num_files": 617}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746650437} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746650437} +{"event": "exit", "properties": {"reason": "Completed lint/test/commit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746650440} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657288} +{"event": "model warning", "properties": {"main_model": "openrouter/REDACTED", "weak_model": "openrouter/REDACTED", "editor_model": "openrouter/REDACTED"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657291} +{"event": "exit", "properties": {"reason": "Keyboard interrupt during model warnings"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657297} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657300} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657302} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657302} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657302} +{"event": "message_send", "properties": {"main_model": "openrouter/REDACTED", "weak_model": "openrouter/REDACTED", "editor_model": "openrouter/REDACTED", "edit_format": "whole", "prompt_tokens": 605, "completion_tokens": 362, "total_tokens": 967, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657321} +{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657321} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657326} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657328} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657328} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657328} +{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657334} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657340} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657342} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657342} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657342} +{"event": "message_send", "properties": {"main_model": "openrouter/REDACTED", "weak_model": "openrouter/REDACTED", "editor_model": "openrouter/REDACTED", "edit_format": "whole", "prompt_tokens": 605, "completion_tokens": 300, "total_tokens": 905, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657355} +{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657355} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657389} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657391} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657391} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657391} +{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657397} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657459} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657462} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657462} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657462} +{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657473} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657474} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657476} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657476} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657476} +{"event": "message_send", "properties": {"main_model": "openrouter/REDACTED", "weak_model": "openrouter/REDACTED", "editor_model": "openrouter/REDACTED", "edit_format": "whole", "prompt_tokens": 605, "completion_tokens": 40, "total_tokens": 645, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657481} +{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657481} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657535} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657537} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657537} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657537} +{"event": "message_send", "properties": {"main_model": "openrouter/REDACTED", "weak_model": "openrouter/REDACTED", "editor_model": "openrouter/REDACTED", "edit_format": "whole", "prompt_tokens": 605, "completion_tokens": 214, "total_tokens": 819, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657541} +{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746657541} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746658868} +{"event": "repo", "properties": {"num_files": 617}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746658868} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746658868} +{"event": "cli session", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff-simple"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746658868} +{"event": "command_edit", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746658873} +{"event": "command_ask", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746658947} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746658947} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746659079} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff-simple", "prompt_tokens": 40797, "completion_tokens": 630, "total_tokens": 41427, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746659096} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746659220} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff-simple", "prompt_tokens": 41689, "completion_tokens": 808, "total_tokens": 42497, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746659238} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746659274} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746659277} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746659277} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746659277} +{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746659279} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746659294} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746659296} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746659296} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746659296} +{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746659297} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746659303} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746659305} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746659305} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746659305} +{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746659310} +{"event": "command_exit", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746659316} +{"event": "exit", "properties": {"reason": "/exit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746659316} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746660773} +{"event": "repo", "properties": {"num_files": 617}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746660774} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746660774} +{"event": "exit", "properties": {"reason": "Completed lint/test/commit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746660777} diff --git a/aider/website/docs/config/adv-model-settings.md b/aider/website/docs/config/adv-model-settings.md index 65c48c993..b1a683b61 100644 --- a/aider/website/docs/config/adv-model-settings.md +++ b/aider/website/docs/config/adv-model-settings.md @@ -1222,6 +1222,11 @@ cog.out("```\n") use_repo_map: true overeager: true +- name: openrouter/google/gemini-2.5-pro-preview-03-25 + edit_format: diff-fenced + weak_model_name: openrouter/google/gemini-2.0-flash-001 + use_repo_map: true + - name: openrouter/google/gemma-3-27b-it use_system_prompt: false diff --git a/aider/website/docs/faq.md b/aider/website/docs/faq.md index 88da6a54f..856713cb0 100644 --- a/aider/website/docs/faq.md +++ b/aider/website/docs/faq.md @@ -264,14 +264,13 @@ tr:hover { background-color: #f5f5f5; } - - - - - - + + + + + - +
Model NameTotal TokensPercent
gemini/gemini-2.5-pro-exp-03-251,588,02870.8%
gemini/gemini-2.5-pro-preview-03-25432,97919.3%
o3138,8426.2%
openrouter/anthropic/claude-3.7-sonnet41,0171.8%
gemini/gemini-2.5-flash-preview-04-1718,6450.8%
xai/grok-3-fast-beta10,2880.5%
gemini/gemini-2.5-pro-exp-03-251,315,56467.0%
gemini/gemini-2.5-pro-preview-03-25442,01922.5%
o3138,8427.1%
openrouter/anthropic/claude-3.7-sonnet41,0172.1%
gemini/gemini-2.5-flash-preview-04-1710,3050.5%
gemini/gemini-2.5-pro-preview-05-068,5760.4%
openrouter/REDACTED2,2010.1%
openrouter/REDACTED5,5370.3%
gemini/REDACTED1,9890.1%
From c72e5fcc5e16f8755e4214c46e1751a4df52dea8 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Wed, 7 May 2025 16:53:18 -0700 Subject: [PATCH 75/85] feat: Improve history, faq, and linter tests for Windows and special chars --- HISTORY.md | 10 ++++++++++ aider/website/HISTORY.md | 10 ++++++++++ aider/website/assets/sample-analytics.jsonl | 12 +++++------ aider/website/docs/faq.md | 6 +++--- tests/basic/test_linter.py | 22 +++++++++++++++++++++ 5 files changed, 51 insertions(+), 9 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 92530ea68..d04306507 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -13,6 +13,16 @@ - Add common file types (`.svg`, `.pdf`) to the default list of ignored files for AI comment scanning (`--watch`). - Skip scanning files larger than 1MB for AI comments (`--watch`). - Aider wrote 67% of the code in this release. +### main branch + +- Set development version to 0.82.4.dev. +- Improved cost calculation using `litellm.completion_cost` where available. +- Fixed linter command execution on Windows by adopting `oslex` for argument quoting, by Titusz Pan. +- Enabled support for `thinking_tokens` and `reasoning_effort` parameters for OpenRouter models. +- Added support for `gemini-2.5-pro-preview-05-06` models. +- Added model settings for `openrouter/google/gemini-2.5-pro-preview-03-25`. +- Aider wrote 67% of the code in this release. + ### Aider v0.82.2 diff --git a/aider/website/HISTORY.md b/aider/website/HISTORY.md index 82a2527a1..cc39db23b 100644 --- a/aider/website/HISTORY.md +++ b/aider/website/HISTORY.md @@ -37,6 +37,16 @@ cog.out(text) - Add common file types (`.svg`, `.pdf`) to the default list of ignored files for AI comment scanning (`--watch`). - Skip scanning files larger than 1MB for AI comments (`--watch`). - Aider wrote 67% of the code in this release. +### main branch + +- Set development version to 0.82.4.dev. +- Improved cost calculation using `litellm.completion_cost` where available. +- Fixed linter command execution on Windows by adopting `oslex` for argument quoting, by Titusz Pan. +- Enabled support for `thinking_tokens` and `reasoning_effort` parameters for OpenRouter models. +- Added support for `gemini-2.5-pro-preview-05-06` models. +- Added model settings for `openrouter/google/gemini-2.5-pro-preview-03-25`. +- Aider wrote 67% of the code in this release. + ### Aider v0.82.2 diff --git a/aider/website/assets/sample-analytics.jsonl b/aider/website/assets/sample-analytics.jsonl index 5127072c9..c90524869 100644 --- a/aider/website/assets/sample-analytics.jsonl +++ b/aider/website/assets/sample-analytics.jsonl @@ -1,9 +1,3 @@ -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173231} -{"event": "model warning", "properties": {"main_model": "gemini/REDACTED", "weak_model": "gemini/REDACTED", "editor_model": "gemini/REDACTED"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173234} -{"event": "exit", "properties": {"reason": "Keyboard interrupt during model warnings"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173235} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173477} -{"event": "repo", "properties": {"num_files": 613}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173478} -{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173478} {"event": "cli session", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173478} {"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173651} {"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff", "prompt_tokens": 13344, "completion_tokens": 1294, "total_tokens": 14638, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173666} @@ -998,3 +992,9 @@ {"event": "repo", "properties": {"num_files": 617}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746660774} {"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746660774} {"event": "exit", "properties": {"reason": "Completed lint/test/commit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746660777} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746661684} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746661684} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746661684} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746661684} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff-simple", "prompt_tokens": 6018, "completion_tokens": 231, "total_tokens": 6249, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746661749} +{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746661749} diff --git a/aider/website/docs/faq.md b/aider/website/docs/faq.md index 856713cb0..871a030b0 100644 --- a/aider/website/docs/faq.md +++ b/aider/website/docs/faq.md @@ -264,9 +264,9 @@ tr:hover { background-color: #f5f5f5; } - - - + + + diff --git a/tests/basic/test_linter.py b/tests/basic/test_linter.py index 60132b565..46b02a367 100644 --- a/tests/basic/test_linter.py +++ b/tests/basic/test_linter.py @@ -41,6 +41,7 @@ class TestLinter(unittest.TestCase): if os.name != "nt": self.skipTest("This test only runs on Windows") from pathlib import Path + root = Path(__file__).parent.parent.parent.absolute().as_posix() linter = Linter(encoding="utf-8", root=root) result = linter.run_cmd("dir", "tests\\basic", "code") @@ -57,6 +58,27 @@ class TestLinter(unittest.TestCase): self.assertIsNotNone(result) self.assertIn("Error message", result.text) + def test_run_cmd_with_special_chars(self): + with patch("subprocess.Popen") as mock_popen: + mock_process = MagicMock() + mock_process.returncode = 1 + mock_process.stdout.read.side_effect = ("Error message", None) + mock_popen.return_value = mock_process + + # Test with a file path containing special characters + special_path = "src/(main)/product/[id]/page.tsx" + result = self.linter.run_cmd("eslint", special_path, "code") + + # Verify that the command was constructed correctly + mock_popen.assert_called_once() + call_args = mock_popen.call_args[0][0] + + self.assertIn(special_path, call_args) + + # The result should contain the error message + self.assertIsNotNone(result) + self.assertIn("Error message", result.text) + if __name__ == "__main__": unittest.main() From 1167700a53580d8ce4cb5f489a60140b418306b2 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Wed, 7 May 2025 17:09:05 -0700 Subject: [PATCH 76/85] copy --- HISTORY.md | 22 +++---- aider/website/HISTORY.md | 22 +++---- aider/website/assets/sample-analytics.jsonl | 68 ++++++++++----------- aider/website/assets/sample.aider.conf.yml | 11 ++-- aider/website/assets/sample.env | 11 ++-- aider/website/docs/config/aider_conf.md | 11 ++-- aider/website/docs/config/dotenv.md | 11 ++-- aider/website/docs/config/options.md | 15 +++-- aider/website/docs/faq.md | 6 +- 9 files changed, 98 insertions(+), 79 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index d04306507..846f0b08f 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,16 @@ # Release history +### main branch + +- Set development version to 0.82.4.dev. +- Improved cost calculation using `litellm.completion_cost` where available. +- Fixed linter command execution on Windows by adopting `oslex` for argument quoting, by Titusz Pan. +- Enabled support for `thinking_tokens` and `reasoning_effort` parameters for OpenRouter models. +- Added support for `gemini-2.5-pro-preview-05-06` models. +- Added model settings for `openrouter/google/gemini-2.5-pro-preview-03-25`. + Introduced `--attribute-co-authored-by` option to add a `Co-authored-by: aider () ` trailer to AI-generated commits. This setting takes precedence over default author/committer name modifications unless `--attribute-author` or `--attribute-committer` are explicitly set to true, by Andrew Grigorev. + Aider wrote 55% of the code in this release. + ### Aider v0.82.3 - Add support for `gemini-2.5-flash-preview-04-17` models. @@ -12,17 +23,6 @@ - Set Gemini 2.5 Pro models to use the `overeager` prompt setting by default. - Add common file types (`.svg`, `.pdf`) to the default list of ignored files for AI comment scanning (`--watch`). - Skip scanning files larger than 1MB for AI comments (`--watch`). -- Aider wrote 67% of the code in this release. -### main branch - -- Set development version to 0.82.4.dev. -- Improved cost calculation using `litellm.completion_cost` where available. -- Fixed linter command execution on Windows by adopting `oslex` for argument quoting, by Titusz Pan. -- Enabled support for `thinking_tokens` and `reasoning_effort` parameters for OpenRouter models. -- Added support for `gemini-2.5-pro-preview-05-06` models. -- Added model settings for `openrouter/google/gemini-2.5-pro-preview-03-25`. -- Aider wrote 67% of the code in this release. - ### Aider v0.82.2 diff --git a/aider/website/HISTORY.md b/aider/website/HISTORY.md index cc39db23b..5adf61ec8 100644 --- a/aider/website/HISTORY.md +++ b/aider/website/HISTORY.md @@ -24,6 +24,17 @@ cog.out(text) ]]]--> +### main branch + +- Set development version to 0.82.4.dev. +- Improved cost calculation using `litellm.completion_cost` where available. +- Fixed linter command execution on Windows by adopting `oslex` for argument quoting, by Titusz Pan. +- Enabled support for `thinking_tokens` and `reasoning_effort` parameters for OpenRouter models. +- Added support for `gemini-2.5-pro-preview-05-06` models. +- Added model settings for `openrouter/google/gemini-2.5-pro-preview-03-25`. + Introduced `--attribute-co-authored-by` option to add a `Co-authored-by: aider () ` trailer to AI-generated commits. This setting takes precedence over default author/committer name modifications unless `--attribute-author` or `--attribute-committer` are explicitly set to true, by Andrew Grigorev. + Aider wrote 55% of the code in this release. + ### Aider v0.82.3 - Add support for `gemini-2.5-flash-preview-04-17` models. @@ -36,17 +47,6 @@ cog.out(text) - Set Gemini 2.5 Pro models to use the `overeager` prompt setting by default. - Add common file types (`.svg`, `.pdf`) to the default list of ignored files for AI comment scanning (`--watch`). - Skip scanning files larger than 1MB for AI comments (`--watch`). -- Aider wrote 67% of the code in this release. -### main branch - -- Set development version to 0.82.4.dev. -- Improved cost calculation using `litellm.completion_cost` where available. -- Fixed linter command execution on Windows by adopting `oslex` for argument quoting, by Titusz Pan. -- Enabled support for `thinking_tokens` and `reasoning_effort` parameters for OpenRouter models. -- Added support for `gemini-2.5-pro-preview-05-06` models. -- Added model settings for `openrouter/google/gemini-2.5-pro-preview-03-25`. -- Aider wrote 67% of the code in this release. - ### Aider v0.82.2 diff --git a/aider/website/assets/sample-analytics.jsonl b/aider/website/assets/sample-analytics.jsonl index c90524869..b0c5cc2d0 100644 --- a/aider/website/assets/sample-analytics.jsonl +++ b/aider/website/assets/sample-analytics.jsonl @@ -1,37 +1,3 @@ -{"event": "cli session", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173478} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173651} -{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff", "prompt_tokens": 13344, "completion_tokens": 1294, "total_tokens": 14638, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173666} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173674} -{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff", "prompt_tokens": 15409, "completion_tokens": 651, "total_tokens": 16060, "cost": 0.0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173687} -{"event": "command_undo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173750} -{"event": "command_undo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173754} -{"event": "command_clear", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173757} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173764} -{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff", "prompt_tokens": 13350, "completion_tokens": 721, "total_tokens": 14071, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173772} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173790} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173796} -{"event": "repo", "properties": {"num_files": 613}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173796} -{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173796} -{"event": "cli session", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173796} -{"event": "command_exit", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173798} -{"event": "exit", "properties": {"reason": "/exit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173798} -{"event": "exit", "properties": {"reason": "Control-C"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173873} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173898} -{"event": "repo", "properties": {"num_files": 613}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173898} -{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173898} -{"event": "cli session", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173898} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173908} -{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff", "prompt_tokens": 8723, "completion_tokens": 179, "total_tokens": 8902, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173914} -{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173939} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173954} -{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff", "prompt_tokens": 7633, "completion_tokens": 328, "total_tokens": 7961, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173960} -{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173967} -{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173985} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745173997} -{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff", "prompt_tokens": 25866, "completion_tokens": 543, "total_tokens": 26409, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745174004} -{"event": "command_undo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745174035} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745174044} -{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff", "prompt_tokens": 26460, "completion_tokens": 137, "total_tokens": 26597, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745174049} {"event": "command_drop", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745174055} {"event": "command_exit", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745174056} {"event": "exit", "properties": {"reason": "/exit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745174056} @@ -998,3 +964,37 @@ {"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746661684} {"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff-simple", "prompt_tokens": 6018, "completion_tokens": 231, "total_tokens": 6249, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746661749} {"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746661749} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746661993} +{"event": "repo", "properties": {"num_files": 617}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746661993} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746661993} +{"event": "exit", "properties": {"reason": "Completed lint/test/commit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746661998} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746662225} +{"event": "repo", "properties": {"num_files": 617}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746662225} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746662225} +{"event": "cli session", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff-simple"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746662226} +{"event": "command_edit", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746662230} +{"event": "command_ask", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746662273} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746662273} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "ask", "prompt_tokens": 14331, "completion_tokens": 2421, "total_tokens": 16752, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746662373} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746662390} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff-simple", "prompt_tokens": 17412, "completion_tokens": 2765, "total_tokens": 20177, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746662420} +{"event": "command_run", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746662480} +{"event": "command_run", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746662488} +{"event": "command_ask", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746662513} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746662513} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "ask", "prompt_tokens": 23117, "completion_tokens": 1083, "total_tokens": 24200, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746662558} +{"event": "command_undo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746662591} +{"event": "command_undo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746662601} +{"event": "command_undo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746662606} +{"event": "command_undo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746662610} +{"event": "exit", "properties": {"reason": "Control-C"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746662701} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746662833} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746662833} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746662833} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746662833} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746662878} +{"event": "repo", "properties": {"num_files": 617}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746662879} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746662879} +{"event": "cli session", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff-simple"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746662879} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff-simple", "prompt_tokens": 14673, "completion_tokens": 281, "total_tokens": 14954, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746662896} +{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746662896} diff --git a/aider/website/assets/sample.aider.conf.yml b/aider/website/assets/sample.aider.conf.yml index f5f902c9a..b9c51d5d9 100644 --- a/aider/website/assets/sample.aider.conf.yml +++ b/aider/website/assets/sample.aider.conf.yml @@ -224,11 +224,11 @@ ## Enable/disable commits when repo is found dirty (default: True) #dirty-commits: true -## Attribute aider code changes in the git author name (default: True) -#attribute-author: true +## Attribute aider code changes in the git author name (default: True). If explicitly set to True, overrides --attribute-co-authored-by precedence. +#attribute-author: xxx -## Attribute aider commits in the git committer name (default: True) -#attribute-committer: true +## Attribute aider commits in the git committer name (default: True). If explicitly set to True, overrides --attribute-co-authored-by precedence for aider edits. +#attribute-committer: xxx ## Prefix commit messages with 'aider: ' if aider authored the changes (default: False) #attribute-commit-message-author: false @@ -236,6 +236,9 @@ ## Prefix all commit messages with 'aider: ' (default: False) #attribute-commit-message-committer: false +## Attribute aider edits using the Co-authored-by trailer in the commit message (default: False). If True, this takes precedence over default --attribute-author and --attribute-committer behavior unless they are explicitly set to True. +#attribute-co-authored-by: false + ## Enable/disable git pre-commit hooks with --no-verify (default: False) #git-commit-verify: false diff --git a/aider/website/assets/sample.env b/aider/website/assets/sample.env index 439e637de..6f694b2cf 100644 --- a/aider/website/assets/sample.env +++ b/aider/website/assets/sample.env @@ -213,11 +213,11 @@ ## Enable/disable commits when repo is found dirty (default: True) #AIDER_DIRTY_COMMITS=true -## Attribute aider code changes in the git author name (default: True) -#AIDER_ATTRIBUTE_AUTHOR=true +## Attribute aider code changes in the git author name (default: True). If explicitly set to True, overrides --attribute-co-authored-by precedence. +#AIDER_ATTRIBUTE_AUTHOR= -## Attribute aider commits in the git committer name (default: True) -#AIDER_ATTRIBUTE_COMMITTER=true +## Attribute aider commits in the git committer name (default: True). If explicitly set to True, overrides --attribute-co-authored-by precedence for aider edits. +#AIDER_ATTRIBUTE_COMMITTER= ## Prefix commit messages with 'aider: ' if aider authored the changes (default: False) #AIDER_ATTRIBUTE_COMMIT_MESSAGE_AUTHOR=false @@ -225,6 +225,9 @@ ## Prefix all commit messages with 'aider: ' (default: False) #AIDER_ATTRIBUTE_COMMIT_MESSAGE_COMMITTER=false +## Attribute aider edits using the Co-authored-by trailer in the commit message (default: False). If True, this takes precedence over default --attribute-author and --attribute-committer behavior unless they are explicitly set to True. +#AIDER_ATTRIBUTE_CO_AUTHORED_BY=false + ## Enable/disable git pre-commit hooks with --no-verify (default: False) #AIDER_GIT_COMMIT_VERIFY=false diff --git a/aider/website/docs/config/aider_conf.md b/aider/website/docs/config/aider_conf.md index 40483ae4b..5bb380b14 100644 --- a/aider/website/docs/config/aider_conf.md +++ b/aider/website/docs/config/aider_conf.md @@ -278,11 +278,11 @@ cog.outl("```") ## Enable/disable commits when repo is found dirty (default: True) #dirty-commits: true -## Attribute aider code changes in the git author name (default: True) -#attribute-author: true +## Attribute aider code changes in the git author name (default: True). If explicitly set to True, overrides --attribute-co-authored-by precedence. +#attribute-author: xxx -## Attribute aider commits in the git committer name (default: True) -#attribute-committer: true +## Attribute aider commits in the git committer name (default: True). If explicitly set to True, overrides --attribute-co-authored-by precedence for aider edits. +#attribute-committer: xxx ## Prefix commit messages with 'aider: ' if aider authored the changes (default: False) #attribute-commit-message-author: false @@ -290,6 +290,9 @@ cog.outl("```") ## Prefix all commit messages with 'aider: ' (default: False) #attribute-commit-message-committer: false +## Attribute aider edits using the Co-authored-by trailer in the commit message (default: False). If True, this takes precedence over default --attribute-author and --attribute-committer behavior unless they are explicitly set to True. +#attribute-co-authored-by: false + ## Enable/disable git pre-commit hooks with --no-verify (default: False) #git-commit-verify: false diff --git a/aider/website/docs/config/dotenv.md b/aider/website/docs/config/dotenv.md index 5a1c616e8..8ef6d3567 100644 --- a/aider/website/docs/config/dotenv.md +++ b/aider/website/docs/config/dotenv.md @@ -253,11 +253,11 @@ cog.outl("```") ## Enable/disable commits when repo is found dirty (default: True) #AIDER_DIRTY_COMMITS=true -## Attribute aider code changes in the git author name (default: True) -#AIDER_ATTRIBUTE_AUTHOR=true +## Attribute aider code changes in the git author name (default: True). If explicitly set to True, overrides --attribute-co-authored-by precedence. +#AIDER_ATTRIBUTE_AUTHOR= -## Attribute aider commits in the git committer name (default: True) -#AIDER_ATTRIBUTE_COMMITTER=true +## Attribute aider commits in the git committer name (default: True). If explicitly set to True, overrides --attribute-co-authored-by precedence for aider edits. +#AIDER_ATTRIBUTE_COMMITTER= ## Prefix commit messages with 'aider: ' if aider authored the changes (default: False) #AIDER_ATTRIBUTE_COMMIT_MESSAGE_AUTHOR=false @@ -265,6 +265,9 @@ cog.outl("```") ## Prefix all commit messages with 'aider: ' (default: False) #AIDER_ATTRIBUTE_COMMIT_MESSAGE_COMMITTER=false +## Attribute aider edits using the Co-authored-by trailer in the commit message (default: False). If True, this takes precedence over default --attribute-author and --attribute-committer behavior unless they are explicitly set to True. +#AIDER_ATTRIBUTE_CO_AUTHORED_BY=false + ## Enable/disable git pre-commit hooks with --no-verify (default: False) #AIDER_GIT_COMMIT_VERIFY=false diff --git a/aider/website/docs/config/options.md b/aider/website/docs/config/options.md index d07234921..8468c2bc3 100644 --- a/aider/website/docs/config/options.md +++ b/aider/website/docs/config/options.md @@ -56,6 +56,7 @@ usage: aider [-h] [--model] [--openai-api-key] [--anthropic-api-key] [--attribute-committer | --no-attribute-committer] [--attribute-commit-message-author | --no-attribute-commit-message-author] [--attribute-commit-message-committer | --no-attribute-commit-message-committer] + [--attribute-co-authored-by | --no-attribute-co-authored-by] [--git-commit-verify | --no-git-commit-verify] [--commit] [--commit-prompt] [--dry-run | --no-dry-run] [--skip-sanity-check-repo] @@ -412,16 +413,14 @@ Aliases: - `--no-dirty-commits` ### `--attribute-author` -Attribute aider code changes in the git author name (default: True) -Default: True +Attribute aider code changes in the git author name (default: True). If explicitly set to True, overrides --attribute-co-authored-by precedence. Environment variable: `AIDER_ATTRIBUTE_AUTHOR` Aliases: - `--attribute-author` - `--no-attribute-author` ### `--attribute-committer` -Attribute aider commits in the git committer name (default: True) -Default: True +Attribute aider commits in the git committer name (default: True). If explicitly set to True, overrides --attribute-co-authored-by precedence for aider edits. Environment variable: `AIDER_ATTRIBUTE_COMMITTER` Aliases: - `--attribute-committer` @@ -443,6 +442,14 @@ Aliases: - `--attribute-commit-message-committer` - `--no-attribute-commit-message-committer` +### `--attribute-co-authored-by` +Attribute aider edits using the Co-authored-by trailer in the commit message (default: False). If True, this takes precedence over default --attribute-author and --attribute-committer behavior unless they are explicitly set to True. +Default: False +Environment variable: `AIDER_ATTRIBUTE_CO_AUTHORED_BY` +Aliases: + - `--attribute-co-authored-by` + - `--no-attribute-co-authored-by` + ### `--git-commit-verify` Enable/disable git pre-commit hooks with --no-verify (default: False) Default: False diff --git a/aider/website/docs/faq.md b/aider/website/docs/faq.md index 871a030b0..c16807ee5 100644 --- a/aider/website/docs/faq.md +++ b/aider/website/docs/faq.md @@ -264,9 +264,9 @@ tr:hover { background-color: #f5f5f5; }
Model NameTotal TokensPercent
gemini/gemini-2.5-pro-exp-03-251,315,56467.0%
gemini/gemini-2.5-pro-preview-03-25442,01922.5%
o3138,8427.1%
gemini/gemini-2.5-pro-exp-03-251,321,81367.1%
gemini/gemini-2.5-pro-preview-03-25442,01922.4%
o3138,8427.0%
openrouter/anthropic/claude-3.7-sonnet41,0172.1%
gemini/gemini-2.5-flash-preview-04-1710,3050.5%
gemini/gemini-2.5-pro-preview-05-068,5760.4%
- - - + + + From 765ac2a14d43541980b2899fa98344c4d51f6b4e Mon Sep 17 00:00:00 2001 From: "Paul Gauthier (aider)" Date: Wed, 7 May 2025 17:11:03 -0700 Subject: [PATCH 77/85] Feat: Add gemini-2.5-pro-preview-05-06 model entries --- aider/resources/model-settings.yml | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/aider/resources/model-settings.yml b/aider/resources/model-settings.yml index 8a7567d49..f3dbf2ae0 100644 --- a/aider/resources/model-settings.yml +++ b/aider/resources/model-settings.yml @@ -1391,4 +1391,22 @@ edit_format: diff-fenced use_repo_map: true weak_model_name: openrouter/google/gemini-2.0-flash-001 - \ No newline at end of file + +- name: gemini/gemini-2.5-pro-preview-05-06 + overeager: true + edit_format: diff-fenced + use_repo_map: true + weak_model_name: gemini/gemini-2.0-flash + +- name: vertex_ai/gemini-2.5-pro-preview-05-06 + edit_format: diff-fenced + use_repo_map: true + weak_model_name: vertex_ai-language-models/gemini-2.5-flash-preview-04-17 + overeager: true + editor_model_name: vertex_ai-language-models/gemini-2.5-flash-preview-04-17 + +- name: openrouter/google/gemini-2.5-pro-preview-05-06 + edit_format: diff-fenced + use_repo_map: true + weak_model_name: openrouter/google/gemini-2.0-flash-001 + From 84d6cf937bb6b6712da4ded904b841598b45ed6c Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Wed, 7 May 2025 17:13:36 -0700 Subject: [PATCH 78/85] chore: Mark Gemini 2.5 Pro previews as overeager --- aider/resources/model-settings.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/aider/resources/model-settings.yml b/aider/resources/model-settings.yml index f3dbf2ae0..1046023a3 100644 --- a/aider/resources/model-settings.yml +++ b/aider/resources/model-settings.yml @@ -1388,6 +1388,7 @@ accepts_settings: ["thinking_tokens"] - name: openrouter/google/gemini-2.5-pro-preview-03-25 + overeager: true edit_format: diff-fenced use_repo_map: true weak_model_name: openrouter/google/gemini-2.0-flash-001 @@ -1406,6 +1407,7 @@ editor_model_name: vertex_ai-language-models/gemini-2.5-flash-preview-04-17 - name: openrouter/google/gemini-2.5-pro-preview-05-06 + overeager: true edit_format: diff-fenced use_repo_map: true weak_model_name: openrouter/google/gemini-2.0-flash-001 From 67cbda3bd50f8d4bd9119d850c30c13db4a17884 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Wed, 7 May 2025 17:25:29 -0700 Subject: [PATCH 79/85] docs: Explain --attribute-co-authored-by and its interaction --- aider/website/docs/git.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/aider/website/docs/git.md b/aider/website/docs/git.md index 00ee5a272..572e1b703 100644 --- a/aider/website/docs/git.md +++ b/aider/website/docs/git.md @@ -71,4 +71,6 @@ Additionally, you can use the following options to prefix commit messages: - `--attribute-commit-message-author`: Prefix commit messages with 'aider: ' if aider authored the changes. - `--attribute-commit-message-committer`: Prefix all commit messages with 'aider: ', regardless of whether aider authored the changes or not. -Both of these options are disabled by default, but can be useful for easily identifying changes made by aider. +Finally, you can use `--attribute-co-authored-by` to have aider append a Co-authored-by trailer to the end of the commit string. +This will disable appending `(aider)` to the git author and git committer unless you have explicitly enabled those settings. + From 8dd8fb52f4007836884e8308420e94334217966e Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Wed, 7 May 2025 18:08:00 -0700 Subject: [PATCH 80/85] copy --- HISTORY.md | 5 +- aider/website/HISTORY.md | 5 +- aider/website/assets/sample-analytics.jsonl | 58 +++++++++---------- aider/website/assets/sample.aider.conf.yml | 3 + aider/website/assets/sample.env | 3 + .../website/docs/config/adv-model-settings.md | 20 +++++++ aider/website/docs/config/aider_conf.md | 3 + aider/website/docs/config/dotenv.md | 3 + aider/website/docs/config/options.md | 12 +++- aider/website/docs/faq.md | 6 +- 10 files changed, 81 insertions(+), 37 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 846f0b08f..c2bf06ebe 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -9,7 +9,10 @@ - Added support for `gemini-2.5-pro-preview-05-06` models. - Added model settings for `openrouter/google/gemini-2.5-pro-preview-03-25`. Introduced `--attribute-co-authored-by` option to add a `Co-authored-by: aider () ` trailer to AI-generated commits. This setting takes precedence over default author/committer name modifications unless `--attribute-author` or `--attribute-committer` are explicitly set to true, by Andrew Grigorev. - Aider wrote 55% of the code in this release. + Added `--disable-playwright` flag to prevent Playwright installation prompts and usage, by Andrew Grigorev. + Added repomap support for OCaml and OCaml interface files, by Andrey Popp. + Improved cross-platform display of shell commands by using `oslex` for robust argument quoting, by Titusz Pan. + Aider wrote 44% of the code in this release. ### Aider v0.82.3 diff --git a/aider/website/HISTORY.md b/aider/website/HISTORY.md index 5adf61ec8..3b3d9d4cc 100644 --- a/aider/website/HISTORY.md +++ b/aider/website/HISTORY.md @@ -33,7 +33,10 @@ cog.out(text) - Added support for `gemini-2.5-pro-preview-05-06` models. - Added model settings for `openrouter/google/gemini-2.5-pro-preview-03-25`. Introduced `--attribute-co-authored-by` option to add a `Co-authored-by: aider () ` trailer to AI-generated commits. This setting takes precedence over default author/committer name modifications unless `--attribute-author` or `--attribute-committer` are explicitly set to true, by Andrew Grigorev. - Aider wrote 55% of the code in this release. + Added `--disable-playwright` flag to prevent Playwright installation prompts and usage, by Andrew Grigorev. + Added repomap support for OCaml and OCaml interface files, by Andrey Popp. + Improved cross-platform display of shell commands by using `oslex` for robust argument quoting, by Titusz Pan. + Aider wrote 44% of the code in this release. ### Aider v0.82.3 diff --git a/aider/website/assets/sample-analytics.jsonl b/aider/website/assets/sample-analytics.jsonl index b0c5cc2d0..ba787a162 100644 --- a/aider/website/assets/sample-analytics.jsonl +++ b/aider/website/assets/sample-analytics.jsonl @@ -1,32 +1,3 @@ -{"event": "command_drop", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745174055} -{"event": "command_exit", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745174056} -{"event": "exit", "properties": {"reason": "/exit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745174056} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745174643} -{"event": "repo", "properties": {"num_files": 615}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745174643} -{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745174643} -{"event": "cli session", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff-simple"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745174643} -{"event": "command_exit", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745174645} -{"event": "exit", "properties": {"reason": "/exit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745174645} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745175891} -{"event": "repo", "properties": {"num_files": 615}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745175892} -{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745175892} -{"event": "exit", "properties": {"reason": "Showed prompts"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745175896} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745189251} -{"event": "repo", "properties": {"num_files": 615}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745189251} -{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745189251} -{"event": "exit", "properties": {"reason": "Completed lint/test/commit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745189254} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745189929} -{"event": "repo", "properties": {"num_files": 615}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745189931} -{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745189931} -{"event": "exit", "properties": {"reason": "Completed lint/test/commit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745189934} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745189982} -{"event": "exit", "properties": {"reason": "Listed models"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745189984} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745189999} -{"event": "repo", "properties": {"num_files": 615}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745190000} -{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745190000} -{"event": "cli session", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff-simple"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745190000} -{"event": "command_add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745190007} -{"event": "command_edit", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745190022} {"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745190053} {"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff-simple", "prompt_tokens": 16858, "completion_tokens": 143, "total_tokens": 17001, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745190062} {"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745190237} @@ -998,3 +969,32 @@ {"event": "cli session", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff-simple"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746662879} {"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff-simple", "prompt_tokens": 14673, "completion_tokens": 281, "total_tokens": 14954, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746662896} {"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746662896} +{"event": "ai-comments file-add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746662898} +{"event": "ai-comments file-add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746662900} +{"event": "command_drop", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746662909} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746662959} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff-simple", "prompt_tokens": 16375, "completion_tokens": 343, "total_tokens": 16718, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746663063} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746663153} +{"event": "repo", "properties": {"num_files": 617}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746663154} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746663154} +{"event": "cli session", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff-simple"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746663154} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746663170} +{"event": "command_exit", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746663207} +{"event": "exit", "properties": {"reason": "/exit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746663207} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746663212} +{"event": "repo", "properties": {"num_files": 617}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746663213} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746663213} +{"event": "exit", "properties": {"reason": "Completed lint/test/commit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746663216} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff-simple", "prompt_tokens": 11173, "completion_tokens": 947, "total_tokens": 12120, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746663253} +{"event": "command_undo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746663802} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746663926} +{"event": "repo", "properties": {"num_files": 617}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746663926} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746663926} +{"event": "exit", "properties": {"reason": "Completed lint/test/commit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746663929} +{"event": "exit", "properties": {"reason": "Completed main CLI coder.run"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746664012} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746664482} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746664482} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746664482} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746664482} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff-simple", "prompt_tokens": 19959, "completion_tokens": 176, "total_tokens": 20135, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746664554} +{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746664554} diff --git a/aider/website/assets/sample.aider.conf.yml b/aider/website/assets/sample.aider.conf.yml index b9c51d5d9..da6956cd5 100644 --- a/aider/website/assets/sample.aider.conf.yml +++ b/aider/website/assets/sample.aider.conf.yml @@ -361,6 +361,9 @@ ################# # Other settings: +## Never prompt for or attempt to install Playwright for web scraping (default: False). +#disable-playwright: false + ## specify a file to edit (can be used multiple times) #file: xxx ## Specify multiple values like this: diff --git a/aider/website/assets/sample.env b/aider/website/assets/sample.env index 6f694b2cf..b08bb1a38 100644 --- a/aider/website/assets/sample.env +++ b/aider/website/assets/sample.env @@ -342,6 +342,9 @@ ################# # Other settings: +## Never prompt for or attempt to install Playwright for web scraping (default: False). +#AIDER_DISABLE_PLAYWRIGHT=false + ## specify a file to edit (can be used multiple times) #AIDER_FILE= diff --git a/aider/website/docs/config/adv-model-settings.md b/aider/website/docs/config/adv-model-settings.md index b1a683b61..e9301d5b5 100644 --- a/aider/website/docs/config/adv-model-settings.md +++ b/aider/website/docs/config/adv-model-settings.md @@ -692,6 +692,12 @@ cog.out("```\n") use_repo_map: true overeager: true +- name: gemini/gemini-2.5-pro-preview-05-06 + edit_format: diff-fenced + weak_model_name: gemini/gemini-2.0-flash + use_repo_map: true + overeager: true + - name: gemini/gemini-exp-1114 edit_format: diff use_repo_map: true @@ -1226,6 +1232,13 @@ cog.out("```\n") edit_format: diff-fenced weak_model_name: openrouter/google/gemini-2.0-flash-001 use_repo_map: true + overeager: true + +- name: openrouter/google/gemini-2.5-pro-preview-05-06 + edit_format: diff-fenced + weak_model_name: openrouter/google/gemini-2.0-flash-001 + use_repo_map: true + overeager: true - name: openrouter/google/gemma-3-27b-it use_system_prompt: false @@ -1500,6 +1513,13 @@ cog.out("```\n") overeager: true editor_model_name: vertex_ai-language-models/gemini-2.5-flash-preview-04-17 +- name: vertex_ai/gemini-2.5-pro-preview-05-06 + edit_format: diff-fenced + weak_model_name: vertex_ai-language-models/gemini-2.5-flash-preview-04-17 + use_repo_map: true + overeager: true + editor_model_name: vertex_ai-language-models/gemini-2.5-flash-preview-04-17 + - 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 5bb380b14..3eb580bce 100644 --- a/aider/website/docs/config/aider_conf.md +++ b/aider/website/docs/config/aider_conf.md @@ -415,6 +415,9 @@ cog.outl("```") ################# # Other settings: +## Never prompt for or attempt to install Playwright for web scraping (default: False). +#disable-playwright: false + ## specify a file to edit (can be used multiple times) #file: xxx ## Specify multiple values like this: diff --git a/aider/website/docs/config/dotenv.md b/aider/website/docs/config/dotenv.md index 8ef6d3567..5dff49c51 100644 --- a/aider/website/docs/config/dotenv.md +++ b/aider/website/docs/config/dotenv.md @@ -382,6 +382,9 @@ cog.outl("```") ################# # Other settings: +## Never prompt for or attempt to install Playwright for web scraping (default: False). +#AIDER_DISABLE_PLAYWRIGHT=false + ## specify a file to edit (can be used multiple times) #AIDER_FILE= diff --git a/aider/website/docs/config/options.md b/aider/website/docs/config/options.md index 8468c2bc3..f0bbe5177 100644 --- a/aider/website/docs/config/options.md +++ b/aider/website/docs/config/options.md @@ -73,9 +73,10 @@ usage: aider [-h] [--model] [--openai-api-key] [--anthropic-api-key] [--copy-paste | --no-copy-paste] [--apply] [--apply-clipboard-edits] [--exit] [--show-repo-map] [--show-prompts] [--voice-format] [--voice-language] - [--voice-input-device] [--file] [--read] [--vim] - [--chat-language] [--yes-always] [-v] [--load] - [--encoding] [--line-endings] [-c] [--env-file] + [--voice-input-device] [--disable-playwright] [--file] + [--read] [--vim] [--chat-language] [--yes-always] [-v] + [--load] [--encoding] [--line-endings] [-c] + [--env-file] [--suggest-shell-commands | --no-suggest-shell-commands] [--fancy-input | --no-fancy-input] [--multiline | --no-multiline] @@ -659,6 +660,11 @@ Environment variable: `AIDER_VOICE_INPUT_DEVICE` ## Other settings: +### `--disable-playwright` +Never prompt for or attempt to install Playwright for web scraping (default: False). +Default: False +Environment variable: `AIDER_DISABLE_PLAYWRIGHT` + ### `--file FILE` specify a file to edit (can be used multiple times) Environment variable: `AIDER_FILE` diff --git a/aider/website/docs/faq.md b/aider/website/docs/faq.md index c16807ee5..6a9d144f9 100644 --- a/aider/website/docs/faq.md +++ b/aider/website/docs/faq.md @@ -264,9 +264,9 @@ tr:hover { background-color: #f5f5f5; }
Model NameTotal TokensPercent
gemini/gemini-2.5-pro-exp-03-251,321,81367.1%
gemini/gemini-2.5-pro-preview-03-25442,01922.4%
o3138,8427.0%
gemini/gemini-2.5-pro-exp-03-251,283,25866.4%
gemini/gemini-2.5-pro-preview-03-25442,01922.9%
o3138,8427.2%
openrouter/anthropic/claude-3.7-sonnet41,0172.1%
gemini/gemini-2.5-flash-preview-04-1710,3050.5%
gemini/gemini-2.5-pro-preview-05-068,5760.4%
- - - + + + From fe20e528b0163ae89db7618a155a7c5b1ec964c9 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Wed, 7 May 2025 18:09:09 -0700 Subject: [PATCH 81/85] pick up grep-ast 0.9.0 for ml/mli --- requirements.txt | 2 +- requirements/common-constraints.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 52137b7e8..f3c08d722 100644 --- a/requirements.txt +++ b/requirements.txt @@ -137,7 +137,7 @@ googleapis-common-protos==1.70.0 # -c requirements/common-constraints.txt # google-api-core # grpcio-status -grep-ast==0.8.1 +grep-ast==0.9.0 # via # -c requirements/common-constraints.txt # -r requirements/requirements.in diff --git a/requirements/common-constraints.txt b/requirements/common-constraints.txt index aaf158695..e23b6c23a 100644 --- a/requirements/common-constraints.txt +++ b/requirements/common-constraints.txt @@ -160,7 +160,7 @@ greenlet==3.2.1 # via # playwright # sqlalchemy -grep-ast==0.8.1 +grep-ast==0.9.0 # via -r requirements/requirements.in griffe==1.7.3 # via banks From 8bb971c15d07139565b9e204450d138f74380b52 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Wed, 7 May 2025 18:11:09 -0700 Subject: [PATCH 82/85] copy --- HISTORY.md | 15 +++++++-------- aider/website/HISTORY.md | 15 +++++++-------- aider/website/docs/languages.md | 2 ++ 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index c2bf06ebe..48a965555 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,16 +2,15 @@ ### main branch -- Set development version to 0.82.4.dev. +- Added support for `gemini-2.5-pro-preview-05-06` models. +- Enabled support for `thinking_tokens` and `reasoning_effort` parameters for OpenRouter models. +- Added model settings for `openrouter/google/gemini-2.5-pro-preview-03-25`. + Introduced `--attribute-co-authored-by` option to add co-author trailer to commit messages, by Andrew Grigorev. +- Added `--disable-playwright` flag to prevent Playwright installation prompts and usage, by Andrew Grigorev. +- Added repomap support for OCaml and OCaml interface files, by Andrey Popp. - Improved cost calculation using `litellm.completion_cost` where available. - Fixed linter command execution on Windows by adopting `oslex` for argument quoting, by Titusz Pan. -- Enabled support for `thinking_tokens` and `reasoning_effort` parameters for OpenRouter models. -- Added support for `gemini-2.5-pro-preview-05-06` models. -- Added model settings for `openrouter/google/gemini-2.5-pro-preview-03-25`. - Introduced `--attribute-co-authored-by` option to add a `Co-authored-by: aider () ` trailer to AI-generated commits. This setting takes precedence over default author/committer name modifications unless `--attribute-author` or `--attribute-committer` are explicitly set to true, by Andrew Grigorev. - Added `--disable-playwright` flag to prevent Playwright installation prompts and usage, by Andrew Grigorev. - Added repomap support for OCaml and OCaml interface files, by Andrey Popp. - Improved cross-platform display of shell commands by using `oslex` for robust argument quoting, by Titusz Pan. +- Improved cross-platform display of shell commands by using `oslex` for robust argument quoting, by Titusz Pan. Aider wrote 44% of the code in this release. ### Aider v0.82.3 diff --git a/aider/website/HISTORY.md b/aider/website/HISTORY.md index 3b3d9d4cc..81eedc99c 100644 --- a/aider/website/HISTORY.md +++ b/aider/website/HISTORY.md @@ -26,16 +26,15 @@ cog.out(text) ### main branch -- Set development version to 0.82.4.dev. +- Added support for `gemini-2.5-pro-preview-05-06` models. +- Enabled support for `thinking_tokens` and `reasoning_effort` parameters for OpenRouter models. +- Added model settings for `openrouter/google/gemini-2.5-pro-preview-03-25`. + Introduced `--attribute-co-authored-by` option to add co-author trailer to commit messages, by Andrew Grigorev. +- Added `--disable-playwright` flag to prevent Playwright installation prompts and usage, by Andrew Grigorev. +- Added repomap support for OCaml and OCaml interface files, by Andrey Popp. - Improved cost calculation using `litellm.completion_cost` where available. - Fixed linter command execution on Windows by adopting `oslex` for argument quoting, by Titusz Pan. -- Enabled support for `thinking_tokens` and `reasoning_effort` parameters for OpenRouter models. -- Added support for `gemini-2.5-pro-preview-05-06` models. -- Added model settings for `openrouter/google/gemini-2.5-pro-preview-03-25`. - Introduced `--attribute-co-authored-by` option to add a `Co-authored-by: aider () ` trailer to AI-generated commits. This setting takes precedence over default author/committer name modifications unless `--attribute-author` or `--attribute-committer` are explicitly set to true, by Andrew Grigorev. - Added `--disable-playwright` flag to prevent Playwright installation prompts and usage, by Andrew Grigorev. - Added repomap support for OCaml and OCaml interface files, by Andrey Popp. - Improved cross-platform display of shell commands by using `oslex` for robust argument quoting, by Titusz Pan. +- Improved cross-platform display of shell commands by using `oslex` for robust argument quoting, by Titusz Pan. Aider wrote 44% of the code in this release. ### Aider v0.82.3 diff --git a/aider/website/docs/languages.md b/aider/website/docs/languages.md index ff9c14bfc..f5eba91ca 100644 --- a/aider/website/docs/languages.md +++ b/aider/website/docs/languages.md @@ -180,6 +180,8 @@ cog.out(get_supported_languages_md()) | nix | .nix | | ✓ | | nqc | .nqc | | ✓ | | objc | .mm | | ✓ | +| ocaml | .ml | ✓ | ✓ | +| ocaml_interface | .mli | ✓ | ✓ | | odin | .odin | | ✓ | | org | .org | | ✓ | | pascal | .pas | | ✓ | From 592dea0f8c421c1cdf1ff5e88714812a19e67978 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Wed, 7 May 2025 18:17:16 -0700 Subject: [PATCH 83/85] chore: Update weak model name for gemini to 2.5 flash preview --- aider/resources/model-settings.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aider/resources/model-settings.yml b/aider/resources/model-settings.yml index 1046023a3..4504ffffd 100644 --- a/aider/resources/model-settings.yml +++ b/aider/resources/model-settings.yml @@ -1397,7 +1397,7 @@ overeager: true edit_format: diff-fenced use_repo_map: true - weak_model_name: gemini/gemini-2.0-flash + weak_model_name: gemini/gemini-2.5-flash-preview-04-17 - name: vertex_ai/gemini-2.5-pro-preview-05-06 edit_format: diff-fenced From 4ab8faf21e04489caf1d2f0dfbace03521e90b25 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Wed, 7 May 2025 18:27:35 -0700 Subject: [PATCH 84/85] copy --- HISTORY.md | 5 +- aider/website/HISTORY.md | 5 +- aider/website/assets/sample-analytics.jsonl | 108 +++++++++--------- .../website/docs/config/adv-model-settings.md | 2 +- aider/website/docs/faq.md | 9 +- 5 files changed, 65 insertions(+), 64 deletions(-) diff --git a/HISTORY.md b/HISTORY.md index 48a965555..5ea1c939f 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,17 +1,18 @@ # Release history ### main branch - +- Automatically fetch model parameters (context window, pricing) for OpenRouter models directly from their website, by Stefan Hladnik. - Added support for `gemini-2.5-pro-preview-05-06` models. - Enabled support for `thinking_tokens` and `reasoning_effort` parameters for OpenRouter models. - Added model settings for `openrouter/google/gemini-2.5-pro-preview-03-25`. Introduced `--attribute-co-authored-by` option to add co-author trailer to commit messages, by Andrew Grigorev. - Added `--disable-playwright` flag to prevent Playwright installation prompts and usage, by Andrew Grigorev. +- The `aider scrape` command-line tool will now use Playwright for web scraping if it is available, by Jon Keys. - Added repomap support for OCaml and OCaml interface files, by Andrey Popp. - Improved cost calculation using `litellm.completion_cost` where available. - Fixed linter command execution on Windows by adopting `oslex` for argument quoting, by Titusz Pan. - Improved cross-platform display of shell commands by using `oslex` for robust argument quoting, by Titusz Pan. - Aider wrote 44% of the code in this release. +- Aider wrote 45% of the code in this release. ### Aider v0.82.3 diff --git a/aider/website/HISTORY.md b/aider/website/HISTORY.md index 81eedc99c..60fba240e 100644 --- a/aider/website/HISTORY.md +++ b/aider/website/HISTORY.md @@ -25,17 +25,18 @@ cog.out(text) ### main branch - +- Automatically fetch model parameters (context window, pricing) for OpenRouter models directly from their website, by Stefan Hladnik. - Added support for `gemini-2.5-pro-preview-05-06` models. - Enabled support for `thinking_tokens` and `reasoning_effort` parameters for OpenRouter models. - Added model settings for `openrouter/google/gemini-2.5-pro-preview-03-25`. Introduced `--attribute-co-authored-by` option to add co-author trailer to commit messages, by Andrew Grigorev. - Added `--disable-playwright` flag to prevent Playwright installation prompts and usage, by Andrew Grigorev. +- The `aider scrape` command-line tool will now use Playwright for web scraping if it is available, by Jon Keys. - Added repomap support for OCaml and OCaml interface files, by Andrey Popp. - Improved cost calculation using `litellm.completion_cost` where available. - Fixed linter command execution on Windows by adopting `oslex` for argument quoting, by Titusz Pan. - Improved cross-platform display of shell commands by using `oslex` for robust argument quoting, by Titusz Pan. - Aider wrote 44% of the code in this release. +- Aider wrote 45% of the code in this release. ### Aider v0.82.3 diff --git a/aider/website/assets/sample-analytics.jsonl b/aider/website/assets/sample-analytics.jsonl index ba787a162..4a5968384 100644 --- a/aider/website/assets/sample-analytics.jsonl +++ b/aider/website/assets/sample-analytics.jsonl @@ -1,57 +1,3 @@ -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745190053} -{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff-simple", "prompt_tokens": 16858, "completion_tokens": 143, "total_tokens": 17001, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745190062} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745190237} -{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff-simple", "prompt_tokens": 17173, "completion_tokens": 312, "total_tokens": 17485, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745190243} -{"event": "command_exit", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745190249} -{"event": "exit", "properties": {"reason": "/exit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745190249} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745190260} -{"event": "repo", "properties": {"num_files": 615}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745190262} -{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745190262} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745190262} -{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-flash-preview-04-17", "weak_model": "gemini/gemini-2.5-flash-preview-04-17", "editor_model": "gemini/gemini-2.5-flash-preview-04-17", "edit_format": "diff", "prompt_tokens": 10189, "completion_tokens": 116, "total_tokens": 10305, "cost": 0.0015979499999999999, "total_cost": 0.0015979499999999999}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745190272} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745190955} -{"event": "repo", "properties": {"num_files": 615}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745190955} -{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745190955} -{"event": "cli session", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff-simple"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745190955} -{"event": "command_edit", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745190964} -{"event": "command_ask", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745191011} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745191011} -{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "ask", "prompt_tokens": 8442, "completion_tokens": 417, "total_tokens": 8859, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745191025} -{"event": "command_ask", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745191054} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745191054} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745191127} -{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff-simple", "prompt_tokens": 14287, "completion_tokens": 1995, "total_tokens": 16282, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745191145} -{"event": "command_clear", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745191182} -{"event": "command_ask", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745191214} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745191214} -{"event": "command_clear", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745191224} -{"event": "command_edit", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745191228} -{"event": "command_ask", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745191286} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745191286} -{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "ask", "prompt_tokens": 8481, "completion_tokens": 1848, "total_tokens": 10329, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745191334} -{"event": "command_clear", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745191533} -{"event": "ai-comments execute", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745191535} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745191535} -{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff-simple", "prompt_tokens": 8611, "completion_tokens": 89, "total_tokens": 8700, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745191553} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745192191} -{"event": "repo", "properties": {"num_files": 615}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745192191} -{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745192191} -{"event": "exit", "properties": {"reason": "Completed lint/test/commit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745192196} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745192301} -{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745192301} -{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745192301} -{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745192301} -{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff-simple", "prompt_tokens": 7873, "completion_tokens": 147, "total_tokens": 8020, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745192314} -{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745192314} -{"event": "ai-comments file-add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745192315} -{"event": "ai-comments file-add", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745192318} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745192612} -{"event": "repo", "properties": {"num_files": 615}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745192612} -{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745192612} -{"event": "exit", "properties": {"reason": "Completed lint/test/commit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745192615} -{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745194554} -{"event": "repo", "properties": {"num_files": 615}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745194556} -{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745194556} {"event": "cli session", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff-simple"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745194556} {"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745194568} {"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1745194656} @@ -998,3 +944,57 @@ {"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746664482} {"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff-simple", "prompt_tokens": 19959, "completion_tokens": 176, "total_tokens": 20135, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746664554} {"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746664554} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746666729} +{"event": "repo", "properties": {"num_files": 621}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746666730} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746666730} +{"event": "exit", "properties": {"reason": "Completed lint/test/commit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746666733} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746666821} +{"event": "repo", "properties": {"num_files": 621}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746666822} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746666822} +{"event": "exit", "properties": {"reason": "Completed lint/test/commit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746666825} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746666956} +{"event": "repo", "properties": {"num_files": 621}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746666956} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746666956} +{"event": "cli session", "properties": {"main_model": "gemini/gemini-2.0-flash", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.0-flash", "edit_format": "diff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746666956} +{"event": "exit", "properties": {"reason": "Completed main CLI coder.run"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746666960} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746666962} +{"event": "repo", "properties": {"num_files": 621}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746666962} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746666962} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746666966} +{"event": "model warning", "properties": {"main_model": "gemini/REDACTED", "weak_model": "gemini/REDACTED", "editor_model": "gemini/REDACTED"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746666968} +{"event": "exit", "properties": {"reason": "Keyboard interrupt during model warnings"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746666988} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746666997} +{"event": "repo", "properties": {"num_files": 621}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746666997} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746666997} +{"event": "cli session", "properties": {"main_model": "gemini/gemini-2.5-flash-preview-04-17", "weak_model": "gemini/gemini-2.5-flash-preview-04-17", "editor_model": "gemini/gemini-2.5-flash-preview-04-17", "edit_format": "diff"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746666997} +{"event": "command_exit", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746666999} +{"event": "exit", "properties": {"reason": "/exit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746666999} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746667009} +{"event": "model warning", "properties": {"main_model": "openrouter/REDACTED", "weak_model": "openrouter/REDACTED", "editor_model": "openrouter/REDACTED"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746667011} +{"event": "exit", "properties": {"reason": "Keyboard interrupt during model warnings"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746667027} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746667033} +{"event": "repo", "properties": {"num_files": 621}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746667033} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746667033} +{"event": "exit", "properties": {"reason": "Completed lint/test/commit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746667036} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746667201} +{"event": "model warning", "properties": {"main_model": "openrouter/REDACTED", "weak_model": "openrouter/REDACTED", "editor_model": "openrouter/REDACTED"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746667203} +{"event": "repo", "properties": {"num_files": 621}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746667207} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746667207} +{"event": "cli session", "properties": {"main_model": "openrouter/REDACTED", "weak_model": "openrouter/REDACTED", "editor_model": "openrouter/REDACTED", "edit_format": "whole"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746667207} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746667209} +{"event": "command_exit", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746667229} +{"event": "exit", "properties": {"reason": "/exit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746667229} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746667436} +{"event": "repo", "properties": {"num_files": 621}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746667439} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746667439} +{"event": "cli session", "properties": {"main_model": "openrouter/REDACTED", "weak_model": "openrouter/REDACTED", "editor_model": "openrouter/REDACTED", "edit_format": "whole"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746667439} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746667441} +{"event": "message_send", "properties": {"main_model": "openrouter/REDACTED", "weak_model": "openrouter/REDACTED", "editor_model": "openrouter/REDACTED", "edit_format": "whole", "prompt_tokens": 9655, "completion_tokens": 395, "total_tokens": 10050, "cost": 0.00168525, "total_cost": 0.00168525}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746667458} +{"event": "command_exit", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746667467} +{"event": "exit", "properties": {"reason": "/exit"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746667467} +{"event": "launched", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746667540} +{"event": "no-repo", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746667540} +{"event": "auto_commits", "properties": {"enabled": true}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746667540} +{"event": "message_send_starting", "properties": {}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746667540} +{"event": "message_send", "properties": {"main_model": "gemini/gemini-2.5-pro-exp-03-25", "weak_model": "gemini/gemini-2.0-flash", "editor_model": "gemini/gemini-2.5-pro-exp-03-25", "edit_format": "udiff-simple", "prompt_tokens": 23450, "completion_tokens": 234, "total_tokens": 23684, "cost": 0, "total_cost": 0.0}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746667620} +{"event": "exit", "properties": {"reason": "Completed --message"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1746667620} diff --git a/aider/website/docs/config/adv-model-settings.md b/aider/website/docs/config/adv-model-settings.md index e9301d5b5..6d91b6922 100644 --- a/aider/website/docs/config/adv-model-settings.md +++ b/aider/website/docs/config/adv-model-settings.md @@ -694,7 +694,7 @@ cog.out("```\n") - name: gemini/gemini-2.5-pro-preview-05-06 edit_format: diff-fenced - weak_model_name: gemini/gemini-2.0-flash + weak_model_name: gemini/gemini-2.5-flash-preview-04-17 use_repo_map: true overeager: true diff --git a/aider/website/docs/faq.md b/aider/website/docs/faq.md index 6a9d144f9..39c132394 100644 --- a/aider/website/docs/faq.md +++ b/aider/website/docs/faq.md @@ -264,13 +264,12 @@ tr:hover { background-color: #f5f5f5; }
Model NameTotal TokensPercent
gemini/gemini-2.5-pro-exp-03-251,283,25866.4%
gemini/gemini-2.5-pro-preview-03-25442,01922.9%
o3138,8427.2%
gemini/gemini-2.5-pro-exp-03-251,332,23167.3%
gemini/gemini-2.5-pro-preview-03-25442,01922.3%
o3138,8427.0%
openrouter/anthropic/claude-3.7-sonnet41,0172.1%
gemini/gemini-2.5-flash-preview-04-1710,3050.5%
gemini/gemini-2.5-pro-preview-05-068,5760.4%
- - - + + + - + -
Model NameTotal TokensPercent
gemini/gemini-2.5-pro-exp-03-251,332,23167.3%
gemini/gemini-2.5-pro-preview-03-25442,01922.3%
o3138,8427.0%
gemini/gemini-2.5-pro-exp-03-251,269,23966.2%
gemini/gemini-2.5-pro-preview-03-25442,01923.1%
o3138,8427.2%
openrouter/anthropic/claude-3.7-sonnet41,0172.1%
gemini/gemini-2.5-flash-preview-04-1710,3050.5%
openrouter/REDACTED15,5870.8%
gemini/gemini-2.5-pro-preview-05-068,5760.4%
openrouter/REDACTED5,5370.3%
gemini/REDACTED1,9890.1%
From 03acee1ed271150fda006050a6e2af6d601d36d3 Mon Sep 17 00:00:00 2001 From: Paul Gauthier Date: Wed, 7 May 2025 19:19:21 -0700 Subject: [PATCH 85/85] copy --- aider/website/_posts/2025-05-07-gemini-cost.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aider/website/_posts/2025-05-07-gemini-cost.md b/aider/website/_posts/2025-05-07-gemini-cost.md index c54c18e05..fdadee5ed 100644 --- a/aider/website/_posts/2025-05-07-gemini-cost.md +++ b/aider/website/_posts/2025-05-07-gemini-cost.md @@ -41,7 +41,7 @@ completed the benchmark at a cost of about $37. ## Investigation detail -The version of litellm available at that time appears to have been +The version of litellm available at that time of the benchmark appears to have been excluding reasoning tokens from the token counts it reported. So even though aider had correct per-token pricing, it did not have the correct token counts used during the benchmark.