auto-coder 0.1.400__py3-none-any.whl → 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of auto-coder might be problematic. Click here for more details.

Files changed (48) hide show
  1. {auto_coder-0.1.400.dist-info → auto_coder-1.0.0.dist-info}/METADATA +1 -1
  2. {auto_coder-0.1.400.dist-info → auto_coder-1.0.0.dist-info}/RECORD +48 -31
  3. autocoder/agent/agentic_filter.py +1 -1
  4. autocoder/agent/base_agentic/tools/read_file_tool_resolver.py +1 -1
  5. autocoder/auto_coder_runner.py +120 -26
  6. autocoder/chat_auto_coder.py +81 -22
  7. autocoder/commands/auto_command.py +1 -1
  8. autocoder/common/__init__.py +2 -2
  9. autocoder/common/file_monitor/test_file_monitor.py +307 -0
  10. autocoder/common/git_utils.py +7 -2
  11. autocoder/common/pruner/__init__.py +0 -0
  12. autocoder/common/pruner/agentic_conversation_pruner.py +197 -0
  13. autocoder/common/pruner/context_pruner.py +574 -0
  14. autocoder/common/pruner/conversation_pruner.py +132 -0
  15. autocoder/common/pruner/test_agentic_conversation_pruner.py +342 -0
  16. autocoder/common/pruner/test_context_pruner.py +546 -0
  17. autocoder/common/tokens/__init__.py +15 -0
  18. autocoder/common/tokens/counter.py +20 -0
  19. autocoder/common/v2/agent/agentic_edit.py +372 -538
  20. autocoder/common/v2/agent/agentic_edit_tools/__init__.py +8 -1
  21. autocoder/common/v2/agent/agentic_edit_tools/ac_mod_read_tool_resolver.py +40 -0
  22. autocoder/common/v2/agent/agentic_edit_tools/ac_mod_write_tool_resolver.py +43 -0
  23. autocoder/common/v2/agent/agentic_edit_tools/ask_followup_question_tool_resolver.py +8 -0
  24. autocoder/common/v2/agent/agentic_edit_tools/execute_command_tool_resolver.py +1 -1
  25. autocoder/common/v2/agent/agentic_edit_tools/read_file_tool_resolver.py +1 -1
  26. autocoder/common/v2/agent/agentic_edit_tools/search_files_tool_resolver.py +33 -88
  27. autocoder/common/v2/agent/agentic_edit_tools/test_write_to_file_tool_resolver.py +8 -8
  28. autocoder/common/v2/agent/agentic_edit_tools/todo_read_tool_resolver.py +118 -0
  29. autocoder/common/v2/agent/agentic_edit_tools/todo_write_tool_resolver.py +324 -0
  30. autocoder/common/v2/agent/agentic_edit_types.py +46 -4
  31. autocoder/common/v2/agent/runner/__init__.py +31 -0
  32. autocoder/common/v2/agent/runner/base_runner.py +106 -0
  33. autocoder/common/v2/agent/runner/event_runner.py +216 -0
  34. autocoder/common/v2/agent/runner/sdk_runner.py +40 -0
  35. autocoder/common/v2/agent/runner/terminal_runner.py +283 -0
  36. autocoder/common/v2/agent/runner/tool_display.py +191 -0
  37. autocoder/index/entry.py +1 -1
  38. autocoder/plugins/token_helper_plugin.py +107 -7
  39. autocoder/run_context.py +9 -0
  40. autocoder/sdk/__init__.py +114 -81
  41. autocoder/sdk/cli/main.py +5 -0
  42. autocoder/sdk/core/auto_coder_core.py +0 -158
  43. autocoder/sdk/core/bridge.py +2 -4
  44. autocoder/version.py +1 -1
  45. {auto_coder-0.1.400.dist-info → auto_coder-1.0.0.dist-info}/WHEEL +0 -0
  46. {auto_coder-0.1.400.dist-info → auto_coder-1.0.0.dist-info}/entry_points.txt +0 -0
  47. {auto_coder-0.1.400.dist-info → auto_coder-1.0.0.dist-info}/licenses/LICENSE +0 -0
  48. {auto_coder-0.1.400.dist-info → auto_coder-1.0.0.dist-info}/top_level.txt +0 -0
@@ -1,56 +1,34 @@
1
1
  import json
2
2
  import os
3
3
  import time
4
- from pydantic import BaseModel, Field
5
4
  import byzerllm
6
- from typing import List, Dict, Any, Union, Callable, Optional, Tuple
5
+ from typing import List, Dict, Any, Union, Optional, Tuple
7
6
  from autocoder.common.printer import Printer
8
- from rich.console import Console
9
- from rich.panel import Panel
10
- from pydantic import SkipValidation
11
- from byzerllm.utils.types import SingleOutputMeta
12
7
 
13
- from byzerllm.utils import (
14
- format_str_jinja2
15
- )
16
-
17
- from autocoder.common import AutoCoderArgs, git_utils, SourceCodeList, SourceCode
8
+ from autocoder.common import AutoCoderArgs, git_utils, SourceCodeList
18
9
  from autocoder.common.global_cancel import global_cancel
19
10
  from autocoder.common import detect_env
20
11
  from autocoder.common import shells
21
12
  from loguru import logger
22
- from autocoder.utils import llms as llms_utils
23
- from autocoder.common.auto_configure import config_readme
24
13
  from autocoder.utils.auto_project_type import ProjectTypeAnalyzer
25
- from rich.text import Text
14
+
26
15
  from autocoder.common.mcp_server import get_mcp_server, McpServerInfoRequest
27
16
  from autocoder.common import SourceCodeList
28
17
  from autocoder.common.utils_code_auto_generate import stream_chat_with_continue # Added import
29
18
  import re
30
19
  import xml.sax.saxutils
31
20
  import time # Added for sleep
32
- from typing import Iterator, Union, Type, Generator
33
- from xml.etree import ElementTree as ET
34
- from rich.console import Console # Added
35
- from rich.panel import Panel # Added
36
- from rich.syntax import Syntax # Added
37
- from rich.markdown import Markdown # Added
21
+ from typing import Union, Type, Generator
38
22
  from autocoder.events.event_manager_singleton import get_event_manager
39
- from autocoder.events.event_types import Event, EventType, EventMetadata
23
+ from autocoder.events.event_types import EventMetadata
40
24
  from autocoder.memory.active_context_manager import ActiveContextManager
41
25
  from autocoder.events import event_content as EventContentCreator
42
- from autocoder.shadows.shadow_manager import ShadowManager
43
- from autocoder.linters.shadow_linter import ShadowLinter
44
- from autocoder.compilers.shadow_compiler import ShadowCompiler
45
26
  from autocoder.common.action_yml_file_manager import ActionYmlFileManager
46
27
  from autocoder.common.auto_coder_lang import get_message
47
28
  from autocoder.common.save_formatted_log import save_formatted_log
