diff --git a/.github/workflows/close-stale.yml b/.github/workflows/close-stale.yml deleted file mode 100644 index aee25446c..000000000 --- a/.github/workflows/close-stale.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: 'Close stale issues and PRs' -on: - schedule: - - cron: '30 1 * * *' - workflow_dispatch: - -permissions: - issues: write - -jobs: - stale: - runs-on: ubuntu-latest - steps: - - uses: actions/stale@v9 - with: - stale-issue-message: 'This issue has been labelled stale because it has been open for 2 weeks with no activity. Remove stale label or add a comment to keep this issue open. Otherwise, it will be closed in 7 days.' - close-issue-message: 'This issue was closed because it has been stalled for 3 weeks with no activity. Feel free to add a comment here and we can re-open it. Or feel free to file a new issue any time.' - days-before-stale: 14 - days-before-close: 7 - stale-issue-label: 'stale' - stale-pr-label: 'stale' - only-labels: 'question' - days-before-pr-stale: -1 - days-before-pr-close: -1 diff --git a/aider/coders/architect_prompts.py b/aider/coders/architect_prompts.py index e6798dbba..2ac23f5fc 100644 --- a/aider/coders/architect_prompts.py +++ b/aider/coders/architect_prompts.py @@ -13,7 +13,7 @@ Just show the changes needed. DO NOT show the entire updated function/file/etc! -Always reply in the same language as the change request. +Always reply to the user in {language}. """ example_messages = [] diff --git a/aider/coders/ask_prompts.py b/aider/coders/ask_prompts.py index 7e1da106a..198ec6172 100644 --- a/aider/coders/ask_prompts.py +++ b/aider/coders/ask_prompts.py @@ -6,7 +6,7 @@ from .base_prompts import CoderPrompts class AskPrompts(CoderPrompts): main_system = """Act as an expert code analyst. Answer questions about the supplied code. -Always reply to the user in the same language they are using. +Always reply to the user in {language}. """ example_messages = [] diff --git a/aider/coders/base_coder.py b/aider/coders/base_coder.py index 2f42adfd6..164010140 100755 --- a/aider/coders/base_coder.py +++ b/aider/coders/base_coder.py @@ -820,7 +820,7 @@ class Coder: "Add URL to the chat?", subject=url, group=group, allow_never=True ): inp += "\n\n" - inp += self.commands.cmd_web(url) + inp += self.commands.cmd_web(url, return_content=True) added_urls.append(url) else: self.rejected_urls.add(url) @@ -956,12 +956,18 @@ class Coder: platform=platform_text ) + if self.chat_language: + language = self.chat_language + else: + language = "in the same language they are using" + prompt = prompt.format( fence=self.fence, lazy_prompt=lazy_prompt, platform=platform_text, shell_cmd_prompt=shell_cmd_prompt, shell_cmd_reminder=shell_cmd_reminder, + language=language, ) return prompt diff --git a/aider/coders/editblock_prompts.py b/aider/coders/editblock_prompts.py index 05d2a3de3..da2acdf95 100644 --- a/aider/coders/editblock_prompts.py +++ b/aider/coders/editblock_prompts.py @@ -11,7 +11,7 @@ Respect and use existing conventions, libraries, etc that are already present in Take requests for changes to the supplied code. If the request is ambiguous, ask questions. -Always reply to the user in the same language they are using. +Always reply to the user in {language}. Once you understand the request you MUST: diff --git a/aider/coders/udiff_prompts.py b/aider/coders/udiff_prompts.py index 8084f885c..5e7ca2c13 100644 --- a/aider/coders/udiff_prompts.py +++ b/aider/coders/udiff_prompts.py @@ -12,7 +12,7 @@ Respect and use existing conventions, libraries, etc that are already present in Take requests for changes to the supplied code. If the request is ambiguous, ask questions. -Always reply to the user in the same language they are using. +Always reply to the user in {language}. For each file that needs to be changed, write out the changes similar to a unified diff like `diff -U0` would produce. """ diff --git a/aider/coders/wholefile_prompts.py b/aider/coders/wholefile_prompts.py index 615645f69..95a4bb87b 100644 --- a/aider/coders/wholefile_prompts.py +++ b/aider/coders/wholefile_prompts.py @@ -8,7 +8,7 @@ class WholeFilePrompts(CoderPrompts): Take requests for changes to the supplied code. If the request is ambiguous, ask questions. -Always reply to the user in the same language they are using. +Always reply to the user in {language}. {lazy_prompt} Once you understand the request you MUST: diff --git a/aider/commands.py b/aider/commands.py index 45d19c1b8..91d0ea7c3 100644 --- a/aider/commands.py +++ b/aider/commands.py @@ -139,7 +139,7 @@ class Commands: else: self.io.tool_output("Please provide a partial model name to search for.") - def cmd_web(self, args): + def cmd_web(self, args, return_content=False): "Scrape a webpage, convert to markdown and send in a message" url = args.strip() @@ -158,11 +158,16 @@ class Commands: ) content = self.scraper.scrape(url) or "" - content = f"{url}:\n\n" + content + content = f"Here is the content of {url}:\n\n" + content + if return_content: + return content - self.io.tool_output("... done.") + self.io.tool_output("... added to chat.") - return content + self.coder.cur_messages += [ + dict(role="user", content=content), + dict(role="assistant", content="Ok."), + ] def is_command(self, inp): return inp[0] in "/!" diff --git a/aider/main.py b/aider/main.py index 179d4560f..a604c5f64 100644 --- a/aider/main.py +++ b/aider/main.py @@ -87,15 +87,25 @@ def make_new_repo(git_root, io): def setup_git(git_root, io): + try: + cwd = Path.cwd() + except OSError: + cwd = None + repo = None if git_root: - repo = git.Repo(git_root) - elif Path.cwd() == Path.home(): + try: + repo = git.Repo(git_root) + except ANY_GIT_ERROR: + pass + elif cwd == Path.home(): io.tool_warning("You should probably run aider in a directory, not your home dir.") return - elif io.confirm_ask("No git repo found, create one to track aider's changes (recommended)?"): - git_root = str(Path.cwd().resolve()) + elif cwd and io.confirm_ask( + "No git repo found, create one to track aider's changes (recommended)?" + ): + git_root = str(cwd.resolve()) repo = make_new_repo(git_root, io) if not repo: diff --git a/aider/sendchat.py b/aider/sendchat.py index e4b8bd7bf..3d1224bc6 100644 --- a/aider/sendchat.py +++ b/aider/sendchat.py @@ -71,6 +71,8 @@ def simple_send_with_retries(model_name, messages, extra_params=None): } _hash, response = send_completion(**kwargs) + if not response or not hasattr(response, "choices") or not response.choices: + return None return response.choices[0].message.content except litellm_ex.exceptions_tuple() as err: ex_info = litellm_ex.get_ex_info(err) @@ -86,10 +88,10 @@ def simple_send_with_retries(model_name, messages, extra_params=None): should_retry = False if not should_retry: - break + return None print(f"Retrying in {retry_delay:.1f} seconds...") time.sleep(retry_delay) continue except AttributeError: - return + return None diff --git a/aider/website/_data/edit_leaderboard.yml b/aider/website/_data/edit_leaderboard.yml index 09d84630c..24a126e3d 100644 --- a/aider/website/_data/edit_leaderboard.yml +++ b/aider/website/_data/edit_leaderboard.yml @@ -1657,3 +1657,164 @@ versions: 0.59.2.dev seconds_per_case: 18.2 total_cost: 0.0000 + +- dirname: 2024-10-29-00-29-09--Qwen2.5-Coder-0.5B-Instruct + test_cases: 133 + model: Qwen2.5-Coder-0.5B-Instruct + edit_format: whole + commit_hash: 58bd375 + pass_rate_1: 14.3 + pass_rate_2: 14.3 + percent_cases_well_formed: 100.0 + error_outputs: 20 + num_malformed_responses: 0 + num_with_malformed_responses: 0 + user_asks: 45 + lazy_comments: 0 + syntax_errors: 2 + indentation_errors: 0 + exhausted_context_windows: 20 + test_timeouts: 2 + command: aider --model openai/Qwen2.5-Coder-0.5B-Instruct + date: 2024-10-29 + versions: 0.59.2.dev + seconds_per_case: 16.0 + total_cost: 0.0000 + +- dirname: 2024-11-11-19-37-01--Qwen2.5-Coder-1.5B-Instruct + test_cases: 133 + model: Qwen2.5-Coder-1.5B-Instruct + edit_format: whole + commit_hash: bb5681c + pass_rate_1: 28.6 + pass_rate_2: 31.6 + percent_cases_well_formed: 100.0 + error_outputs: 5 + num_malformed_responses: 0 + num_with_malformed_responses: 0 + user_asks: 13 + lazy_comments: 2 + syntax_errors: 1 + indentation_errors: 0 + exhausted_context_windows: 5 + test_timeouts: 2 + command: aider --model openai/Qwen2.5-Coder-1.5B-Instruct + date: 2024-11-11 + versions: 0.59.2.dev + seconds_per_case: 27.4 + total_cost: 0.0000 + +- dirname: 2024-11-04-02-25-32--Qwen2.5-Coder-3B-Instruct + test_cases: 133 + model: Qwen2.5-Coder-3B-Instruct + edit_format: whole + commit_hash: 0ba3647 + pass_rate_1: 33.8 + pass_rate_2: 39.1 + percent_cases_well_formed: 100.0 + error_outputs: 4 + num_malformed_responses: 0 + num_with_malformed_responses: 0 + user_asks: 3 + lazy_comments: 0 + syntax_errors: 0 + indentation_errors: 0 + exhausted_context_windows: 4 + test_timeouts: 6 + command: aider --model openai/Qwen2.5-Coder-3B-Instruct + date: 2024-11-04 + versions: 0.59.2.dev + seconds_per_case: 18.7 + total_cost: 0.0000 + +- dirname: 2024-10-16-16-20-59--Qwen2.5-Coder-7B-Instruct + test_cases: 133 + model: Qwen2.5-Coder-7B-Instruct + edit_format: whole + commit_hash: 92fe979-dirty + pass_rate_1: 51.9 + pass_rate_2: 57.9 + percent_cases_well_formed: 100.0 + error_outputs: 2 + num_malformed_responses: 0 + num_with_malformed_responses: 0 + user_asks: 2 + lazy_comments: 0 + syntax_errors: 0 + indentation_errors: 0 + exhausted_context_windows: 2 + test_timeouts: 5 + command: aider --model openai/Qwen2.5-Coder-7B-Instruct + date: 2024-10-16 + versions: 0.59.2.dev + seconds_per_case: 10.5 + total_cost: 0.0000 + +- dirname: 2024-10-29-11-53-39--Qwen2.5-Coder-14B-Instruct + test_cases: 133 + model: Qwen2.5-Coder-14B-Instruct + edit_format: whole + commit_hash: 58bd375 + pass_rate_1: 58.6 + pass_rate_2: 69.2 + percent_cases_well_formed: 100.0 + error_outputs: 3 + num_malformed_responses: 0 + num_with_malformed_responses: 0 + user_asks: 2 + lazy_comments: 0 + syntax_errors: 0 + indentation_errors: 0 + exhausted_context_windows: 3 + test_timeouts: 0 + command: aider --model openai/Qwen2.5-Coder-14B-Instruct + date: 2024-10-29 + versions: 0.59.2.dev + seconds_per_case: 18.3 + total_cost: 0.0000 + +- dirname: 2024-11-09-10-57-11--Qwen2.5-Coder-32B-Instruct + test_cases: 133 + model: Qwen2.5-Coder-32B-Instruct (whole) + edit_format: whole + commit_hash: ec9982a + pass_rate_1: 60.9 + pass_rate_2: 73.7 + percent_cases_well_formed: 100.0 + error_outputs: 1 + num_malformed_responses: 0 + num_with_malformed_responses: 0 + user_asks: 1 + lazy_comments: 0 + syntax_errors: 0 + indentation_errors: 0 + exhausted_context_windows: 1 + test_timeouts: 1 + command: aider --model openai/Qwen2.5-Coder-32B-Instruct + date: 2024-11-09 + versions: 0.59.2.dev + seconds_per_case: 26.6 + total_cost: 0.0000 + +- dirname: 2024-11-09-11-09-15--Qwen2.5-Coder-32B-Instruct + test_cases: 133 + model: Qwen2.5-Coder-32B-Instruct (diff) + edit_format: diff + commit_hash: ec9982a + pass_rate_1: 59.4 + pass_rate_2: 71.4 + percent_cases_well_formed: 94.7 + error_outputs: 17 + num_malformed_responses: 17 + num_with_malformed_responses: 7 + user_asks: 1 + lazy_comments: 0 + syntax_errors: 0 + indentation_errors: 0 + exhausted_context_windows: 0 + test_timeouts: 3 + command: aider --model openai/Qwen2.5-Coder-32B-Instruct + date: 2024-11-09 + versions: 0.59.2.dev + seconds_per_case: 22.5 + total_cost: 0.0000 diff --git a/aider/website/assets/sample-analytics.jsonl b/aider/website/assets/sample-analytics.jsonl index cf09949b6..a8e85f623 100644 --- a/aider/website/assets/sample-analytics.jsonl +++ b/aider/website/assets/sample-analytics.jsonl @@ -618,3 +618,132 @@ {"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731008891} {"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731008957} {"event": "gui session", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731008958} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731009346} +{"event": "gui session", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731009347} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731009380} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731009498} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731009531} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "diff", "prompt_tokens": 5022, "completion_tokens": 98, "total_tokens": 5120, "cost": 0.016536, "total_cost": 0.016536, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731009544} +{"event": "command_reset", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.1.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731009984} +{"event": "command_add", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.1.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731010753} +{"event": "command_add", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.1.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731010767} +{"event": "command_add", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.1.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731010772} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-sonnet-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "diff", "prompt_tokens": 3609, "completion_tokens": 66, "total_tokens": 3675, "cost": 0.011817, "total_cost": 0.531435, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.1.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731010780} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-sonnet-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "diff", "prompt_tokens": 3798, "completion_tokens": 58, "total_tokens": 3856, "cost": 0.012263999999999999, "total_cost": 0.543699, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.1.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731010783} +{"event": "command_map-refresh", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.1.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731012301} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-sonnet-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "diff", "prompt_tokens": 4349, "completion_tokens": 215, "total_tokens": 4564, "cost": 0.016272, "total_cost": 0.559971, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.1.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731012326} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731012382} +{"event": "model warning", "properties": {"main_model": "claude-3-5-haiku-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-haiku-20241022", "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731012382} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731012391} +{"event": "cli session", "properties": {"main_model": "claude-3-5-haiku-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-haiku-20241022", "edit_format": "diff", "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731012392} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731012437} +{"event": "cli session", "properties": {"main_model": "claude-3-5-haiku-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-haiku-20241022", "edit_format": "diff", "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731012437} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731012462} +{"event": "cli session", "properties": {"main_model": "claude-3-5-haiku-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-haiku-20241022", "edit_format": "diff", "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731012462} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731012492} +{"event": "cli session", "properties": {"main_model": "claude-3-5-haiku-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-haiku-20241022", "edit_format": "diff", "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731012493} +{"event": "message_send", "properties": {"main_model": "claude-3-5-haiku-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-haiku-20241022", "edit_format": "diff", "prompt_tokens": 2175, "completion_tokens": 0, "total_tokens": 2175, "cost": 0.002175, "total_cost": 0.002175, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731012494} +{"event": "command_exit", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731012809} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731013317} +{"event": "message_send", "properties": {"main_model": "gpt-4o-2024-08-06", "weak_model": "gpt-4o-mini", "editor_model": "gpt-4o-2024-08-06", "edit_format": "diff", "prompt_tokens": 4072, "completion_tokens": 67, "total_tokens": 4139, "cost": 0.010850000000000002, "total_cost": 0.010850000000000002, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731013327} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731013779} +{"event": "message_send", "properties": {"main_model": "gpt-4o-2024-08-06", "weak_model": "gpt-4o-mini", "editor_model": "gpt-4o-2024-08-06", "edit_format": "diff", "prompt_tokens": 3821, "completion_tokens": 66, "total_tokens": 3887, "cost": 0.010212500000000001, "total_cost": 0.010212500000000001, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731013789} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731013943} +{"event": "gui session", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731013943} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731014543} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731015697} +{"event": "cli session", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "diff", "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731015699} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731016873} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "str-replace", "prompt_tokens": 1321, "completion_tokens": 57, "total_tokens": 1378, "cost": 0.004818, "total_cost": 0.004818, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731016881} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731016895} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731016946} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "str-replace", "prompt_tokens": 1321, "completion_tokens": 37, "total_tokens": 1358, "cost": 0.004518, "total_cost": 0.004518, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731016952} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731017159} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "str-replace", "prompt_tokens": 1321, "completion_tokens": 37, "total_tokens": 1358, "cost": 0.004518, "total_cost": 0.004518, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731017166} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731017260} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "str-replace", "prompt_tokens": 1321, "completion_tokens": 43, "total_tokens": 1364, "cost": 0.004608, "total_cost": 0.004608, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731017267} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731017271} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "str-replace", "prompt_tokens": 1321, "completion_tokens": 43, "total_tokens": 1364, "cost": 0.004608, "total_cost": 0.004608, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731017277} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731017283} +{"event": "message_send", "properties": {"main_model": "claude-3-5-haiku-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-haiku-20241022", "edit_format": "str-replace", "prompt_tokens": 1321, "completion_tokens": 0, "total_tokens": 1321, "cost": 0.001321, "total_cost": 0.001321, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731017285} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731017353} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "str-replace", "prompt_tokens": 5656, "completion_tokens": 230, "total_tokens": 5886, "cost": 0.0128013, "total_cost": 0.0128013, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731017361} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731017673} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "str-replace", "prompt_tokens": 5656, "completion_tokens": 225, "total_tokens": 5881, "cost": 0.02245875, "total_cost": 0.02245875, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731017680} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731017723} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "str-replace", "prompt_tokens": 5656, "completion_tokens": 225, "total_tokens": 5881, "cost": 0.0127263, "total_cost": 0.0127263, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731017730} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731017923} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "str-replace", "prompt_tokens": 2823, "completion_tokens": 291, "total_tokens": 3114, "cost": 0.010166399999999999, "total_cost": 0.010166399999999999, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731017931} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731017952} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "str-replace", "prompt_tokens": 2823, "completion_tokens": 133, "total_tokens": 2956, "cost": 0.006678600000000001, "total_cost": 0.006678600000000001, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731017956} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731018026} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "str-replace", "prompt_tokens": 2841, "completion_tokens": 305, "total_tokens": 3146, "cost": 0.0093126, "total_cost": 0.0093126, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731018033} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731018386} +{"event": "message_send", "properties": {"main_model": "claude-3-5-haiku-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-haiku-20241022", "edit_format": "str-replace", "prompt_tokens": 195, "completion_tokens": 0, "total_tokens": 195, "cost": 0.000195, "total_cost": 0.000195, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731018388} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731018393} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "str-replace", "prompt_tokens": 2758, "completion_tokens": 291, "total_tokens": 3049, "cost": 0.013668, "total_cost": 0.013668, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731018400} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731018544} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "str-replace", "prompt_tokens": 2758, "completion_tokens": 291, "total_tokens": 3049, "cost": 0.008934600000000001, "total_cost": 0.008934600000000001, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731018551} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731019468} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "str-replace", "prompt_tokens": 5219, "completion_tokens": 326, "total_tokens": 5545, "cost": 0.022496999999999996, "total_cost": 0.022496999999999996, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731019478} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "str-replace", "prompt_tokens": 5255, "completion_tokens": 342, "total_tokens": 5597, "cost": 0.013874999999999998, "total_cost": 0.036371999999999995, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731019484} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "str-replace", "prompt_tokens": 5292, "completion_tokens": 227, "total_tokens": 5519, "cost": 0.012261, "total_cost": 0.048632999999999996, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731019489} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "str-replace", "prompt_tokens": 5324, "completion_tokens": 249, "total_tokens": 5573, "cost": 0.012687, "total_cost": 0.06132, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731019494} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731023558} +{"event": "cli session", "properties": {"main_model": "openrouter/anthropic/claude-3.5-sonnet", "weak_model": "openrouter/anthropic/claude-3-5-haiku", "editor_model": "openrouter/anthropic/claude-3.5-sonnet", "edit_format": "diff", "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731023560} +{"event": "message_send", "properties": {"main_model": "openrouter/anthropic/claude-3.5-sonnet", "weak_model": "openrouter/anthropic/claude-3-5-haiku", "editor_model": "openrouter/anthropic/claude-3.5-sonnet", "edit_format": "diff", "prompt_tokens": 4643, "completion_tokens": 89, "total_tokens": 4732, "cost": 0.015264, "total_cost": 0.015264, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731023566} +{"event": "command_exit", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731023568} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731085730} +{"event": "cli session", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "diff", "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731085733} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "diff", "prompt_tokens": 5276, "completion_tokens": 829, "total_tokens": 6105, "cost": 0.028263000000000003, "total_cost": 0.028263000000000003, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731085876} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "diff", "prompt_tokens": 7737, "completion_tokens": 165, "total_tokens": 7902, "cost": 0.025686, "total_cost": 0.053949000000000004, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731085899} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "diff", "prompt_tokens": 6410, "completion_tokens": 132, "total_tokens": 6542, "cost": 0.02121, "total_cost": 0.075159, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731086273} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "diff", "prompt_tokens": 6596, "completion_tokens": 307, "total_tokens": 6903, "cost": 0.024392999999999998, "total_cost": 0.099552, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731086706} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "diff", "prompt_tokens": 7053, "completion_tokens": 1311, "total_tokens": 8364, "cost": 0.040824, "total_cost": 0.140376, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731088533} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "diff", "prompt_tokens": 8504, "completion_tokens": 124, "total_tokens": 8628, "cost": 0.027372, "total_cost": 0.167748, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731088557} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "diff", "prompt_tokens": 7215, "completion_tokens": 127, "total_tokens": 7342, "cost": 0.02355, "total_cost": 0.19129800000000002, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731088573} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731088724} +{"event": "cli session", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "diff", "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731088726} +{"event": "command_add", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731088734} +{"event": "command_add", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731088742} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731088755} +{"event": "gui session", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731088756} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "diff", "prompt_tokens": 3938, "completion_tokens": 561, "total_tokens": 4499, "cost": 0.020229, "total_cost": 0.020229, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731088762} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "diff", "prompt_tokens": 5665, "completion_tokens": 81, "total_tokens": 5746, "cost": 0.01821, "total_cost": 0.038439, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731088779} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "diff", "prompt_tokens": 5869, "completion_tokens": 78, "total_tokens": 5947, "cost": 0.018777000000000002, "total_cost": 0.057216, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731088782} +{"event": "command_ask", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731088807} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "ask", "prompt_tokens": 5235, "completion_tokens": 281, "total_tokens": 5516, "cost": 0.01992, "total_cost": 0.07713600000000001, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731088814} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "diff", "prompt_tokens": 7656, "completion_tokens": 199, "total_tokens": 7855, "cost": 0.025953000000000004, "total_cost": 0.10308900000000001, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731088825} +{"event": "command_reset", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731088844} +{"event": "command_add", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731088849} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "diff", "prompt_tokens": 6170, "completion_tokens": 760, "total_tokens": 6930, "cost": 0.029910000000000003, "total_cost": 0.132999, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731088870} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "diff", "prompt_tokens": 6564, "completion_tokens": 126, "total_tokens": 6690, "cost": 0.021582, "total_cost": 0.154581, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731088903} +{"event": "command_ask", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731088927} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "ask", "prompt_tokens": 6794, "completion_tokens": 513, "total_tokens": 7307, "cost": 0.028077, "total_cost": 0.182658, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731088940} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "diff", "prompt_tokens": 9518, "completion_tokens": 211, "total_tokens": 9729, "cost": 0.031719, "total_cost": 0.21437699999999998, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731088965} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "diff", "prompt_tokens": 8247, "completion_tokens": 232, "total_tokens": 8479, "cost": 0.028221, "total_cost": 0.24259799999999998, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731089026} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731104297} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731104362} +{"event": "gui session", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731104363} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731104481} +{"event": "cli session", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "diff", "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731104484} +{"event": "command_add", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731104486} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "diff", "prompt_tokens": 13609, "completion_tokens": 193, "total_tokens": 13802, "cost": 0.043722000000000004, "total_cost": 0.043722000000000004, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731104517} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731104571} +{"event": "cli session", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "diff", "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731104573} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731104579} +{"event": "cli session", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "diff", "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731104580} +{"event": "command_web", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731104586} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "diff", "prompt_tokens": 5465, "completion_tokens": 84, "total_tokens": 5549, "cost": 0.017655, "total_cost": 0.017655, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731104600} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731104626} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731104710} +{"event": "gui session", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731104711} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731104870} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731104934} +{"event": "gui session", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731104934} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731113790} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731115722} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "str-replace", "prompt_tokens": 15622, "completion_tokens": 22, "total_tokens": 15644, "cost": 0.047195999999999995, "total_cost": 0.047195999999999995, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731115754} +{"event": "message_send", "properties": {"main_model": "claude-3-5-sonnet-20241022", "weak_model": "claude-3-5-haiku-20241022", "editor_model": "claude-3-5-sonnet-20241022", "edit_format": "str-replace", "prompt_tokens": 2506, "completion_tokens": 40, "total_tokens": 2546, "cost": 0.008118, "total_cost": 0.055313999999999995, "python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731116109} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731163157} +{"event": "launched", "properties": {"python_version": "3.12.6", "os_platform": "Darwin", "os_release": "23.6.0", "machine": "x86_64", "aider_version": "0.62.2.dev"}, "user_id": "c42c4e6b-f054-44d7-ae1f-6726cc41da88", "time": 1731163182} diff --git a/aider/website/docs/leaderboards/index.md b/aider/website/docs/leaderboards/index.md index 7563bec64..c79047551 100644 --- a/aider/website/docs/leaderboards/index.md +++ b/aider/website/docs/leaderboards/index.md @@ -318,6 +318,6 @@ mod_dates = [get_last_modified_date(file) for file in files] latest_mod_date = max(mod_dates) cog.out(f"{latest_mod_date.strftime('%B %d, %Y.')}") ]]]--> -November 07, 2024. +November 11, 2024.

diff --git a/aider/website/docs/more/infinite-output.md b/aider/website/docs/more/infinite-output.md index b9aada615..f590d0791 100644 --- a/aider/website/docs/more/infinite-output.md +++ b/aider/website/docs/more/infinite-output.md @@ -55,6 +55,7 @@ model_list = "\n".join(f"- {model}" for model in sorted(prefill_models)) cog.out(model_list) ]]]--> +- anthropic.claude-3-5-haiku-20241022-v1:0 - anthropic.claude-3-5-sonnet-20241022-v2:0 - anthropic/claude-3-5-sonnet-20241022 - claude-3-5-haiku-20241022 @@ -88,6 +89,7 @@ cog.out(model_list) - mistral/open-mixtral-8x7b - mistral/pixtral-12b-2409 - openrouter/anthropic/claude-3.5-sonnet +- us.anthropic.claude-3-5-haiku-20241022-v1:0 - us.anthropic.claude-3-5-sonnet-20241022-v2:0 - vertex_ai/claude-3-5-haiku@20241022 - vertex_ai/claude-3-5-sonnet-v2@20241022 diff --git a/scripts/issues.py b/scripts/issues.py index f41e53baa..70ded8caf 100755 --- a/scripts/issues.py +++ b/scripts/issues.py @@ -28,6 +28,10 @@ This looks like a duplicate of #{oldest_issue_number}. Please see the comments t I'm going to close this issue for now. But please let me know if you think this is actually a distinct issue and I will reopen this issue.""" # noqa +STALE_COMMENT = """I'm labeling this issue as stale because it has been open for 2 weeks with no activity. If there are no additional comments, it will be closed in 7 days.""" # noqa + +CLOSE_STALE_COMMENT = """I'm closing this issue because it has been stalled for 3 weeks with no activity. Feel free to add a comment here and we can re-open it. Or feel free to file a new issue at any time.""" # noqa + # GitHub API configuration GITHUB_API_URL = "https://api.github.com" REPO_OWNER = "Aider-AI" @@ -160,11 +164,139 @@ def handle_unlabeled_issues(all_issues, auto_yes): print(f" - Added 'question' label to #{issue['number']}") +def handle_stale_issues(all_issues, auto_yes): + print("\nChecking for stale question issues...") + + for issue in all_issues: + # Skip if not open, not a question, already stale, or has been reopened + if ( + issue["state"] != "open" + or "question" not in [label["name"] for label in issue["labels"]] + or "stale" in [label["name"] for label in issue["labels"]] + or has_been_reopened(issue["number"]) + ): + continue + + # Get latest activity timestamp from issue or its comments + latest_activity = datetime.strptime(issue["updated_at"], "%Y-%m-%dT%H:%M:%SZ") + + # Check if issue is stale (no activity for 14 days) + days_inactive = (datetime.now() - latest_activity).days + if days_inactive >= 14: + print(f"\nStale issue found: #{issue['number']}: {issue['title']}\n{issue['html_url']}") + print(f" No activity for {days_inactive} days") + + if not auto_yes: + confirm = input("Add stale label and comment? (y/n): ") + if confirm.lower() != "y": + print("Skipping this issue.") + continue + + # Add comment + comment_url = ( + f"{GITHUB_API_URL}/repos/{REPO_OWNER}/{REPO_NAME}/issues/{issue['number']}/comments" + ) + response = requests.post(comment_url, headers=headers, json={"body": STALE_COMMENT}) + response.raise_for_status() + + # Add stale label + url = f"{GITHUB_API_URL}/repos/{REPO_OWNER}/{REPO_NAME}/issues/{issue['number']}" + response = requests.patch(url, headers=headers, json={"labels": ["question", "stale"]}) + response.raise_for_status() + + print(f" Added stale label and comment to #{issue['number']}") + + +def handle_stale_closing(all_issues, auto_yes): + print("\nChecking for issues to close or unstale...") + + for issue in all_issues: + # Skip if not open or not stale + if issue["state"] != "open" or "stale" not in [label["name"] for label in issue["labels"]]: + continue + + # Get the timeline to find when the stale label was last added + timeline_url = ( + f"{GITHUB_API_URL}/repos/{REPO_OWNER}/{REPO_NAME}/issues/{issue['number']}/timeline" + ) + response = requests.get(timeline_url, headers=headers) + response.raise_for_status() + events = response.json() + + # Find the most recent stale label addition + stale_events = [ + event + for event in events + if event.get("event") == "labeled" and event.get("label", {}).get("name") == "stale" + ] + + if not stale_events: + continue + + latest_stale = datetime.strptime(stale_events[-1]["created_at"], "%Y-%m-%dT%H:%M:%SZ") + + # Get comments since the stale label + comments_url = ( + f"{GITHUB_API_URL}/repos/{REPO_OWNER}/{REPO_NAME}/issues/{issue['number']}/comments" + ) + response = requests.get(comments_url, headers=headers) + response.raise_for_status() + comments = response.json() + + # Check for comments newer than the stale label + new_comments = [ + comment + for comment in comments + if datetime.strptime(comment["created_at"], "%Y-%m-%dT%H:%M:%SZ") > latest_stale + ] + + if new_comments: + print(f"\nFound new activity on stale issue #{issue['number']}: {issue['title']}") + print(f" {len(new_comments)} new comments since stale label") + + if not auto_yes: + confirm = input("Remove stale label? (y/n): ") + if confirm.lower() != "y": + print("Skipping this issue.") + continue + + # Remove stale label but keep question label + url = f"{GITHUB_API_URL}/repos/{REPO_OWNER}/{REPO_NAME}/issues/{issue['number']}" + response = requests.patch(url, headers=headers, json={"labels": ["question"]}) + response.raise_for_status() + print(f" Removed stale label from #{issue['number']}") + else: + # Check if it's been 7 days since stale label + days_stale = (datetime.now() - latest_stale).days + if days_stale >= 7: + print(f"\nStale issue ready for closing #{issue['number']}: {issue['title']}") + print(f" No activity for {days_stale} days since stale label") + + if not auto_yes: + confirm = input("Close this issue? (y/n): ") + if confirm.lower() != "y": + print("Skipping this issue.") + continue + + # Add closing comment + comment_url = f"{GITHUB_API_URL}/repos/{REPO_OWNER}/{REPO_NAME}/issues/{issue['number']}/comments" + response = requests.post( + comment_url, headers=headers, json={"body": CLOSE_STALE_COMMENT} + ) + response.raise_for_status() + + # Close the issue + url = f"{GITHUB_API_URL}/repos/{REPO_OWNER}/{REPO_NAME}/issues/{issue['number']}" + response = requests.patch(url, headers=headers, json={"state": "closed"}) + response.raise_for_status() + print(f" Closed issue #{issue['number']}") + + def handle_duplicate_issues(all_issues, auto_yes): open_issues = [issue for issue in all_issues if issue["state"] == "open"] grouped_open_issues = group_issues_by_subject(open_issues) - print("Analyzing issues (skipping reopened issues)...") + print("Looking for duplicate issues (skipping reopened issues)...") for subject, issues in grouped_open_issues.items(): oldest_issue = find_oldest_issue(subject, all_issues) if not oldest_issue: @@ -214,6 +346,8 @@ def main(): all_issues = get_issues("all") handle_unlabeled_issues(all_issues, args.yes) + handle_stale_issues(all_issues, args.yes) + handle_stale_closing(all_issues, args.yes) handle_duplicate_issues(all_issues, args.yes) diff --git a/tests/basic/test_exceptions.py b/tests/basic/test_exceptions.py new file mode 100644 index 000000000..f9262a665 --- /dev/null +++ b/tests/basic/test_exceptions.py @@ -0,0 +1,65 @@ +from aider.exceptions import ExInfo, LiteLLMExceptions + + +def test_litellm_exceptions_load(): + """Test that LiteLLMExceptions loads without errors""" + ex = LiteLLMExceptions() + assert len(ex.exceptions) > 0 + + +def test_exceptions_tuple(): + """Test that exceptions_tuple returns a non-empty tuple""" + ex = LiteLLMExceptions() + assert isinstance(ex.exceptions_tuple(), tuple) + assert len(ex.exceptions_tuple()) > 0 + + +def test_get_ex_info(): + """Test get_ex_info returns correct ExInfo""" + ex = LiteLLMExceptions() + + # Test with a known exception type + from litellm import AuthenticationError + + auth_error = AuthenticationError( + message="Invalid API key", llm_provider="openai", model="gpt-4" + ) + ex_info = ex.get_ex_info(auth_error) + assert isinstance(ex_info, ExInfo) + assert ex_info.name == "AuthenticationError" + assert ex_info.retry is False + assert "API key" in ex_info.description + + # Test with unknown exception type + class UnknownError(Exception): + pass + + unknown = UnknownError() + ex_info = ex.get_ex_info(unknown) + assert isinstance(ex_info, ExInfo) + assert ex_info.name is None + assert ex_info.retry is None + assert ex_info.description is None + + +def test_rate_limit_error(): + """Test specific handling of RateLimitError""" + ex = LiteLLMExceptions() + from litellm import RateLimitError + + rate_error = RateLimitError(message="Rate limit exceeded", llm_provider="openai", model="gpt-4") + ex_info = ex.get_ex_info(rate_error) + assert ex_info.retry is True + assert "rate limited" in ex_info.description.lower() + + +def test_context_window_error(): + """Test specific handling of ContextWindowExceededError""" + ex = LiteLLMExceptions() + from litellm import ContextWindowExceededError + + ctx_error = ContextWindowExceededError( + message="Context length exceeded", model="gpt-4", llm_provider="openai" + ) + ex_info = ex.get_ex_info(ctx_error) + assert ex_info.retry is False diff --git a/tests/basic/test_sendchat.py b/tests/basic/test_sendchat.py index 28397e5c8..6b2684a40 100644 --- a/tests/basic/test_sendchat.py +++ b/tests/basic/test_sendchat.py @@ -3,7 +3,7 @@ from unittest.mock import MagicMock, patch from aider.exceptions import LiteLLMExceptions from aider.llm import litellm -from aider.sendchat import simple_send_with_retries +from aider.sendchat import send_completion, simple_send_with_retries class PrintCalled(Exception): @@ -11,6 +11,10 @@ class PrintCalled(Exception): class TestSendChat(unittest.TestCase): + def setUp(self): + self.mock_messages = [{"role": "user", "content": "Hello"}] + self.mock_model = "gpt-4" + def test_litellm_exceptions(self): litellm_ex = LiteLLMExceptions() litellm_ex._load(strict=True) @@ -35,3 +39,55 @@ class TestSendChat(unittest.TestCase): # Call the simple_send_with_retries method simple_send_with_retries("model", ["message"]) assert mock_print.call_count == 3 + + @patch("litellm.completion") + def test_send_completion_basic(self, mock_completion): + # Setup mock response + mock_response = MagicMock() + mock_completion.return_value = mock_response + + # Test basic send_completion + hash_obj, response = send_completion( + self.mock_model, self.mock_messages, functions=None, stream=False + ) + + assert response == mock_response + mock_completion.assert_called_once() + + @patch("litellm.completion") + def test_send_completion_with_functions(self, mock_completion): + mock_function = {"name": "test_function", "parameters": {"type": "object"}} + + hash_obj, response = send_completion( + self.mock_model, self.mock_messages, functions=[mock_function], stream=False + ) + + # Verify function was properly included in tools + called_kwargs = mock_completion.call_args.kwargs + assert "tools" in called_kwargs + assert called_kwargs["tools"][0]["function"] == mock_function + + @patch("litellm.completion") + def test_simple_send_attribute_error(self, mock_completion): + # Setup mock to raise AttributeError + mock_completion.return_value = MagicMock() + mock_completion.return_value.choices = None + + # Should return None on AttributeError + result = simple_send_with_retries(self.mock_model, self.mock_messages) + assert result is None + + @patch("litellm.completion") + @patch("builtins.print") + def test_simple_send_non_retryable_error(self, mock_print, mock_completion): + # Test with an error that shouldn't trigger retries + mock = MagicMock() + mock.status_code = 400 + + mock_completion.side_effect = litellm.NotFoundError( + message="Invalid request", llm_provider="test_provider", model="test_model" + ) + + result = simple_send_with_retries(self.mock_model, self.mock_messages) + assert result is None + assert mock_print.call_count == 1 diff --git a/tests/scrape/test_scrape.py b/tests/scrape/test_scrape.py index 500a70a07..82c649324 100644 --- a/tests/scrape/test_scrape.py +++ b/tests/scrape/test_scrape.py @@ -44,7 +44,7 @@ class TestScrape(unittest.TestCase): self.commands.io.tool_error = mock_print_error # Run the cmd_web command - result = self.commands.cmd_web("https://example.com") + result = self.commands.cmd_web("https://example.com", return_content=True) # Assert that the result contains some content self.assertIsNotNone(result)