auto-coder 0.1.399__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.
- {auto_coder-0.1.399.dist-info → auto_coder-1.0.0.dist-info}/METADATA +1 -1
- {auto_coder-0.1.399.dist-info → auto_coder-1.0.0.dist-info}/RECORD +71 -35
- autocoder/agent/agentic_filter.py +1 -1
- autocoder/agent/base_agentic/tools/read_file_tool_resolver.py +1 -1
- autocoder/auto_coder_runner.py +121 -26
- autocoder/chat_auto_coder.py +81 -22
- autocoder/commands/auto_command.py +1 -1
- autocoder/common/__init__.py +2 -2
- autocoder/common/ac_style_command_parser/parser.py +27 -12
- autocoder/common/auto_coder_lang.py +78 -0
- autocoder/common/command_completer_v2.py +1 -1
- autocoder/common/file_monitor/test_file_monitor.py +307 -0
- autocoder/common/git_utils.py +7 -2
- autocoder/common/pruner/__init__.py +0 -0
- autocoder/common/pruner/agentic_conversation_pruner.py +197 -0
- autocoder/common/pruner/context_pruner.py +574 -0
- autocoder/common/pruner/conversation_pruner.py +132 -0
- autocoder/common/pruner/test_agentic_conversation_pruner.py +342 -0
- autocoder/common/pruner/test_context_pruner.py +546 -0
- autocoder/common/pull_requests/__init__.py +256 -0
- autocoder/common/pull_requests/base_provider.py +191 -0
- autocoder/common/pull_requests/config.py +66 -0
- autocoder/common/pull_requests/example.py +1 -0
- autocoder/common/pull_requests/exceptions.py +46 -0
- autocoder/common/pull_requests/manager.py +201 -0
- autocoder/common/pull_requests/models.py +164 -0
- autocoder/common/pull_requests/providers/__init__.py +23 -0
- autocoder/common/pull_requests/providers/gitcode_provider.py +19 -0
- autocoder/common/pull_requests/providers/gitee_provider.py +20 -0
- autocoder/common/pull_requests/providers/github_provider.py +214 -0
- autocoder/common/pull_requests/providers/gitlab_provider.py +29 -0
- autocoder/common/pull_requests/test_module.py +1 -0
- autocoder/common/pull_requests/utils.py +344 -0
- autocoder/common/tokens/__init__.py +77 -0
- autocoder/common/tokens/counter.py +231 -0
- autocoder/common/tokens/file_detector.py +105 -0
- autocoder/common/tokens/filters.py +111 -0
- autocoder/common/tokens/models.py +28 -0
- autocoder/common/v2/agent/agentic_edit.py +538 -590
- autocoder/common/v2/agent/agentic_edit_tools/__init__.py +8 -1
- autocoder/common/v2/agent/agentic_edit_tools/ac_mod_read_tool_resolver.py +40 -0
- autocoder/common/v2/agent/agentic_edit_tools/ac_mod_write_tool_resolver.py +43 -0
- autocoder/common/v2/agent/agentic_edit_tools/ask_followup_question_tool_resolver.py +8 -0
- autocoder/common/v2/agent/agentic_edit_tools/execute_command_tool_resolver.py +1 -1
- autocoder/common/v2/agent/agentic_edit_tools/read_file_tool_resolver.py +1 -1
- autocoder/common/v2/agent/agentic_edit_tools/search_files_tool_resolver.py +33 -88
- autocoder/common/v2/agent/agentic_edit_tools/test_write_to_file_tool_resolver.py +8 -8
- autocoder/common/v2/agent/agentic_edit_tools/todo_read_tool_resolver.py +118 -0
- autocoder/common/v2/agent/agentic_edit_tools/todo_write_tool_resolver.py +324 -0
- autocoder/common/v2/agent/agentic_edit_types.py +47 -4
- autocoder/common/v2/agent/runner/__init__.py +31 -0
- autocoder/common/v2/agent/runner/base_runner.py +106 -0
- autocoder/common/v2/agent/runner/event_runner.py +216 -0
- autocoder/common/v2/agent/runner/sdk_runner.py +40 -0
- autocoder/common/v2/agent/runner/terminal_runner.py +283 -0
- autocoder/common/v2/agent/runner/tool_display.py +191 -0
- autocoder/index/entry.py +1 -1
- autocoder/plugins/token_helper_plugin.py +107 -7
- autocoder/run_context.py +9 -0
- autocoder/sdk/__init__.py +114 -81
- autocoder/sdk/cli/handlers.py +2 -1
- autocoder/sdk/cli/main.py +9 -2
- autocoder/sdk/cli/options.py +4 -3
- autocoder/sdk/core/auto_coder_core.py +7 -152
- autocoder/sdk/core/bridge.py +5 -4
- autocoder/sdk/models/options.py +8 -6
- autocoder/version.py +1 -1
- {auto_coder-0.1.399.dist-info → auto_coder-1.0.0.dist-info}/WHEEL +0 -0
- {auto_coder-0.1.399.dist-info → auto_coder-1.0.0.dist-info}/entry_points.txt +0 -0
- {auto_coder-0.1.399.dist-info → auto_coder-1.0.0.dist-info}/licenses/LICENSE +0 -0
- {auto_coder-0.1.399.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,
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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,
|
|
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,
|
|
55
|
+
UseRAGTool, ACModReadTool, ACModWriteTool, TodoReadTool,
|
|
56
|
+
TodoWriteTool,
|
|
77
57
|
TOOL_MODEL_MAP,
|
|
78
58
|
# Event Types
|
|
79
59
|
LLMOutputEvent, LLMThinkingEvent, ToolCallEvent,
|
|
@@ -98,19 +78,21 @@ TOOL_RESOLVER_MAP: Dict[Type[BaseTool], Type[BaseToolResolver]] = {
|
|
|
98
78
|
SearchFilesTool: SearchFilesToolResolver,
|
|
99
79
|
ListFilesTool: ListFilesToolResolver,
|
|
100
80
|
ListCodeDefinitionNamesTool: ListCodeDefinitionNamesToolResolver,
|
|
101
|
-
|
|
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
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
from autocoder.common.conversations import ConversationManagerConfig
|
|
91
|
+
from autocoder.common.conversations.get_conversation_manager import get_conversation_manager
|
|
92
|
+
from autocoder.common.pull_requests import create_pull_request
|
|
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
|
|
114
96
|
|
|
115
97
|
|
|
116
98
|
# --- Tool Display Customization is now handled by agentic_tool_display.py ---
|
|
@@ -195,6 +177,9 @@ class AgenticEdit:
|
|
|
195
177
|
# 对话管理器
|
|
196
178
|
self.conversation_config =conversation_config
|
|
197
179
|
self.conversation_manager = get_conversation_manager()
|
|
180
|
+
|
|
181
|
+
# Agentic 对话修剪器
|
|
182
|
+
self.agentic_pruner = AgenticConversationPruner(args=args, llm=self.context_prune_llm)
|
|
198
183
|
|
|
199
184
|
if self.conversation_config.action == "new":
|
|
200
185
|
conversation_id = self.conversation_manager.create_conversation(name=self.conversation_config.query or "New Conversation",
|
|
@@ -342,14 +327,37 @@ class AgenticEdit:
|
|
|
342
327
|
<requires_approval>true or false</requires_approval>
|
|
343
328
|
</execute_command>
|
|
344
329
|
|
|
345
|
-
##
|
|
346
|
-
Description: Request to retrieve information about a
|
|
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).
|
|
347
332
|
Parameters:
|
|
348
|
-
- path: (required) The
|
|
333
|
+
- path: (required) The AC Module directory path (directory containing .ac.mod.md file).
|
|
349
334
|
Usage:
|
|
350
|
-
<
|
|
351
|
-
<path>relative/or/absolute/
|
|
352
|
-
</
|
|
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>
|
|
353
361
|
|
|
354
362
|
## read_file
|
|
355
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.
|
|
@@ -453,7 +461,36 @@ class AgenticEdit:
|
|
|
453
461
|
<options>
|
|
454
462
|
Array of options here (optional), e.g. ["Option 1", "Option 2", "Option 3"]
|
|
455
463
|
</options>
|
|
456
|
-
</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>
|
|
457
494
|
|
|
458
495
|
## attempt_completion
|
|
459
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.
|
|
@@ -503,7 +540,7 @@ class AgenticEdit:
|
|
|
503
540
|
{%if rag_server_info %}
|
|
504
541
|
### RAG_SERVER_LIST
|
|
505
542
|
{{rag_server_info}}
|
|
506
|
-
{%endif%}
|
|
543
|
+
{%endif%}
|
|
507
544
|
|
|
508
545
|
# Tool Use Examples
|
|
509
546
|
|
|
@@ -577,7 +614,35 @@ class AgenticEdit:
|
|
|
577
614
|
<server_name>github</server_name>
|
|
578
615
|
<tool_name>create_issue</tool_name>
|
|
579
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>
|
|
580
|
-
</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>
|
|
581
646
|
|
|
582
647
|
# Tool Use Guidelines
|
|
583
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.
|
|
@@ -738,10 +803,10 @@ class AgenticEdit:
|
|
|
738
803
|
- **Combine multiple approaches** for comprehensive understanding
|
|
739
804
|
|
|
740
805
|
**Default workflow:**
|
|
741
|
-
1. `list_files` → understand structure
|
|
806
|
+
1. `list_files`(without recursively) → understand structure (if needed)
|
|
742
807
|
2. `grep` → find specific patterns/symbols
|
|
743
808
|
3. `read_file` → examine details
|
|
744
|
-
4.
|
|
809
|
+
4. Implement changes
|
|
745
810
|
5. `grep` → verify changes
|
|
746
811
|
|
|
747
812
|
# Comprehensive Workflow
|
|
@@ -807,13 +872,7 @@ class AgenticEdit:
|
|
|
807
872
|
|
|
808
873
|
More detail is on the EDITING FILES PART.
|
|
809
874
|
|
|
810
|
-
## Phase 5: Comprehensive Verification
|
|
811
|
-
|
|
812
|
-
**File System Verification**
|
|
813
|
-
<execute_command>
|
|
814
|
-
<command>ls -la newfile.* 2>/dev/null || echo "Expected new files not found"</command>
|
|
815
|
-
<requires_approval>false</requires_approval>
|
|
816
|
-
</execute_command>
|
|
875
|
+
## Phase 5: Comprehensive Verification
|
|
817
876
|
|
|
818
877
|
**Code Integration Verification**
|
|
819
878
|
<execute_command>
|
|
@@ -830,17 +889,7 @@ class AgenticEdit:
|
|
|
830
889
|
<execute_command>
|
|
831
890
|
<command>npm run lint 2>/dev/null || echo "Linting not configured"</command>
|
|
832
891
|
<requires_approval>false</requires_approval>
|
|
833
|
-
</execute_command>
|
|
834
|
-
|
|
835
|
-
<execute_command>
|
|
836
|
-
<command>npm test 2>/dev/null || echo "Testing not configured"</command>
|
|
837
|
-
<requires_approval>false</requires_approval>
|
|
838
|
-
</execute_command>
|
|
839
|
-
|
|
840
|
-
<execute_command>
|
|
841
|
-
<command>npm run build 2>/dev/null || echo "Build not configured"</command>
|
|
842
|
-
<requires_approval>false</requires_approval>
|
|
843
|
-
</execute_command>
|
|
892
|
+
</execute_command>
|
|
844
893
|
|
|
845
894
|
**Documentation & Comments**
|
|
846
895
|
- Verify that new functions/classes have appropriate documentation
|
|
@@ -878,6 +927,118 @@ class AgenticEdit:
|
|
|
878
927
|
|
|
879
928
|
====
|
|
880
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
|
+
|
|
881
1042
|
EDITING FILES
|
|
882
1043
|
|
|
883
1044
|
Before applying the editing techniques below, ensure you have followed the SEARCHING FILES methodology to fully understand the codebase context.
|
|
@@ -954,41 +1115,158 @@ class AgenticEdit:
|
|
|
954
1115
|
|
|
955
1116
|
====
|
|
956
1117
|
|
|
957
|
-
|
|
1118
|
+
AC MOD FILES
|
|
958
1119
|
|
|
959
|
-
#
|
|
1120
|
+
# AC Modules (.ac.mod.md)
|
|
960
1121
|
|
|
961
|
-
##
|
|
1122
|
+
## What is an AC Module?
|
|
962
1123
|
|
|
963
|
-
-
|
|
964
|
-
- This includes recent changes, important files, and their purposes
|
|
965
|
-
- 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.
|
|
966
1125
|
|
|
967
|
-
##
|
|
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
|
|
968
1133
|
|
|
969
|
-
|
|
970
|
-
- Do NOT use other tools like list_files to view this specialized context information
|
|
1134
|
+
## When to Use AC Modules
|
|
971
1135
|
|
|
972
|
-
|
|
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
|
+
|
|
1152
|
+
|
|
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>
|
|
1167
|
+
|
|
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]
|
|
1172
|
+
|
|
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
|
|
1184
|
+
```
|
|
1185
|
+
|
|
1186
|
+
## Quick Start
|
|
1187
|
+
|
|
1188
|
+
### Basic Usage
|
|
973
1189
|
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
1190
|
+
```python
|
|
1191
|
+
# Import necessary modules
|
|
1192
|
+
from [module_path] import [MainClassName], [HelperClassName]
|
|
977
1193
|
|
|
978
|
-
|
|
1194
|
+
# 1. Initialize configuration
|
|
1195
|
+
[Specific initialization code example]
|
|
979
1196
|
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
1197
|
+
# 2. Create instance
|
|
1198
|
+
[Instance creation code example]
|
|
1199
|
+
|
|
1200
|
+
# 3. Basic usage
|
|
1201
|
+
[Basic usage code example]
|
|
984
1202
|
```
|
|
985
1203
|
|
|
986
|
-
|
|
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]
|
|
1227
|
+
|
|
1228
|
+
## Mermaid File Dependency Graph
|
|
1229
|
+
[Main description of dependencies within the module]
|
|
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
|
+
```
|
|
987
1247
|
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
- Helps prioritize which files to examine in detail with tools like read_file, shell commands, or list_code_definition_names
|
|
1248
|
+
## Dependency Relationships
|
|
1249
|
+
Dependencies on other modules with .ac.mod.md files, simply shown as a relative path list, for example:
|
|
991
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
|
+
|
|
992
1270
|
====
|
|
993
1271
|
|
|
994
1272
|
CAPABILITIES
|
|
@@ -1050,7 +1328,7 @@ class AgenticEdit:
|
|
|
1050
1328
|
{% endfor %}
|
|
1051
1329
|
</user_rule_or_document_files>
|
|
1052
1330
|
|
|
1053
|
-
|
|
1331
|
+
You should decide based on the user's requirements whether to use the read_file tool to get the relevant files listed in index.md.
|
|
1054
1332
|
{% endif %}
|
|
1055
1333
|
|
|
1056
1334
|
|
|
@@ -1255,9 +1533,9 @@ class AgenticEdit:
|
|
|
1255
1533
|
|
|
1256
1534
|
self.current_conversations = conversations
|
|
1257
1535
|
|
|
1258
|
-
#
|
|
1536
|
+
# 计算初始对话窗口长度
|
|
1259
1537
|
conversation_str = json.dumps(conversations, ensure_ascii=False)
|
|
1260
|
-
current_tokens = count_tokens(conversation_str)
|
|
1538
|
+
current_tokens = count_tokens(conversation_str)
|
|
1261
1539
|
yield WindowLengthChangeEvent(tokens_used=current_tokens)
|
|
1262
1540
|
|
|
1263
1541
|
logger.info(
|
|
@@ -1289,12 +1567,12 @@ class AgenticEdit:
|
|
|
1289
1567
|
f"Starting LLM interaction cycle. History size: {len(conversations)}")
|
|
1290
1568
|
|
|
1291
1569
|
assistant_buffer = ""
|
|
1292
|
-
logger.info("Initializing stream chat with LLM")
|
|
1570
|
+
logger.info("Initializing stream chat with LLM")
|
|
1293
1571
|
|
|
1294
|
-
# ##
|
|
1572
|
+
# ## 实际请求大模型,并且我们会裁剪对话窗口长度
|
|
1295
1573
|
llm_response_gen = stream_chat_with_continue(
|
|
1296
1574
|
llm=self.llm,
|
|
1297
|
-
conversations=conversations,
|
|
1575
|
+
conversations=self.agentic_pruner.prune_conversations(deepcopy(conversations)),
|
|
1298
1576
|
llm_config={}, # Placeholder for future LLM configs
|
|
1299
1577
|
args=self.args
|
|
1300
1578
|
)
|
|
@@ -1920,513 +2198,183 @@ class AgenticEdit:
|
|
|
1920
2198
|
def apply_changes(self):
|
|
1921
2199
|
"""
|
|
1922
2200
|
Apply all tracked file changes to the original project directory.
|
|
1923
|
-
"""
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
1927
|
-
|
|
1928
|
-
|
|
1929
|
-
|
|
1930
|
-
|
|
1931
|
-
|
|
1932
|
-
|
|
1933
|
-
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
)
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
2201
|
+
"""
|
|
2202
|
+
if not self.args.skip_commit:
|
|
2203
|
+
try:
|
|
2204
|
+
file_name = os.path.basename(self.args.file)
|
|
2205
|
+
commit_result = git_utils.commit_changes(
|
|
2206
|
+
self.args.source_dir,
|
|
2207
|
+
f"{self.args.query}\nauto_coder_{file_name}",
|
|
2208
|
+
)
|
|
2209
|
+
|
|
2210
|
+
get_event_manager(self.args.event_file).write_result(
|
|
2211
|
+
EventContentCreator.create_result(
|
|
2212
|
+
content={
|
|
2213
|
+
"have_commit":commit_result.success,
|
|
2214
|
+
"commit_hash":commit_result.commit_hash,
|
|
2215
|
+
"diff_file_num":len(commit_result.changed_files),
|
|
2216
|
+
"event_file":self.args.event_file
|
|
2217
|
+
}), metadata=EventMetadata(
|
|
2218
|
+
action_file=self.args.file,
|
|
2219
|
+
is_streaming=False,
|
|
2220
|
+
path="/agent/edit/apply_changes",
|
|
2221
|
+
stream_out_type="/agent/edit").to_dict())
|
|
2222
|
+
|
|
2223
|
+
action_yml_file_manager = ActionYmlFileManager(
|
|
2224
|
+
self.args.source_dir)
|
|
2225
|
+
action_file_name = os.path.basename(self.args.file)
|
|
2226
|
+
add_updated_urls = []
|
|
2227
|
+
commit_result.changed_files
|
|
2228
|
+
for file in commit_result.changed_files:
|
|
2229
|
+
add_updated_urls.append(
|
|
2230
|
+
os.path.join(self.args.source_dir, file))
|
|
2231
|
+
|
|
2232
|
+
self.args.add_updated_urls = add_updated_urls
|
|
2233
|
+
update_yaml_success = action_yml_file_manager.update_yaml_field(
|
|
2234
|
+
action_file_name, "add_updated_urls", add_updated_urls)
|
|
2235
|
+
if not update_yaml_success:
|
|
2236
|
+
self.printer.print_in_terminal(
|
|
2237
|
+
"yaml_save_error", style="red", yaml_file=action_file_name)
|
|
2238
|
+
|
|
2239
|
+
if self.args.enable_active_context:
|
|
2240
|
+
active_context_manager = ActiveContextManager(
|
|
2241
|
+
self.llm, self.args.source_dir)
|
|
2242
|
+
task_id = active_context_manager.process_changes(
|
|
2243
|
+
self.args)
|
|
2244
|
+
self.printer.print_in_terminal("active_context_background_task",
|
|
2245
|
+
style="blue",
|
|
2246
|
+
task_id=task_id)
|
|
2247
|
+
git_utils.print_commit_info(commit_result=commit_result)
|
|
2248
|
+
|
|
2249
|
+
# 检查是否需要创建 Pull Request
|
|
2250
|
+
if self.conversation_config and self.conversation_config.pull_request:
|
|
2251
|
+
self._create_pull_request(commit_result)
|
|
1960
2252
|
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
for file in commit_result.changed_files:
|
|
1967
|
-
add_updated_urls.append(
|
|
1968
|
-
os.path.join(self.args.source_dir, file))
|
|
1969
|
-
|
|
1970
|
-
self.args.add_updated_urls = add_updated_urls
|
|
1971
|
-
update_yaml_success = action_yml_file_manager.update_yaml_field(
|
|
1972
|
-
action_file_name, "add_updated_urls", add_updated_urls)
|
|
1973
|
-
if not update_yaml_success:
|
|
1974
|
-
self.printer.print_in_terminal(
|
|
1975
|
-
"yaml_save_error", style="red", yaml_file=action_file_name)
|
|
1976
|
-
|
|
1977
|
-
if self.args.enable_active_context:
|
|
1978
|
-
active_context_manager = ActiveContextManager(
|
|
1979
|
-
self.llm, self.args.source_dir)
|
|
1980
|
-
task_id = active_context_manager.process_changes(
|
|
1981
|
-
self.args)
|
|
1982
|
-
self.printer.print_in_terminal("active_context_background_task",
|
|
1983
|
-
style="blue",
|
|
1984
|
-
task_id=task_id)
|
|
1985
|
-
git_utils.print_commit_info(commit_result=commit_result)
|
|
1986
|
-
except Exception as e:
|
|
1987
|
-
self.printer.print_str_in_terminal(
|
|
1988
|
-
self.git_require_msg(
|
|
1989
|
-
source_dir=self.args.source_dir, error=str(e)),
|
|
1990
|
-
style="red"
|
|
1991
|
-
)
|
|
2253
|
+
except Exception as e:
|
|
2254
|
+
self.printer.print_str_in_terminal(
|
|
2255
|
+
str(e),
|
|
2256
|
+
style="red"
|
|
2257
|
+
)
|
|
1992
2258
|
|
|
1993
|
-
|
|
1994
|
-
def run_in_terminal(self, request: AgenticEditRequest):
|
|
2259
|
+
def _create_pull_request(self, commit_result):
|
|
1995
2260
|
"""
|
|
1996
|
-
|
|
1997
|
-
the interaction streamingly in the terminal using Rich.
|
|
1998
|
-
"""
|
|
1999
|
-
import json
|
|
2000
|
-
console = Console()
|
|
2001
|
-
project_name = os.path.basename(os.path.abspath(self.args.source_dir))
|
|
2002
|
-
|
|
2003
|
-
if self.conversation_config.action == "list":
|
|
2004
|
-
conversations = self.conversation_manager.list_conversations()
|
|
2005
|
-
# 只保留 conversation_id 和 name 字段
|
|
2006
|
-
filtered_conversations = []
|
|
2007
|
-
for conv in conversations:
|
|
2008
|
-
filtered_conv = {
|
|
2009
|
-
"conversation_id": conv.get("conversation_id"),
|
|
2010
|
-
"name": conv.get("name")
|
|
2011
|
-
}
|
|
2012
|
-
filtered_conversations.append(filtered_conv)
|
|
2013
|
-
|
|
2014
|
-
# 格式化 JSON 输出,使用 JSON 格式渲染而不是 Markdown
|
|
2015
|
-
json_str = json.dumps(filtered_conversations, ensure_ascii=False, indent=4)
|
|
2016
|
-
console.print(Panel(json_str,
|
|
2017
|
-
title="🏁 Task Completion", border_style="green", title_align="left"))
|
|
2018
|
-
return
|
|
2261
|
+
创建 Pull Request(如果配置启用)
|
|
2019
2262
|
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
title="🏁 Task Completion", border_style="green", title_align="left"))
|
|
2024
|
-
return
|
|
2025
|
-
|
|
2026
|
-
console.rule(f"[bold cyan]Starting Agentic Edit: {project_name}[/]")
|
|
2027
|
-
console.print(Panel(
|
|
2028
|
-
f"[bold]{get_message('/agent/edit/user_query')}:[/bold]\n{request.user_input}", title=get_message("/agent/edit/objective"), border_style="blue"))
|
|
2029
|
-
|
|
2030
|
-
# 用于累计TokenUsageEvent数据
|
|
2031
|
-
accumulated_token_usage = {
|
|
2032
|
-
"model_name": "",
|
|
2033
|
-
"input_tokens": 0,
|
|
2034
|
-
"output_tokens": 0,
|
|
2035
|
-
"input_cost": 0.0,
|
|
2036
|
-
"output_cost": 0.0
|
|
2037
|
-
}
|
|
2038
|
-
|
|
2263
|
+
Args:
|
|
2264
|
+
commit_result: Git commit 结果对象
|
|
2265
|
+
"""
|
|
2039
2266
|
try:
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
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}")
|
|
2067
|
-
|
|
2068
|
-
# 累计token使用情况
|
|
2069
|
-
accumulated_token_usage["model_name"] = model_name
|
|
2070
|
-
accumulated_token_usage["input_tokens"] += last_meta.input_tokens_count
|
|
2071
|
-
accumulated_token_usage["output_tokens"] += last_meta.generated_tokens_count
|
|
2072
|
-
accumulated_token_usage["input_cost"] += input_cost
|
|
2073
|
-
accumulated_token_usage["output_cost"] += output_cost
|
|
2074
|
-
|
|
2075
|
-
elif isinstance(event, WindowLengthChangeEvent):
|
|
2076
|
-
# 显示当前会话的token数量
|
|
2077
|
-
logger.info(f"当前会话总 tokens: {event.tokens_used}")
|
|
2078
|
-
console.print(f"[dim]当前会话总 tokens: {event.tokens_used}[/dim]")
|
|
2079
|
-
|
|
2080
|
-
elif isinstance(event, LLMThinkingEvent):
|
|
2081
|
-
# Render thinking within a less prominent style, maybe grey?
|
|
2082
|
-
console.print(f"[grey50]{event.text}[/grey50]", end="")
|
|
2083
|
-
elif isinstance(event, LLMOutputEvent):
|
|
2084
|
-
# Print regular LLM output, potentially as markdown if needed later
|
|
2085
|
-
console.print(event.text, end="")
|
|
2086
|
-
elif isinstance(event, ToolCallEvent):
|
|
2087
|
-
# Skip displaying AttemptCompletionTool's tool call
|
|
2088
|
-
if isinstance(event.tool, AttemptCompletionTool):
|
|
2089
|
-
continue # Do not display AttemptCompletionTool tool call
|
|
2090
|
-
|
|
2091
|
-
tool_name = type(event.tool).__name__
|
|
2092
|
-
# Use the new internationalized display function
|
|
2093
|
-
display_content = get_tool_display_message(event.tool)
|
|
2094
|
-
console.print(Panel(
|
|
2095
|
-
display_content, title=f"🛠️ Action: {tool_name}", border_style="blue", title_align="left"))
|
|
2096
|
-
|
|
2097
|
-
elif isinstance(event, ToolResultEvent):
|
|
2098
|
-
# Skip displaying AttemptCompletionTool's result
|
|
2099
|
-
if event.tool_name == "AttemptCompletionTool":
|
|
2100
|
-
continue # Do not display AttemptCompletionTool result
|
|
2101
|
-
|
|
2102
|
-
if event.tool_name == "PlanModeRespondTool":
|
|
2103
|
-
continue
|
|
2104
|
-
|
|
2105
|
-
result = event.result
|
|
2106
|
-
title = f"✅ Tool Result: {event.tool_name}" if result.success else f"❌ Tool Result: {event.tool_name}"
|
|
2107
|
-
border_style = "green" if result.success else "red"
|
|
2108
|
-
base_content = f"[bold]Status:[/bold] {'Success' if result.success else 'Failure'}\n"
|
|
2109
|
-
base_content += f"[bold]Message:[/bold] {result.message}\n"
|
|
2110
|
-
|
|
2111
|
-
def _format_content(content):
|
|
2112
|
-
if len(content) > 200:
|
|
2113
|
-
return f"{content[:100]}\n...\n{content[-100:]}"
|
|
2114
|
-
else:
|
|
2115
|
-
return content
|
|
2116
|
-
|
|
2117
|
-
# Prepare panel for base info first
|
|
2118
|
-
panel_content = [base_content]
|
|
2119
|
-
syntax_content = None
|
|
2267
|
+
# 获取当前分支名
|
|
2268
|
+
current_branch = git_utils.get_current_branch(self.args.source_dir)
|
|
2269
|
+
if not current_branch:
|
|
2270
|
+
logger.warning(get_message("/agent/edit/pull_request/branch_name_failed"))
|
|
2271
|
+
return
|
|
2272
|
+
|
|
2273
|
+
# 准备 PR 标题和描述
|
|
2274
|
+
query = self.args.query or get_message("/agent/edit/pull_request/default_query")
|
|
2275
|
+
pr_title = get_message_with_format("/agent/edit/pull_request/title", query="{query[0:40]}...")
|
|
2276
|
+
|
|
2277
|
+
# 构建 PR 描述
|
|
2278
|
+
file_list = ""
|
|
2279
|
+
if commit_result.changed_files:
|
|
2280
|
+
for file_path in commit_result.changed_files:
|
|
2281
|
+
file_list += f"- `{file_path}`\n"
|
|
2282
|
+
|
|
2283
|
+
pr_description = get_message_with_format(
|
|
2284
|
+
"/agent/edit/pull_request/description",
|
|
2285
|
+
query=query,
|
|
2286
|
+
file_count=len(commit_result.changed_files or []),
|
|
2287
|
+
commit_hash=commit_result.commit_hash,
|
|
2288
|
+
file_list=file_list.strip(),
|
|
2289
|
+
source_branch=current_branch,
|
|
2290
|
+
target_branch="main",
|
|
2291
|
+
timestamp=time.strftime('%Y-%m-%d %H:%M:%S')
|
|
2292
|
+
)
|
|
2120
2293
|
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
elif ".ts" in event.result.message:
|
|
2140
|
-
lexer = "typescript"
|
|
2141
|
-
elif ".html" in event.result.message:
|
|
2142
|
-
lexer = "html"
|
|
2143
|
-
elif ".css" in event.result.message:
|
|
2144
|
-
lexer = "css"
|
|
2145
|
-
elif ".json" in event.result.message:
|
|
2146
|
-
lexer = "json"
|
|
2147
|
-
elif ".xml" in event.result.message:
|
|
2148
|
-
lexer = "xml"
|
|
2149
|
-
elif ".md" in event.result.message:
|
|
2150
|
-
lexer = "markdown"
|
|
2151
|
-
else:
|
|
2152
|
-
lexer = "text" # Fallback lexer
|
|
2153
|
-
elif event.tool_name == "ExecuteCommandTool":
|
|
2154
|
-
lexer = "shell"
|
|
2155
|
-
else:
|
|
2156
|
-
lexer = "text"
|
|
2157
|
-
|
|
2158
|
-
syntax_content = Syntax(
|
|
2159
|
-
_format_content(result.content), lexer, theme="default", line_numbers=True)
|
|
2160
|
-
else:
|
|
2161
|
-
content_str = str(result.content)
|
|
2162
|
-
# Append simple string content directly
|
|
2163
|
-
panel_content.append(
|
|
2164
|
-
_format_content(content_str))
|
|
2165
|
-
except Exception as e:
|
|
2166
|
-
logger.warning(
|
|
2167
|
-
f"Error formatting tool result content: {e}")
|
|
2168
|
-
panel_content.append(
|
|
2169
|
-
# Fallback
|
|
2170
|
-
_format_content(str(result.content)))
|
|
2171
|
-
|
|
2172
|
-
# Print the base info panel
|
|
2173
|
-
console.print(Panel("\n".join(
|
|
2174
|
-
panel_content), title=title, border_style=border_style, title_align="left"))
|
|
2175
|
-
# Print syntax highlighted content separately if it exists
|
|
2176
|
-
if syntax_content:
|
|
2177
|
-
console.print(syntax_content)
|
|
2178
|
-
elif isinstance(event, PlanModeRespondEvent):
|
|
2179
|
-
console.print(Panel(Markdown(event.completion.response),
|
|
2180
|
-
title="🏁 Task Completion", border_style="green", title_align="left"))
|
|
2181
|
-
|
|
2182
|
-
elif isinstance(event, CompletionEvent):
|
|
2183
|
-
# 在这里完成实际合并
|
|
2184
|
-
try:
|
|
2185
|
-
self.apply_changes()
|
|
2186
|
-
except Exception as e:
|
|
2187
|
-
logger.exception(
|
|
2188
|
-
f"Error merging shadow changes to project: {e}")
|
|
2189
|
-
|
|
2190
|
-
console.print(Panel(Markdown(event.completion.result),
|
|
2191
|
-
title="🏁 Task Completion", border_style="green", title_align="left"))
|
|
2192
|
-
if event.completion.command:
|
|
2193
|
-
console.print(
|
|
2194
|
-
f"[dim]Suggested command:[/dim] [bold cyan]{event.completion.command}[/]")
|
|
2195
|
-
elif isinstance(event, ErrorEvent):
|
|
2196
|
-
console.print(Panel(
|
|
2197
|
-
f"[bold red]Error:[/bold red] {event.message}", title="🔥 Error", border_style="red", title_align="left"))
|
|
2198
|
-
|
|
2199
|
-
time.sleep(0.1) # Small delay for better visual flow
|
|
2200
|
-
|
|
2201
|
-
# 在处理完所有事件后打印累计的token使用情况
|
|
2202
|
-
if accumulated_token_usage["input_tokens"] > 0:
|
|
2203
|
-
self.printer.print_in_terminal(
|
|
2204
|
-
"code_generation_complete",
|
|
2205
|
-
duration=0.0,
|
|
2206
|
-
input_tokens=accumulated_token_usage["input_tokens"],
|
|
2207
|
-
output_tokens=accumulated_token_usage["output_tokens"],
|
|
2208
|
-
input_cost=accumulated_token_usage["input_cost"],
|
|
2209
|
-
output_cost=accumulated_token_usage["output_cost"],
|
|
2210
|
-
speed=0.0,
|
|
2211
|
-
model_names=accumulated_token_usage["model_name"],
|
|
2212
|
-
sampling_count=1
|
|
2294
|
+
# 创建 Pull Request
|
|
2295
|
+
logger.info(get_message_with_format("/agent/edit/pull_request/creating", title=pr_title))
|
|
2296
|
+
|
|
2297
|
+
result = create_pull_request(
|
|
2298
|
+
repo_path=self.args.source_dir,
|
|
2299
|
+
title=pr_title,
|
|
2300
|
+
description=pr_description,
|
|
2301
|
+
)
|
|
2302
|
+
|
|
2303
|
+
if result.success:
|
|
2304
|
+
logger.info(get_message("/agent/edit/pull_request/success"))
|
|
2305
|
+
logger.info(f"PR URL: {result.pr_url}")
|
|
2306
|
+
logger.info(f"PR 编号: {result.pr_number}")
|
|
2307
|
+
|
|
2308
|
+
# 打印成功信息到终端
|
|
2309
|
+
self.printer.print_str_in_terminal(
|
|
2310
|
+
get_message("/agent/edit/pull_request/success"),
|
|
2311
|
+
style="green"
|
|
2213
2312
|
)
|
|
2313
|
+
self.printer.print_str_in_terminal(f"PR URL: {result.pr_url}")
|
|
2314
|
+
self.printer.print_str_in_terminal(f"PR 编号: {result.pr_number}")
|
|
2214
2315
|
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2316
|
+
# 写入事件日志
|
|
2317
|
+
get_event_manager(self.args.event_file).write_result(
|
|
2318
|
+
EventContentCreator.create_result(
|
|
2319
|
+
content={
|
|
2320
|
+
"success": True,
|
|
2321
|
+
"pr_url": result.pr_url,
|
|
2322
|
+
"pr_number": result.pr_number,
|
|
2323
|
+
"source_branch": current_branch,
|
|
2324
|
+
"target_branch": "main",
|
|
2325
|
+
"platform": result.platform.value if result.platform else "unknown"
|
|
2326
|
+
}),
|
|
2327
|
+
metadata=EventMetadata(
|
|
2328
|
+
action_file=self.args.file,
|
|
2329
|
+
is_streaming=False,
|
|
2330
|
+
path="/agent/edit/pull_request_created",
|
|
2331
|
+
stream_out_type="/agent/edit"
|
|
2332
|
+
).to_dict()
|
|
2228
2333
|
)
|
|
2229
2334
|
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2335
|
+
else:
|
|
2336
|
+
error_msg = get_message_with_format("/agent/edit/pull_request/failed", error=result.error_message)
|
|
2337
|
+
logger.error(error_msg)
|
|
2338
|
+
|
|
2339
|
+
# 打印错误信息到终端
|
|
2340
|
+
self.printer.print_str_in_terminal(error_msg, style="red")
|
|
2341
|
+
|
|
2342
|
+
# 写入错误事件日志
|
|
2343
|
+
get_event_manager(self.args.event_file).write_error(
|
|
2344
|
+
EventContentCreator.create_error(
|
|
2345
|
+
error_code="PR_CREATION_FAILED",
|
|
2346
|
+
error_message=result.error_message,
|
|
2347
|
+
details={
|
|
2348
|
+
"source_branch": current_branch,
|
|
2349
|
+
"target_branch": "main"
|
|
2350
|
+
}
|
|
2351
|
+
).to_dict(),
|
|
2352
|
+
metadata=EventMetadata(
|
|
2353
|
+
action_file=self.args.file,
|
|
2354
|
+
is_streaming=False,
|
|
2355
|
+
path="/agent/edit/pull_request_error",
|
|
2356
|
+
stream_out_type="/agent/edit"
|
|
2357
|
+
).to_dict()
|
|
2358
|
+
)
|
|
2243
2359
|
|
|
2244
2360
|
except Exception as e:
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
event_stream = self.analyze(request)
|
|
2260
|
-
for agent_event in event_stream:
|
|
2261
|
-
content = None
|
|
2262
|
-
metadata = EventMetadata(
|
|
2361
|
+
error_msg = get_message_with_format("/agent/edit/pull_request/exception", error=str(e))
|
|
2362
|
+
logger.exception(error_msg)
|
|
2363
|
+
|
|
2364
|
+
# 打印异常信息到终端
|
|
2365
|
+
self.printer.print_str_in_terminal(error_msg, style="red")
|
|
2366
|
+
|
|
2367
|
+
# 写入异常事件日志
|
|
2368
|
+
get_event_manager(self.args.event_file).write_error(
|
|
2369
|
+
EventContentCreator.create_error(
|
|
2370
|
+
error_code="PR_CREATION_EXCEPTION",
|
|
2371
|
+
error_message=get_message_with_format("/agent/edit/pull_request/exception", error=str(e)),
|
|
2372
|
+
details={"exception_type": type(e).__name__}
|
|
2373
|
+
).to_dict(),
|
|
2374
|
+
metadata=EventMetadata(
|
|
2263
2375
|
action_file=self.args.file,
|
|
2264
2376
|
is_streaming=False,
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
content=agent_event.text)
|
|
2270
|
-
metadata.is_streaming = True
|
|
2271
|
-
metadata.path = "/agent/edit/thinking"
|
|
2272
|
-
event_manager.write_stream(
|
|
2273
|
-
content=content.to_dict(), metadata=metadata.to_dict())
|
|
2274
|
-
elif isinstance(agent_event, LLMOutputEvent):
|
|
2275
|
-
content = EventContentCreator.create_stream_content(
|
|
2276
|
-
content=agent_event.text)
|
|
2277
|
-
metadata.is_streaming = True
|
|
2278
|
-
metadata.path = "/agent/edit/output"
|
|
2279
|
-
event_manager.write_stream(content=content.to_dict(),
|
|
2280
|
-
metadata=metadata.to_dict())
|
|
2281
|
-
elif isinstance(agent_event, ToolCallEvent):
|
|
2282
|
-
tool_name = type(agent_event.tool).__name__
|
|
2283
|
-
metadata.path = "/agent/edit/tool/call"
|
|
2284
|
-
content = EventContentCreator.create_result(
|
|
2285
|
-
content={
|
|
2286
|
-
"tool_name": tool_name,
|
|
2287
|
-
**agent_event.tool.model_dump()
|
|
2288
|
-
},
|
|
2289
|
-
metadata={}
|
|
2290
|
-
)
|
|
2291
|
-
event_manager.write_result(
|
|
2292
|
-
content=content.to_dict(), metadata=metadata.to_dict())
|
|
2293
|
-
elif isinstance(agent_event, ToolResultEvent):
|
|
2294
|
-
metadata.path = "/agent/edit/tool/result"
|
|
2295
|
-
content = EventContentCreator.create_result(
|
|
2296
|
-
content={
|
|
2297
|
-
"tool_name": agent_event.tool_name,
|
|
2298
|
-
**agent_event.result.model_dump()
|
|
2299
|
-
},
|
|
2300
|
-
metadata={}
|
|
2301
|
-
)
|
|
2302
|
-
event_manager.write_result(
|
|
2303
|
-
content=content.to_dict(), metadata=metadata.to_dict())
|
|
2304
|
-
elif isinstance(agent_event, PlanModeRespondEvent):
|
|
2305
|
-
metadata.path = "/agent/edit/plan_mode_respond"
|
|
2306
|
-
content = EventContentCreator.create_markdown_result(
|
|
2307
|
-
content=agent_event.completion.response,
|
|
2308
|
-
metadata={}
|
|
2309
|
-
)
|
|
2310
|
-
event_manager.write_result(
|
|
2311
|
-
content=content.to_dict(), metadata=metadata.to_dict())
|
|
2312
|
-
|
|
2313
|
-
elif isinstance(agent_event, TokenUsageEvent):
|
|
2314
|
-
last_meta: SingleOutputMeta = agent_event.usage
|
|
2315
|
-
# Get model info for pricing
|
|
2316
|
-
from autocoder.utils import llms as llm_utils
|
|
2317
|
-
model_name = ",".join(llm_utils.get_llm_names(self.llm))
|
|
2318
|
-
model_info = llm_utils.get_model_info(
|
|
2319
|
-
model_name, self.args.product_mode) or {}
|
|
2320
|
-
input_price = model_info.get(
|
|
2321
|
-
"input_price", 0.0) if model_info else 0.0
|
|
2322
|
-
output_price = model_info.get(
|
|
2323
|
-
"output_price", 0.0) if model_info else 0.0
|
|
2324
|
-
|
|
2325
|
-
# Calculate costs
|
|
2326
|
-
input_cost = (last_meta.input_tokens_count *
|
|
2327
|
-
input_price) / 1000000 # Convert to millions
|
|
2328
|
-
# Convert to millions
|
|
2329
|
-
output_cost = (
|
|
2330
|
-
last_meta.generated_tokens_count * output_price) / 1000000
|
|
2331
|
-
|
|
2332
|
-
# 添加日志记录
|
|
2333
|
-
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}")
|
|
2334
|
-
|
|
2335
|
-
# 直接将每次的 TokenUsageEvent 写入到事件中
|
|
2336
|
-
metadata.path = "/agent/edit/token_usage"
|
|
2337
|
-
content = EventContentCreator.create_result(content=EventContentCreator.ResultTokenStatContent(
|
|
2338
|
-
model_name=model_name,
|
|
2339
|
-
elapsed_time=0.0,
|
|
2340
|
-
first_token_time=last_meta.first_token_time,
|
|
2341
|
-
input_tokens=last_meta.input_tokens_count,
|
|
2342
|
-
output_tokens=last_meta.generated_tokens_count,
|
|
2343
|
-
input_cost=input_cost,
|
|
2344
|
-
output_cost=output_cost
|
|
2345
|
-
).to_dict())
|
|
2346
|
-
event_manager.write_result(content=content.to_dict(), metadata=metadata.to_dict())
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
elif isinstance(agent_event, CompletionEvent):
|
|
2350
|
-
# 在这里完成实际合并
|
|
2351
|
-
try:
|
|
2352
|
-
self.apply_changes()
|
|
2353
|
-
except Exception as e:
|
|
2354
|
-
logger.exception(
|
|
2355
|
-
f"Error merging shadow changes to project: {e}")
|
|
2356
|
-
|
|
2357
|
-
metadata.path = "/agent/edit/completion"
|
|
2358
|
-
content = EventContentCreator.create_completion(
|
|
2359
|
-
success_code="AGENT_COMPLETE",
|
|
2360
|
-
success_message="Agent attempted task completion.",
|
|
2361
|
-
result={
|
|
2362
|
-
"response": agent_event.completion.result
|
|
2363
|
-
}
|
|
2364
|
-
)
|
|
2365
|
-
event_manager.write_completion(
|
|
2366
|
-
content=content.to_dict(), metadata=metadata.to_dict())
|
|
2367
|
-
elif isinstance(agent_event, WindowLengthChangeEvent):
|
|
2368
|
-
# 处理窗口长度变化事件
|
|
2369
|
-
metadata.path = "/agent/edit/window_length_change"
|
|
2370
|
-
content = EventContentCreator.create_result(
|
|
2371
|
-
content={
|
|
2372
|
-
"tokens_used": agent_event.tokens_used
|
|
2373
|
-
},
|
|
2374
|
-
metadata={}
|
|
2375
|
-
)
|
|
2376
|
-
event_manager.write_result(
|
|
2377
|
-
content=content.to_dict(), metadata=metadata.to_dict())
|
|
2378
|
-
|
|
2379
|
-
# 记录日志
|
|
2380
|
-
logger.info(f"当前会话总 tokens: {agent_event.tokens_used}")
|
|
2381
|
-
|
|
2382
|
-
elif isinstance(agent_event, ConversationIdEvent):
|
|
2383
|
-
metadata.path = "/agent/edit/conversation_id"
|
|
2384
|
-
content = EventContentCreator.create_result(
|
|
2385
|
-
content={
|
|
2386
|
-
"conversation_id": agent_event.conversation_id
|
|
2387
|
-
},
|
|
2388
|
-
metadata={}
|
|
2389
|
-
)
|
|
2390
|
-
event_manager.write_result(content=content.to_dict(), metadata=metadata.to_dict())
|
|
2391
|
-
|
|
2392
|
-
elif isinstance(agent_event, ErrorEvent):
|
|
2393
|
-
metadata.path = "/agent/edit/error"
|
|
2394
|
-
content = EventContentCreator.create_error(
|
|
2395
|
-
error_code="AGENT_ERROR",
|
|
2396
|
-
error_message=agent_event.message,
|
|
2397
|
-
details={"agent_event_type": "ErrorEvent"}
|
|
2398
|
-
)
|
|
2399
|
-
event_manager.write_error(
|
|
2400
|
-
content=content.to_dict(), metadata=metadata.to_dict())
|
|
2401
|
-
else:
|
|
2402
|
-
metadata.path = "/agent/edit/error"
|
|
2403
|
-
logger.warning(
|
|
2404
|
-
f"Unhandled agent event type: {type(agent_event)}")
|
|
2405
|
-
content = EventContentCreator.create_error(
|
|
2406
|
-
error_code="AGENT_ERROR",
|
|
2407
|
-
error_message=f"Unhandled agent event type: {type(agent_event)}",
|
|
2408
|
-
details={"agent_event_type": type(
|
|
2409
|
-
agent_event).__name__}
|
|
2410
|
-
)
|
|
2411
|
-
event_manager.write_error(
|
|
2412
|
-
content=content.to_dict(), metadata=metadata.to_dict())
|
|
2413
|
-
|
|
2414
|
-
except Exception as e:
|
|
2415
|
-
logger.exception(
|
|
2416
|
-
"An unexpected error occurred during agent execution:")
|
|
2417
|
-
metadata = EventMetadata(
|
|
2418
|
-
action_file=self.args.file,
|
|
2419
|
-
is_streaming=False,
|
|
2420
|
-
stream_out_type="/agent/edit/error")
|
|
2421
|
-
|
|
2422
|
-
# 发送累计的TokenUsageEvent数据(在错误情况下也需要发送)
|
|
2423
|
-
|
|
2424
|
-
error_content = EventContentCreator.create_error(
|
|
2425
|
-
error_code="AGENT_FATAL_ERROR",
|
|
2426
|
-
error_message=f"An unexpected error occurred: {str(e)}",
|
|
2427
|
-
details={"exception_type": type(e).__name__}
|
|
2428
|
-
)
|
|
2429
|
-
event_manager.write_error(
|
|
2430
|
-
content=error_content.to_dict(), metadata=metadata.to_dict())
|
|
2431
|
-
# Re-raise the exception if needed, or handle appropriately
|
|
2432
|
-
raise e
|
|
2377
|
+
path="/agent/edit/pull_request_exception",
|
|
2378
|
+
stream_out_type="/agent/edit"
|
|
2379
|
+
).to_dict()
|
|
2380
|
+
)
|