48
- # Import the new display function
49
- from autocoder.common.v2.agent.agentic_tool_display import get_tool_display_message
50
29
  from autocoder.common.v2.agent.agentic_edit_types import FileChangeEntry
51
30
  from autocoder.utils.llms import get_single_llm
52
31
 
53
- from autocoder.common.file_checkpoint.models import FileChange as CheckpointFileChange
54
32
  from autocoder.common.file_checkpoint.manager import FileChangeManager as CheckpointFileChangeManager
55
33
  from autocoder.linters.normal_linter import NormalLinter
56
34
  from autocoder.compilers.normal_compiler import NormalCompiler
@@ -60,7 +38,8 @@ from autocoder.common.v2.agent.agentic_edit_tools import ( # Import specific re
60
38
  ReplaceInFileToolResolver, SearchFilesToolResolver, ListFilesToolResolver,
61
39
  ListCodeDefinitionNamesToolResolver, AskFollowupQuestionToolResolver,
62
40
  AttemptCompletionToolResolver, PlanModeRespondToolResolver, UseMcpToolResolver,
63
- UseRAGToolResolver, ListPackageInfoToolResolver
41
+ UseRAGToolResolver, ACModReadToolResolver, ACModWriteToolResolver, TodoReadToolResolver,
42
+ TodoWriteToolResolver
64
43
  )
65
44
  from autocoder.common.llm_friendly_package import LLMFriendlyPackageManager
66
45
  from autocoder.common.rulefiles.autocoderrules_utils import get_rules,auto_select_rules,get_required_and_index_rules
@@ -73,7 +52,8 @@ from autocoder.common.v2.agent.agentic_edit_types import (AgenticEditRequest, To
73
52
  ListFilesTool,
74
53
  ListCodeDefinitionNamesTool, AskFollowupQuestionTool,
75
54
  AttemptCompletionTool, PlanModeRespondTool, UseMcpTool,
76
- UseRAGTool, ListPackageInfoTool,
55
+ UseRAGTool, ACModReadTool, ACModWriteTool, TodoReadTool,
56
+ TodoWriteTool,
77
57
  TOOL_MODEL_MAP,
78
58
  # Event Types
79
59
  LLMOutputEvent, LLMThinkingEvent, ToolCallEvent,
@@ -98,21 +78,21 @@ TOOL_RESOLVER_MAP: Dict[Type[BaseTool], Type[BaseToolResolver]] = {
98
78
  SearchFilesTool: SearchFilesToolResolver,
99
79
  ListFilesTool: ListFilesToolResolver,
100
80
  ListCodeDefinitionNamesTool: ListCodeDefinitionNamesToolResolver,
101
- ListPackageInfoTool: ListPackageInfoToolResolver,
81
+ ACModReadTool: ACModReadToolResolver,
82
+ ACModWriteTool: ACModWriteToolResolver,
102
83
  AskFollowupQuestionTool: AskFollowupQuestionToolResolver,
103
84
  AttemptCompletionTool: AttemptCompletionToolResolver, # Will stop the loop anyway
104
85
  PlanModeRespondTool: PlanModeRespondToolResolver,
105
86
  UseMcpTool: UseMcpToolResolver,
106
- UseRAGTool: UseRAGToolResolver
87
+ UseRAGTool: UseRAGToolResolver,
88
+ TodoReadTool: TodoReadToolResolver,
89
+ TodoWriteTool: TodoWriteToolResolver
107
90
  }
108
- from autocoder.common.conversations.get_conversation_manager import (
109
- get_conversation_manager,
110
- get_conversation_manager_config,
111
- reset_conversation_manager
112
- )
113
- from autocoder.common.conversations import ConversationManagerConfig
114
- from autocoder.common.pull_requests import create_pull_request, detect_platform_from_repo
91
+ from autocoder.common.conversations.get_conversation_manager import get_conversation_manager
92
+ from autocoder.common.pull_requests import create_pull_request
115
93
  from autocoder.common.auto_coder_lang import get_message, get_message_with_format
94
+ from autocoder.common.pruner.agentic_conversation_pruner import AgenticConversationPruner
95
+ from copy import deepcopy
116
96
 
117
97
 
118
98
  # --- Tool Display Customization is now handled by agentic_tool_display.py ---
@@ -197,6 +177,9 @@ class AgenticEdit:
197
177
  # 对话管理器
198
178
  self.conversation_config =conversation_config
199
179
  self.conversation_manager = get_conversation_manager()
180
+
181
+ # Agentic 对话修剪器
182
+ self.agentic_pruner = AgenticConversationPruner(args=args, llm=self.context_prune_llm)
200
183
 
201
184
  if self.conversation_config.action == "new":
202
185
  conversation_id = self.conversation_manager.create_conversation(name=self.conversation_config.query or "New Conversation",
@@ -344,14 +327,37 @@ class AgenticEdit:
344
327
  <requires_approval>true or false</requires_approval>
345
328
  </execute_command>
346
329
 
347
- ## list_package_info
348
- Description: Request to retrieve information about a source code package, such as recent changes or documentation summary, to better understand the code context. It accepts a directory path (absolute or relative to the current project).
330
+ ## ac_mod_read
331
+ Description: Request to retrieve information about an AC Module - a language-agnostic module containing a .ac.mod.md file that provides complete functionality and can be used as an API. The .ac.mod.md file contains usage examples, core components, component dependencies, references to other AC modules, and testing information. It accepts a directory path (absolute or relative to the current project).
349
332
  Parameters:
350
- - path: (required) The source code package directory path.
333
+ - path: (required) The AC Module directory path (directory containing .ac.mod.md file).
351
334
  Usage:
352
- <list_package_info>
353
- <path>relative/or/absolute/package/path</path>
354
- </list_package_info>
335
+ <ac_mod_read>
336
+ <path>relative/or/absolute/ac/module/path</path>
337
+ </ac_mod_read>
338
+
339
+ ## ac_mod_write
340
+ Description: Request to create or update an AC Module's .ac.mod.md file. This tool allows you to define a new AC Module or modify an existing one by writing to its .ac.mod.md file. The file contains usage examples, core components, component dependencies, references to other AC modules, and testing information.
341
+ Parameters:
342
+ - path: (required) The AC Module directory path (directory where .ac.mod.md file should be created or updated).
343
+ - diff: (required) One or more SEARCH/REPLACE blocks following this exact format:
344
+ ```
345
+ <<<<<<< SEARCH
346
+ [exact content to find]
347
+ =======
348
+ [new content to replace with]
349
+ >>>>>>> REPLACE
350
+
351
+ This tool have the same usage as the replace_in_file tool, but it is used to update the AC Module's .ac.mod.md file.
352
+
353
+ Usage:
354
+
355
+ <ac_mod_write>
356
+ <path>relative/or/absolute/ac/module/path</path>
357
+ <diff>
358
+ Search and replace blocks here
359
+ </diff>
360
+ </ac_mod_write>
355
361
 
356
362
  ## read_file
357
363
  Description: Request to read the contents of a file at the specified path. Use this when you need to examine the contents of an existing file you do not know the contents of, for example to analyze code, review text files, or extract information from configuration files. Automatically extracts raw text from PDF and DOCX files. May not be suitable for other types of binary files, as it returns the raw content as a string.
@@ -455,7 +461,36 @@ class AgenticEdit:
455
461
  <options>
456
462
  Array of options here (optional), e.g. ["Option 1", "Option 2", "Option 3"]
457
463
  </options>
458
- </ask_followup_question>
464
+ </ask_followup_question>
465
+
466
+ ## todo_read
467
+ Description: Request to read the current todo list for the session. This tool helps you track progress, organize complex tasks, and understand the current status of ongoing work. Use this tool proactively to stay aware of task progress and demonstrate thoroughness.
468
+ Parameters:
469
+ - No parameters required
470
+ Usage:
471
+ <todo_read>
472
+ </todo_read>
473
+
474
+ ## todo_write
475
+ Description: Request to create and manage a structured task list for your current coding session. This helps you track progress, organize complex tasks, and demonstrate thoroughness to the user. It also helps the user understand the progress of the task and overall progress of their request. Use this tool proactively for complex multi-step tasks, when explicitly requested by the user, or when you need to organize multiple operations.
476
+ Parameters:
477
+ - action: (required) The action to perform: 'create' (create new todo list), 'add_task' (add single task), 'update' (update existing task), 'mark_progress' (mark task as in progress), 'mark_completed' (mark task as completed)
478
+ - task_id: (optional) The ID of the task to update (required for update, mark_progress, mark_completed actions)
479
+ - content: (optional) The task content or description (required for create, add_task actions)
480
+ - priority: (optional) Task priority level: 'high', 'medium', 'low' (default: 'medium')
481
+ - status: (optional) Task status: 'pending', 'in_progress', 'completed' (default: 'pending')
482
+ - notes: (optional) Additional notes or details about the task
483
+ Usage:
484
+ <todo_write>
485
+ <action>create</action>
486
+ <content>
487
+ <task>Read the configuration file</task>
488
+ <task>Update the database settings</task>
489
+ <task>Test the connection</task>
490
+ <task>Deploy the changes</task>
491
+ </content>
492
+ <priority>high</priority>
493
+ </todo_write>
459
494
 
460
495
  ## attempt_completion
461
496
  Description: After each tool use, the user will respond with the result of that tool use, i.e. if it succeeded or failed, along with any reasons for failure. Once you've received the results of tool uses and can confirm that the task is complete, use this tool to present the result of your work to the user. Optionally you may provide a CLI command to showcase the result of your work. The user may respond with feedback if they are not satisfied with the result, which you can use to make improvements and try again.
@@ -505,7 +540,7 @@ class AgenticEdit:
505
540
  {%if rag_server_info %}
506
541
  ### RAG_SERVER_LIST
507
542
  {{rag_server_info}}
508
- {%endif%}
543
+ {%endif%}
509
544
 
510
545
  # Tool Use Examples
511
546
 
@@ -579,7 +614,35 @@ class AgenticEdit:
579
614
  <server_name>github</server_name>
580
615
  <tool_name>create_issue</tool_name>
581
616
  <query>ower is octocat, repo is hello-world, title is Found a bug, body is I'm having a problem with this. labels is "bug" and "help wanted",assignees is "octocat"</query>
582
- </use_mcp_tool>
617
+ </use_mcp_tool>
618
+
619
+ ## Example 5: Reading the current todo list
620
+
621
+ <todo_read>
622
+ </todo_read>
623
+
624
+ ## Example 6: Creating a new todo list for a complex task
625
+
626
+ <todo_write>
627
+ <action>create</action>
628
+ <content>
629
+ <task>Analyze the existing codebase structure</task>
630
+ <task>Design the new feature architecture</task>
631
+ <task>Implement the core functionality</task>
632
+ <task>Add comprehensive tests</task>
633
+ <task>Update documentation</task>
634
+ <task>Review and refactor code</task>
635
+ </content>
636
+ <priority>high</priority>
637
+ </todo_write>
638
+
639
+ ## Example 7: Marking a specific task as completed
640
+
641
+ <todo_write>
642
+ <action>mark_completed</action>
643
+ <task_id>task_123</task_id>
644
+ <notes>Successfully implemented with 95% test coverage</notes>
645
+ </todo_write>
583
646
 
584
647
  # Tool Use Guidelines
585
648
  0. **ALWAYS START WITH THOROUGH SEARCH AND EXPLORATION.** Before making any code changes, use search tools (list_files, grep commands) to fully understand the codebase structure, existing patterns, and dependencies. This prevents errors and ensures your changes align with project conventions.
@@ -740,10 +803,10 @@ class AgenticEdit:
740
803
  - **Combine multiple approaches** for comprehensive understanding
741
804
 
742
805
  **Default workflow:**
743
- 1. `list_files` → understand structure
806
+ 1. `list_files`(without recursively) → understand structure (if needed)
744
807
  2. `grep` → find specific patterns/symbols
745
808
  3. `read_file` → examine details
746
- 4. Implement changes
809
+ 4. Implement changes
747
810
  5. `grep` → verify changes
748
811
 
749
812
  # Comprehensive Workflow
@@ -809,13 +872,7 @@ class AgenticEdit:
809
872
 
810
873
  More detail is on the EDITING FILES PART.
811
874
 
812
- ## Phase 5: Comprehensive Verification
813
-
814
- **File System Verification**
815
- <execute_command>
816
- <command>ls -la newfile.* 2>/dev/null || echo "Expected new files not found"</command>
817
- <requires_approval>false</requires_approval>
818
- </execute_command>
875
+ ## Phase 5: Comprehensive Verification
819
876
 
820
877
  **Code Integration Verification**
821
878
  <execute_command>
@@ -832,17 +889,7 @@ class AgenticEdit:
832
889
  <execute_command>
833
890
  <command>npm run lint 2>/dev/null || echo "Linting not configured"</command>
834
891
  <requires_approval>false</requires_approval>
835
- </execute_command>
836
-
837
- <execute_command>
838
- <command>npm test 2>/dev/null || echo "Testing not configured"</command>
839
- <requires_approval>false</requires_approval>
840
- </execute_command>
841
-
842
- <execute_command>
843
- <command>npm run build 2>/dev/null || echo "Build not configured"</command>
844
- <requires_approval>false</requires_approval>
845
- </execute_command>
892
+ </execute_command>
846
893
 
847
894
  **Documentation & Comments**
848
895
  - Verify that new functions/classes have appropriate documentation
@@ -880,6 +927,118 @@ class AgenticEdit:
880
927
 
881
928
  ====
882
929
 
930
+ TODO FILE TOOLS
931
+
932
+ The TODO tools help you manage and track task progress during complex coding sessions. They provide structured task management capabilities that enhance productivity and demonstrate thoroughness to users.
933
+
934
+ # todo_read
935
+
936
+ ## Purpose
937
+
938
+ - Read and display the current session's todo list to understand task progress
939
+ - Get an overview of all pending, in-progress, and completed tasks
940
+ - Track the status of complex multi-step operations
941
+
942
+ ## When to Use
943
+
944
+ Use this tool proactively and frequently to ensure awareness of current task status:
945
+
946
+ - **At the beginning of conversations** to see what's pending
947
+ - **Before starting new tasks** to prioritize work appropriately
948
+ - **When the user asks about previous tasks** or plans
949
+ - **Whenever you're uncertain about what to do next**
950
+ - **After completing tasks** to update understanding of remaining work
951
+ - **After every few messages** to ensure you're staying on track
952
+ - **Periodically during long sessions** to review progress and stay organized
953
+
954
+ ## Important Considerations
955
+
956
+ - This tool takes **no parameters** - leave the input completely blank or empty
957
+ - **DO NOT** include dummy objects, placeholder strings, or keys like "input" or "empty"
958
+ - **LEAVE IT BLANK** - the tool will automatically read the current session's todo list
959
+ - Returns formatted output showing tasks grouped by status (In Progress, Pending, Completed)
960
+ - Provides summary statistics about task completion rates
961
+
962
+ ## Benefits
963
+
964
+ - Helps maintain context and continuity across complex tasks
965
+ - Provides clear visibility into what has been accomplished and what remains
966
+ - Demonstrates organized approach to problem-solving
967
+ - Helps prioritize next steps based on current task status
968
+
969
+ # todo_write
970
+
971
+ ## Purpose
972
+
973
+ - Create and manage structured task lists for complex coding sessions
974
+ - Track progress on multi-step operations with status updates
975
+ - Organize work into manageable, prioritized tasks
976
+ - Provide clear progress visibility to users
977
+
978
+ ## When to Use
979
+
980
+ Use this tool proactively in these scenarios:
981
+
982
+ - **Complex multi-step tasks**: When a task requires 3 or more distinct steps or actions
983
+ - **Non-trivial and complex tasks**: Tasks that require careful planning or multiple operations
984
+ - **User explicitly requests todo list**: When the user directly asks you to use the todo list
985
+ - **User provides multiple tasks**: When users provide a list of things to be done (numbered or comma-separated)
986
+ - **After receiving new instructions**: Immediately capture user requirements as todos
987
+ - **When you start working on a task**: Mark it as in_progress BEFORE beginning work (ideally only one task should be in_progress at a time)
988
+ - **After completing a task**: Mark it as completed and add any new follow-up tasks discovered during implementation
989
+
990
+ ## When NOT to Use
991
+
992
+ Skip using this tool when:
993
+
994
+ - There is only a **single, straightforward task**
995
+ - The task is **trivial** and tracking it provides no organizational benefit
996
+ - The task can be completed in **less than 3 trivial steps**
997
+ - The task is **purely conversational or informational**
998
+
999
+ **NOTE**: Do not use this tool if there is only one trivial task to do. In this case you are better off just doing the task directly.
1000
+
1001
+ ## Important Considerations
1002
+
1003
+ - Each task gets a unique ID that can be used for future updates
1004
+ - Task content for 'create' action should be formatted as a numbered list for multiple tasks
1005
+ - The system automatically tracks task creation and modification timestamps
1006
+ - Todo lists persist across tool calls within the same session
1007
+ - Use descriptive task names that clearly indicate what needs to be accomplished
1008
+
1009
+ ## Example Usage Scenario
1010
+
1011
+ ```
1012
+ User: I want to add a dark mode toggle to the application settings. Make sure you run the tests and build when you're done!
1013
+
1014
+ Assistant: I'll help add a dark mode toggle to your application settings. Let me create a todo list to track this implementation.
1015
+
1016
+ Creates todo list with the following items:
1017
+ 1. Create dark mode toggle component in Settings page
1018
+ 2. Add dark mode state management (context/store)
1019
+ 3. Implement CSS-in-JS styles for dark theme
1020
+ 4. Update existing components to support theme switching
1021
+ 5. Run tests and build process, addressing any failures or errors that occur
1022
+
1023
+ Thinking: The assistant used the todo list because:
1024
+ 1. Adding dark mode is a multi-step feature requiring UI, state management, and styling changes
1025
+ 2. The user explicitly requested tests and build be run afterward
1026
+ 3. The assistant inferred that tests and build need to pass by adding "Ensure tests and build succeed" as the final task
1027
+ ```
1028
+
1029
+ ## Workflow Tips
1030
+
1031
+ 1. **Start with creation**: Use 'create' action to establish the initial task list for complex projects
1032
+ 2. **Add tasks incrementally**: Use 'add_task' as new requirements emerge during implementation
1033
+ 3. **Track progress actively**: Use 'mark_progress' when starting work on a task
1034
+ 4. **Complete tasks promptly**: Use 'mark_completed' when tasks are finished
1035
+ 5. **Add context**: Use 'notes' parameter to record important decisions or challenges
1036
+ 6. **Review regularly**: Use todo_read to maintain awareness of overall progress
1037
+
1038
+ By using these TODO tools effectively, you can maintain better organization, provide clear progress visibility, and demonstrate a systematic approach to complex coding tasks.
1039
+
1040
+ ====
1041
+
883
1042
  EDITING FILES
884
1043
 
885
1044
  Before applying the editing techniques below, ensure you have followed the SEARCHING FILES methodology to fully understand the codebase context.
@@ -956,41 +1115,158 @@ class AgenticEdit:
956
1115
 
957
1116
  ====
958
1117
 
959
- PACKAGE CONTEXT INFORMATION
1118
+ AC MOD FILES
960
1119
 
961
- # Understanding Directory Context
1120
+ # AC Modules (.ac.mod.md)
962
1121
 
963
- ## Purpose
1122
+ ## What is an AC Module?
964
1123
 
965
- - Each directory in the project (especially source code directories) has implicit context information
966
- - This includes recent changes, important files, and their purposes
967
- - This contextual information helps you understand the role of the directory and the files in the directory
1124
+ Any directory containing a `.ac.mod.md` file is considered an AC Module - a language-agnostic module that provides complete functionality and can be used as an API. These modules are self-contained units with well-defined interfaces and comprehensive documentation.
968
1125
 
969
- ## Accessing Directory Context
1126
+ ## AC Module Structure
1127
+ - .ac.mod.md contains detailed information about:
1128
+ - Usage examples and quick start guides
1129
+ - Core components and their relationships
1130
+ - Dependencies between components
1131
+ - References to other AC modules it depends on
1132
+ - Testing instructions and examples
970
1133
 
971
- - Use the **list_package_info** tool to view this information for a specific directory
972
- - Do NOT use other tools like list_files to view this specialized context information
1134
+ ## When to Use AC Modules
973
1135
 
974
- ## When to Use
1136
+ 1. **Avoid duplicate implementation**: Check if functionality already exists in project AC modules before implementing new features
1137
+ 2. **Project understanding**: Review multiple AC modules to gain comprehensive knowledge of the entire project architecture
1138
+ 3. **File modification context**: When modifying files in a directory, check if it's an AC module or contains AC modules to understand the full impact
1139
+
1140
+ ## ac_mod_read
1141
+
1142
+ When to use:
1143
+ - Use the this tool to retrieve comprehensive information about an AC module
1144
+ - The tool reads the `.ac.mod.md` file and provides structured information about the module
1145
+
1146
+ Example:
1147
+
1148
+ <ac_mod_read>
1149
+ <path>src/autocoder/agent</path>
1150
+ </ac_mod_read>
1151
+
975
1152
 
976
- - When you need to understand what has recently changed in a directory
977
- - When you need insight into the purpose and organization of a directory
978
- - Before diving into detailed file exploration with other tools
1153
+ ## ac_mod_write
1154
+
1155
+ When to use:
1156
+ - When we edit files in an AC module, we should update the `.ac.mod.md` file to reflect the changes.
1157
+ - When the user directly asks you to create or update an AC module
1158
+
1159
+ Example:
1160
+
1161
+ <ac_mod_write>
1162
+ <path>src/autocoder/agent</path>
1163
+ <diff>
1164
+ search and replace blocks here
1165
+ </diff>
1166
+ </ac_mod_write>
979
1167
 
980
- ## Example
1168
+ The content of the `.ac.mod.md` file should be ***strictly following*** the structure of the example as follows:
1169
+
1170
+ <ac_mod_md_example>
1171
+ # [Module Name]
981
1172
 
982
- ```xml
983
- <list_package_info>
984
- <path>src/some/directory</path>
985
- </list_package_info>
1173
+ [One-sentence description of the module's core functionality and its role in the project]
1174
+
1175
+ ## Directory Structure
1176
+
1177
+ ```
1178
+ [module_path]/
1179
+ ├── [main_file1] # [Detailed function description]
1180
+ ├── [main_file2] # [Detailed function description]
1181
+ ├── [subdirectory]/ # [Subdirectory function description]
1182
+ │ └── [subfile] # [Subfile function description]
1183
+ └── .ac.mod.md # This document
986
1184
  ```
987
1185
 
988
- # Benefits
1186
+ ## Quick Start
1187
+
1188
+ ### Basic Usage
1189
+
1190
+ ```python
1191
+ # Import necessary modules
1192
+ from [module_path] import [MainClassName], [HelperClassName]
1193
+
1194
+ # 1. Initialize configuration
1195
+ [Specific initialization code example]
1196
+
1197
+ # 2. Create instance
1198
+ [Instance creation code example]
1199
+
1200
+ # 3. Basic usage
1201
+ [Basic usage code example]
1202
+ ```
1203
+
1204
+ ### Helper Functions
1205
+
1206
+ [Detailed explanation of helper functions provided by the module]
1207
+
1208
+ ### Configuration Management
1209
+
1210
+ [Explanation of configuration options and management methods]
1211
+
1212
+ ## Core Components
1213
+
1214
+ ### 1. [MainClassName] Main Class
1215
+ [YOU SHOULD KEEP THIS PART AS SIMPLIFIED AS POSSIBLE]
1216
+ **Core Features:**
1217
+ - [Feature1]: [Detailed description]
1218
+ - [Feature2]: [Detailed description]
1219
+
1220
+ **Main Methods:**
1221
+ - `[method1]()`: [Method functionality and parameter description]
1222
+ - `[method2]()`: [Method functionality and parameter description]
1223
+
1224
+ ### 2. [Module] Architecture
1225
+
1226
+ [Detailed explanation of the module's design and implementation]
989
1227
 
990
- - Quickly identifies recently modified files that may be relevant to your task
991
- - Provides high-level understanding of directory contents and purpose
992
- - Helps prioritize which files to examine in detail with tools like read_file, shell commands, or list_code_definition_names
1228
+ ## Mermaid File Dependency Graph
1229
+ [Main description of dependencies within the module]
993
1230
 
1231
+ ```mermaid
1232
+ graph TB
1233
+ %% Core module definition
1234
+ [MainModule][MainModule<br/>Core functionality description]
1235
+ [SubModule1][SubModule1<br/>Functionality description]
1236
+
1237
+ %% Dependency relationships
1238
+ [MainModule] --> [SubModule1]
1239
+
1240
+ %% Style definitions
1241
+ classDef coreClass fill:#e1f5fe,stroke:#0277bd,stroke-width:2px
1242
+ classDef subClass fill:#f3e5f5,stroke:#7b1fa2,stroke-width:1px
1243
+
1244
+ class [MainModule] coreClass
1245
+ class [SubModule1] subClass
1246
+ ```
1247
+
1248
+ ## Dependency Relationships
1249
+ Dependencies on other modules with .ac.mod.md files, simply shown as a relative path list, for example:
1250
+
1251
+ - ../a/.ac.mod.md
1252
+ - ../../b/.ac.mod.md
1253
+
1254
+ ## Commands to Verify Module Functionality
1255
+
1256
+ Usually an executable command that can run a script or execute tests, for example:
1257
+
1258
+ ```
1259
+ node --experimental-transform-types ./a/b/c.ts
1260
+ ```
1261
+
1262
+ Or test execution commands:
1263
+
1264
+ ```
1265
+ pytest path/to/your/module/tests -v
1266
+ ```
1267
+ </ac_mod_md_example>
1268
+
1269
+
994
1270
  ====
995
1271
 
996
1272
  CAPABILITIES
@@ -1257,9 +1533,9 @@ class AgenticEdit:
1257
1533
 
1258
1534
  self.current_conversations = conversations
1259
1535
 
1260
- # 计算初始对话窗口长度并触发事件
1536
+ # 计算初始对话窗口长度
1261
1537
  conversation_str = json.dumps(conversations, ensure_ascii=False)
1262
- current_tokens = count_tokens(conversation_str)
1538
+ current_tokens = count_tokens(conversation_str)
1263
1539
  yield WindowLengthChangeEvent(tokens_used=current_tokens)
1264
1540
 
1265
1541
  logger.info(
@@ -1291,12 +1567,12 @@ class AgenticEdit:
1291
1567
  f"Starting LLM interaction cycle. History size: {len(conversations)}")
1292
1568
 
1293
1569
  assistant_buffer = ""
1294
- logger.info("Initializing stream chat with LLM")
1570
+ logger.info("Initializing stream chat with LLM")
1295
1571
 
1296
- # ## 实际请求大模型
1572
+ # ## 实际请求大模型,并且我们会裁剪对话窗口长度
1297
1573
  llm_response_gen = stream_chat_with_continue(
1298
1574
  llm=self.llm,
1299
- conversations=conversations,
1575
+ conversations=self.agentic_pruner.prune_conversations(deepcopy(conversations)),
1300
1576
  llm_config={}, # Placeholder for future LLM configs
1301
1577
  args=self.args
1302
1578
  )
@@ -1996,7 +2272,7 @@ class AgenticEdit:
1996
2272
 
1997
2273
  # 准备 PR 标题和描述
1998
2274
  query = self.args.query or get_message("/agent/edit/pull_request/default_query")
1999
- pr_title = get_message_with_format("/agent/edit/pull_request/title", query=query[0:40])
2275
+ pr_title = get_message_with_format("/agent/edit/pull_request/title", query="{query[0:40]}...")
2000
2276
 
2001
2277
  # 构建 PR 描述
2002
2278
  file_list = ""
@@ -2101,446 +2377,4 @@ class AgenticEdit:
2101
2377
  path="/agent/edit/pull_request_exception",
2102
2378
  stream_out_type="/agent/edit"
2103
2379
  ).to_dict()
2104
- )
2105
-
2106
- def run_in_terminal(self, request: AgenticEditRequest):
2107
- """
2108
- Runs the agentic edit process based on the request and displays
2109
- the interaction streamingly in the terminal using Rich.
2110
- """
2111
- import json
2112
- console = Console()
2113
- project_name = os.path.basename(os.path.abspath(self.args.source_dir))
2114
-
2115
- if self.conversation_config.action == "list":
2116
- conversations = self.conversation_manager.list_conversations()
2117
- # 只保留 conversation_id 和 name 字段
2118
- filtered_conversations = []
2119
- for conv in conversations:
2120
- filtered_conv = {
2121
- "conversation_id": conv.get("conversation_id"),
2122
- "name": conv.get("name")
2123
- }
2124
- filtered_conversations.append(filtered_conv)
2125
-
2126
- # 格式化 JSON 输出,使用 JSON 格式渲染而不是 Markdown
2127
- json_str = json.dumps(filtered_conversations, ensure_ascii=False, indent=4)
2128
- console.print(Panel(json_str,
2129
- title="🏁 Task Completion", border_style="green", title_align="left"))
2130
- return
2131
-
2132
-
2133
- if self.conversation_config.action == "new" and not request.user_input.strip():
2134
- console.print(Panel(Markdown(f"New conversation created: {self.conversation_manager.get_current_conversation_id()}"),
2135
- title="🏁 Task Completion", border_style="green", title_align="left"))
2136
- return
2137
-
2138
- console.rule(f"[bold cyan]Starting Agentic Edit: {project_name}[/]")
2139
- console.print(Panel(
2140
- f"[bold]{get_message('/agent/edit/user_query')}:[/bold]\n{request.user_input}", title=get_message("/agent/edit/objective"), border_style="blue"))
2141
-
2142
- # 用于累计TokenUsageEvent数据
2143
- accumulated_token_usage = {
2144
- "model_name": "",
2145
- "input_tokens": 0,
2146
- "output_tokens": 0,
2147
- "input_cost": 0.0,
2148
- "output_cost": 0.0
2149
- }
2150
-
2151
- try:
2152
- self.apply_pre_changes()
2153
- event_stream = self.analyze(request)
2154
- for event in event_stream:
2155
- if isinstance(event, ConversationIdEvent):
2156
- console.print(f"[dim]Conversation ID: {event.conversation_id}[/dim]")
2157
- continue
2158
- if isinstance(event, TokenUsageEvent):
2159
- last_meta: SingleOutputMeta = event.usage
2160
- # Get model info for pricing
2161
- from autocoder.utils import llms as llm_utils
2162
- model_name = ",".join(llm_utils.get_llm_names(self.llm))
2163
- model_info = llm_utils.get_model_info(
2164
- model_name, self.args.product_mode) or {}
2165
- input_price = model_info.get(
2166
- "input_price", 0.0) if model_info else 0.0
2167
- output_price = model_info.get(
2168
- "output_price", 0.0) if model_info else 0.0
2169
-
2170
- # Calculate costs
2171
- input_cost = (last_meta.input_tokens_count *
2172
- input_price) / 1000000 # Convert to millions
2173
- # Convert to millions
2174
- output_cost = (
2175
- last_meta.generated_tokens_count * output_price) / 1000000
2176
-
2177
- # 添加日志记录
2178
- logger.info(f"Token Usage: Model={model_name}, Input Tokens={last_meta.input_tokens_count}, Output Tokens={last_meta.generated_tokens_count}, Input Cost=${input_cost:.6f}, Output Cost=${output_cost:.6f}")
2179
-
2180
- # 累计token使用情况
2181
- accumulated_token_usage["model_name"] = model_name
2182
- accumulated_token_usage["input_tokens"] += last_meta.input_tokens_count
2183
- accumulated_token_usage["output_tokens"] += last_meta.generated_tokens_count
2184
- accumulated_token_usage["input_cost"] += input_cost
2185
- accumulated_token_usage["output_cost"] += output_cost
2186
-
2187
- elif isinstance(event, WindowLengthChangeEvent):
2188
- # 显示当前会话的token数量
2189
- logger.info(f"当前会话总 tokens: {event.tokens_used}")
2190
- console.print(f"[dim]当前会话总 tokens: {event.tokens_used}[/dim]")
2191
-
2192
- elif isinstance(event, LLMThinkingEvent):
2193
- # Render thinking within a less prominent style, maybe grey?
2194
- console.print(f"[grey50]{event.text}[/grey50]", end="")
2195
- elif isinstance(event, LLMOutputEvent):
2196
- # Print regular LLM output, potentially as markdown if needed later
2197
- console.print(event.text, end="")
2198
- elif isinstance(event, ToolCallEvent):
2199
- # Skip displaying AttemptCompletionTool's tool call
2200
- if isinstance(event.tool, AttemptCompletionTool):
2201
- continue # Do not display AttemptCompletionTool tool call
2202
-
2203
- tool_name = type(event.tool).__name__
2204
- # Use the new internationalized display function
2205
- display_content = get_tool_display_message(event.tool)
2206
- console.print(Panel(
2207
- display_content, title=f"🛠️ Action: {tool_name}", border_style="blue", title_align="left"))
2208
-
2209
- elif isinstance(event, ToolResultEvent):
2210
- # Skip displaying AttemptCompletionTool's result
2211
- if event.tool_name == "AttemptCompletionTool":
2212
- continue # Do not display AttemptCompletionTool result
2213
-
2214
- if event.tool_name == "PlanModeRespondTool":
2215
- continue
2216
-
2217
- result = event.result
2218
- title = f"✅ Tool Result: {event.tool_name}" if result.success else f"❌ Tool Result: {event.tool_name}"
2219
- border_style = "green" if result.success else "red"
2220
- base_content = f"[bold]Status:[/bold] {'Success' if result.success else 'Failure'}\n"
2221
- base_content += f"[bold]Message:[/bold] {result.message}\n"
2222
-
2223
- def _format_content(content):
2224
- if len(content) > 200:
2225
- return f"{content[:100]}\n...\n{content[-100:]}"
2226
- else:
2227
- return content
2228
-
2229
- # Prepare panel for base info first
2230
- panel_content = [base_content]
2231
- syntax_content = None
2232
-
2233
- if result.content is not None:
2234
- content_str = ""
2235
- try:
2236
- if isinstance(result.content, (dict, list)):
2237
- import json
2238
- content_str = json.dumps(
2239
- result.content, indent=2, ensure_ascii=False)
2240
- syntax_content = Syntax(
2241
- content_str, "json", theme="default", line_numbers=False)
2242
- elif isinstance(result.content, str) and ('\n' in result.content or result.content.strip().startswith('<')):
2243
- # Heuristic for code or XML/HTML
2244
- lexer = "python" # Default guess
2245
- if event.tool_name == "ReadFileTool" and isinstance(event.result.message, str):
2246
- # Try to guess lexer from file extension in message
2247
- if ".py" in event.result.message:
2248
- lexer = "python"
2249
- elif ".js" in event.result.message:
2250
- lexer = "javascript"
2251
- elif ".ts" in event.result.message:
2252
- lexer = "typescript"
2253
- elif ".html" in event.result.message:
2254
- lexer = "html"
2255
- elif ".css" in event.result.message:
2256
- lexer = "css"
2257
- elif ".json" in event.result.message:
2258
- lexer = "json"
2259
- elif ".xml" in event.result.message:
2260
- lexer = "xml"
2261
- elif ".md" in event.result.message:
2262
- lexer = "markdown"
2263
- else:
2264
- lexer = "text" # Fallback lexer
2265
- elif event.tool_name == "ExecuteCommandTool":
2266
- lexer = "shell"
2267
- else:
2268
- lexer = "text"
2269
-
2270
- syntax_content = Syntax(
2271
- _format_content(result.content), lexer, theme="default", line_numbers=True)
2272
- else:
2273
- content_str = str(result.content)
2274
- # Append simple string content directly
2275
- panel_content.append(
2276
- _format_content(content_str))
2277
- except Exception as e:
2278
- logger.warning(
2279
- f"Error formatting tool result content: {e}")
2280
- panel_content.append(
2281
- # Fallback
2282
- _format_content(str(result.content)))
2283
-
2284
- # Print the base info panel
2285
- console.print(Panel("\n".join(
2286
- panel_content), title=title, border_style=border_style, title_align="left"))
2287
- # Print syntax highlighted content separately if it exists
2288
- if syntax_content:
2289
- console.print(syntax_content)
2290
- elif isinstance(event, PlanModeRespondEvent):
2291
- console.print(Panel(Markdown(event.completion.response),
2292
- title="🏁 Task Completion", border_style="green", title_align="left"))
2293
-
2294
- elif isinstance(event, CompletionEvent):
2295
- # 在这里完成实际合并
2296
- try:
2297
- self.apply_changes()
2298
- except Exception as e:
2299
- logger.exception(
2300
- f"Error merging shadow changes to project: {e}")
2301
-
2302
- console.print(Panel(Markdown(event.completion.result),
2303
- title="🏁 Task Completion", border_style="green", title_align="left"))
2304
- if event.completion.command:
2305
- console.print(
2306
- f"[dim]Suggested command:[/dim] [bold cyan]{event.completion.command}[/]")
2307
- elif isinstance(event, ErrorEvent):
2308
- console.print(Panel(
2309
- f"[bold red]Error:[/bold red] {event.message}", title="🔥 Error", border_style="red", title_align="left"))
2310
-
2311
- time.sleep(0.1) # Small delay for better visual flow
2312
-
2313
- # 在处理完所有事件后打印累计的token使用情况
2314
- if accumulated_token_usage["input_tokens"] > 0:
2315
- self.printer.print_in_terminal(
2316
- "code_generation_complete",
2317
- duration=0.0,
2318
- input_tokens=accumulated_token_usage["input_tokens"],
2319
- output_tokens=accumulated_token_usage["output_tokens"],
2320
- input_cost=accumulated_token_usage["input_cost"],
2321
- output_cost=accumulated_token_usage["output_cost"],
2322
- speed=0.0,
2323
- model_names=accumulated_token_usage["model_name"],
2324
- sampling_count=1
2325
- )
2326
-
2327
- except Exception as e:
2328
- # 在处理异常时也打印累计的token使用情况
2329
- if accumulated_token_usage["input_tokens"] > 0:
2330
- self.printer.print_in_terminal(
2331
- "code_generation_complete",
2332
- duration=0.0,
2333
- input_tokens=accumulated_token_usage["input_tokens"],
2334
- output_tokens=accumulated_token_usage["output_tokens"],
2335
- input_cost=accumulated_token_usage["input_cost"],
2336
- output_cost=accumulated_token_usage["output_cost"],
2337
- speed=0.0,
2338
- model_names=accumulated_token_usage["model_name"],
2339
- sampling_count=1
2340
- )
2341
-
2342
- logger.exception(
2343
- "An unexpected error occurred during agent execution:")
2344
- console.print(Panel(
2345
- f"[bold red]FATAL ERROR:[/bold red]\n{str(e)}", title="🔥 System Error", border_style="red"))
2346
- raise e
2347
- finally:
2348
- console.rule("[bold cyan]Agentic Edit Finished[/]")
2349
-
2350
- def run(self, request: AgenticEditRequest):
2351
- try:
2352
- event_stream = self.analyze(request)
2353
- for agent_event in event_stream:
2354
- if isinstance(agent_event, CompletionEvent):
2355
- self.apply_changes()
2356
- yield agent_event
2357
-
2358
- except Exception as e:
2359
- logger.exception(
2360
- "An unexpected error occurred during agent execution: {e}")
2361
- raise e
2362
-
2363
-
2364
- def run_with_events(self, request: AgenticEditRequest):
2365
- """
2366
- Runs the agentic edit process, converting internal events to the
2367
- standard event system format and writing them using the event manager.
2368
- """
2369
- event_manager = get_event_manager(self.args.event_file)
2370
- self.apply_pre_changes()
2371
-
2372
- try:
2373
- event_stream = self.analyze(request)
2374
- for agent_event in event_stream:
2375
- content = None
2376
- metadata = EventMetadata(
2377
- action_file=self.args.file,
2378
- is_streaming=False,
2379
- stream_out_type="/agent/edit")
2380
-
2381
- if isinstance(agent_event, LLMThinkingEvent):
2382
- content = EventContentCreator.create_stream_thinking(
2383
- content=agent_event.text)
2384
- metadata.is_streaming = True
2385
- metadata.path = "/agent/edit/thinking"
2386
- event_manager.write_stream(
2387
- content=content.to_dict(), metadata=metadata.to_dict())
2388
- elif isinstance(agent_event, LLMOutputEvent):
2389
- content = EventContentCreator.create_stream_content(
2390
- content=agent_event.text)
2391
- metadata.is_streaming = True
2392
- metadata.path = "/agent/edit/output"
2393
- event_manager.write_stream(content=content.to_dict(),
2394
- metadata=metadata.to_dict())
2395
- elif isinstance(agent_event, ToolCallEvent):
2396
- tool_name = type(agent_event.tool).__name__
2397
- metadata.path = "/agent/edit/tool/call"
2398
- content = EventContentCreator.create_result(
2399
- content={
2400
- "tool_name": tool_name,
2401
- **agent_event.tool.model_dump()
2402
- },
2403
- metadata={}
2404
- )
2405
- event_manager.write_result(
2406
- content=content.to_dict(), metadata=metadata.to_dict())
2407
- elif isinstance(agent_event, ToolResultEvent):
2408
- metadata.path = "/agent/edit/tool/result"
2409
- content = EventContentCreator.create_result(
2410
- content={
2411
- "tool_name": agent_event.tool_name,
2412
- **agent_event.result.model_dump()
2413
- },
2414
- metadata={}
2415
- )
2416
- event_manager.write_result(
2417
- content=content.to_dict(), metadata=metadata.to_dict())
2418
- elif isinstance(agent_event, PlanModeRespondEvent):
2419
- metadata.path = "/agent/edit/plan_mode_respond"
2420
- content = EventContentCreator.create_markdown_result(
2421
- content=agent_event.completion.response,
2422
- metadata={}
2423
- )
2424
- event_manager.write_result(
2425
- content=content.to_dict(), metadata=metadata.to_dict())
2426
-
2427
- elif isinstance(agent_event, TokenUsageEvent):
2428
- last_meta: SingleOutputMeta = agent_event.usage
2429
- # Get model info for pricing
2430
- from autocoder.utils import llms as llm_utils
2431
- model_name = ",".join(llm_utils.get_llm_names(self.llm))
2432
- model_info = llm_utils.get_model_info(
2433
- model_name, self.args.product_mode) or {}
2434
- input_price = model_info.get(
2435
- "input_price", 0.0) if model_info else 0.0
2436
- output_price = model_info.get(
2437
- "output_price", 0.0) if model_info else 0.0
2438
-
2439
- # Calculate costs
2440
- input_cost = (last_meta.input_tokens_count *
2441
- input_price) / 1000000 # Convert to millions
2442
- # Convert to millions
2443
- output_cost = (
2444
- last_meta.generated_tokens_count * output_price) / 1000000
2445
-
2446
- # 添加日志记录
2447
- logger.info(f"Token Usage Details: Model={model_name}, Input Tokens={last_meta.input_tokens_count}, Output Tokens={last_meta.generated_tokens_count}, Input Cost=${input_cost:.6f}, Output Cost=${output_cost:.6f}")
2448
-
2449
- # 直接将每次的 TokenUsageEvent 写入到事件中
2450
- metadata.path = "/agent/edit/token_usage"
2451
- content = EventContentCreator.create_result(content=EventContentCreator.ResultTokenStatContent(
2452
- model_name=model_name,
2453
- elapsed_time=0.0,
2454
- first_token_time=last_meta.first_token_time,
2455
- input_tokens=last_meta.input_tokens_count,
2456
- output_tokens=last_meta.generated_tokens_count,
2457
- input_cost=input_cost,
2458
- output_cost=output_cost
2459
- ).to_dict())
2460
- event_manager.write_result(content=content.to_dict(), metadata=metadata.to_dict())
2461
-
2462
-
2463
- elif isinstance(agent_event, CompletionEvent):
2464
- # 在这里完成实际合并
2465
- try:
2466
- self.apply_changes()
2467
- except Exception as e:
2468
- logger.exception(
2469
- f"Error merging shadow changes to project: {e}")
2470
-
2471
- metadata.path = "/agent/edit/completion"
2472
- content = EventContentCreator.create_completion(
2473
- success_code="AGENT_COMPLETE",
2474
- success_message="Agent attempted task completion.",
2475
- result={
2476
- "response": agent_event.completion.result
2477
- }
2478
- )
2479
- event_manager.write_completion(
2480
- content=content.to_dict(), metadata=metadata.to_dict())
2481
- elif isinstance(agent_event, WindowLengthChangeEvent):
2482
- # 处理窗口长度变化事件
2483
- metadata.path = "/agent/edit/window_length_change"
2484
- content = EventContentCreator.create_result(
2485
- content={
2486
- "tokens_used": agent_event.tokens_used
2487
- },
2488
- metadata={}
2489
- )
2490
- event_manager.write_result(
2491
- content=content.to_dict(), metadata=metadata.to_dict())
2492
-
2493
- # 记录日志
2494
- logger.info(f"当前会话总 tokens: {agent_event.tokens_used}")
2495
-
2496
- elif isinstance(agent_event, ConversationIdEvent):
2497
- metadata.path = "/agent/edit/conversation_id"
2498
- content = EventContentCreator.create_result(
2499
- content={
2500
- "conversation_id": agent_event.conversation_id
2501
- },
2502
- metadata={}
2503
- )
2504
- event_manager.write_result(content=content.to_dict(), metadata=metadata.to_dict())
2505
-
2506
- elif isinstance(agent_event, ErrorEvent):
2507
- metadata.path = "/agent/edit/error"
2508
- content = EventContentCreator.create_error(
2509
- error_code="AGENT_ERROR",
2510
- error_message=agent_event.message,
2511
- details={"agent_event_type": "ErrorEvent"}
2512
- )
2513
- event_manager.write_error(
2514
- content=content.to_dict(), metadata=metadata.to_dict())
2515
- else:
2516
- metadata.path = "/agent/edit/error"
2517
- logger.warning(
2518
- f"Unhandled agent event type: {type(agent_event)}")
2519
- content = EventContentCreator.create_error(
2520
- error_code="AGENT_ERROR",
2521
- error_message=f"Unhandled agent event type: {type(agent_event)}",
2522
- details={"agent_event_type": type(
2523
- agent_event).__name__}
2524
- )
2525
- event_manager.write_error(
2526
- content=content.to_dict(), metadata=metadata.to_dict())
2527
-
2528
- except Exception as e:
2529
- logger.exception(
2530
- "An unexpected error occurred during agent execution:")
2531
- metadata = EventMetadata(
2532
- action_file=self.args.file,
2533
- is_streaming=False,
2534
- stream_out_type="/agent/edit/error")
2535
-
2536
- # 发送累计的TokenUsageEvent数据(在错误情况下也需要发送)
2537
-
2538
- error_content = EventContentCreator.create_error(
2539
- error_code="AGENT_FATAL_ERROR",
2540
- error_message=f"An unexpected error occurred: {str(e)}",
2541
- details={"exception_type": type(e).__name__}
2542
- )
2543
- event_manager.write_error(
2544
- content=error_content.to_dict(), metadata=metadata.to_dict())
2545
- # Re-raise the exception if needed, or handle appropriately
2546
- raise e
2380
+ )