1
1
"""Langchain tools for workspace operations."""
2
2
3
3
from collections .abc import Callable
4
- from typing import Annotated , ClassVar , Literal , Optional
4
+ from typing import ClassVar , Literal
5
5
6
- from langchain_core .messages import ToolMessage
7
- from langchain_core .tools import InjectedToolCallId
8
6
from langchain_core .tools .base import BaseTool
9
7
from pydantic import BaseModel , Field
10
8
@@ -54,11 +52,10 @@ class ViewFileInput(BaseModel):
54
52
"""Input for viewing a file."""
55
53
56
54
filepath : str = Field (..., description = "Path to the file relative to workspace root" )
57
- start_line : Optional [int ] = Field (None , description = "Starting line number to view (1-indexed, inclusive)" )
58
- end_line : Optional [int ] = Field (None , description = "Ending line number to view (1-indexed, inclusive)" )
59
- max_lines : Optional [int ] = Field (None , description = "Maximum number of lines to view at once, defaults to 250" )
60
- line_numbers : Optional [bool ] = Field (True , description = "If True, add line numbers to the content (1-indexed)" )
61
- tool_call_id : Annotated [str , InjectedToolCallId ]
55
+ start_line : int | None = Field (None , description = "Starting line number to view (1-indexed, inclusive)" )
56
+ end_line : int | None = Field (None , description = "Ending line number to view (1-indexed, inclusive)" )
57
+ max_lines : int | None = Field (None , description = "Maximum number of lines to view at once, defaults to 250" )
58
+ line_numbers : bool | None = Field (True , description = "If True, add line numbers to the content (1-indexed)" )
62
59
63
60
64
61
class ViewFileTool (BaseTool ):
@@ -76,13 +73,12 @@ def __init__(self, codebase: Codebase) -> None:
76
73
77
74
def _run (
78
75
self ,
79
- tool_call_id : str ,
80
76
filepath : str ,
81
- start_line : Optional [ int ] = None ,
82
- end_line : Optional [ int ] = None ,
83
- max_lines : Optional [ int ] = None ,
84
- line_numbers : Optional [ bool ] = True ,
85
- ) -> ToolMessage :
77
+ start_line : int | None = None ,
78
+ end_line : int | None = None ,
79
+ max_lines : int | None = None ,
80
+ line_numbers : bool | None = True ,
81
+ ) -> str :
86
82
result = view_file (
87
83
self .codebase ,
88
84
filepath ,
@@ -92,15 +88,14 @@ def _run(
92
88
max_lines = max_lines if max_lines is not None else 250 ,
93
89
)
94
90
95
- return result .render (tool_call_id )
91
+ return result .render ()
96
92
97
93
98
94
class ListDirectoryInput (BaseModel ):
99
95
"""Input for listing directory contents."""
100
96
101
97
dirpath : str = Field (default = "./" , description = "Path to directory relative to workspace root" )
102
98
depth : int = Field (default = 1 , description = "How deep to traverse. Use -1 for unlimited depth." )
103
- tool_call_id : Annotated [str , InjectedToolCallId ]
104
99
105
100
106
101
class ListDirectoryTool (BaseTool ):
@@ -114,9 +109,9 @@ class ListDirectoryTool(BaseTool):
114
109
def __init__ (self , codebase : Codebase ) -> None :
115
110
super ().__init__ (codebase = codebase )
116
111
117
- def _run (self , tool_call_id : str , dirpath : str = "./" , depth : int = 1 ) -> ToolMessage :
112
+ def _run (self , dirpath : str = "./" , depth : int = 1 ) -> str :
118
113
result = list_directory (self .codebase , dirpath , depth )
119
- return result .render (tool_call_id )
114
+ return result .render ()
120
115
121
116
122
117
class SearchInput (BaseModel ):
@@ -131,7 +126,6 @@ class SearchInput(BaseModel):
131
126
page : int = Field (default = 1 , description = "Page number to return (1-based, default: 1)" )
132
127
files_per_page : int = Field (default = 10 , description = "Number of files to return per page (default: 10)" )
133
128
use_regex : bool = Field (default = False , description = "Whether to treat query as a regex pattern (default: False)" )
134
- tool_call_id : Annotated [str , InjectedToolCallId ]
135
129
136
130
137
131
class SearchTool (BaseTool ):
@@ -145,17 +139,16 @@ class SearchTool(BaseTool):
145
139
def __init__ (self , codebase : Codebase ) -> None :
146
140
super ().__init__ (codebase = codebase )
147
141
148
- def _run (self , tool_call_id : str , query : str , file_extensions : Optional [ list [str ]] = None , page : int = 1 , files_per_page : int = 10 , use_regex : bool = False ) -> ToolMessage :
142
+ def _run (self , query : str , file_extensions : list [str ] | None = None , page : int = 1 , files_per_page : int = 10 , use_regex : bool = False ) -> str :
149
143
result = search (self .codebase , query , file_extensions = file_extensions , page = page , files_per_page = files_per_page , use_regex = use_regex )
150
- return result .render (tool_call_id )
144
+ return result .render ()
151
145
152
146
153
147
class EditFileInput (BaseModel ):
154
148
"""Input for editing a file."""
155
149
156
150
filepath : str = Field (..., description = "Path to the file to edit" )
157
151
content : str = Field (..., description = "New content for the file" )
158
- tool_call_id : Annotated [str , InjectedToolCallId ]
159
152
160
153
161
154
class EditFileTool (BaseTool ):
@@ -188,9 +181,9 @@ class EditFileTool(BaseTool):
188
181
def __init__ (self , codebase : Codebase ) -> None :
189
182
super ().__init__ (codebase = codebase )
190
183
191
- def _run (self , filepath : str , content : str , tool_call_id : str ) -> str :
184
+ def _run (self , filepath : str , content : str ) -> str :
192
185
result = edit_file (self .codebase , filepath , content )
193
- return result .render (tool_call_id )
186
+ return result .render ()
194
187
195
188
196
189
class CreateFileInput (BaseModel ):
@@ -347,7 +340,6 @@ class SemanticEditInput(BaseModel):
347
340
edit_content : str = Field (..., description = FILE_EDIT_PROMPT )
348
341
start : int = Field (default = 1 , description = "Starting line number (1-indexed, inclusive). Default is 1." )
349
342
end : int = Field (default = - 1 , description = "Ending line number (1-indexed, inclusive). Default is -1 (end of file)." )
350
- tool_call_id : Annotated [str , InjectedToolCallId ]
351
343
352
344
353
345
class SemanticEditTool (BaseTool ):
@@ -361,10 +353,10 @@ class SemanticEditTool(BaseTool):
361
353
def __init__ (self , codebase : Codebase ) -> None :
362
354
super ().__init__ (codebase = codebase )
363
355
364
- def _run (self , filepath : str , tool_call_id : str , edit_content : str , start : int = 1 , end : int = - 1 ) -> ToolMessage :
356
+ def _run (self , filepath : str , edit_content : str , start : int = 1 , end : int = - 1 ) -> str :
365
357
# Create the the draft editor mini llm
366
358
result = semantic_edit (self .codebase , filepath , edit_content , start = start , end = end )
367
- return result .render (tool_call_id )
359
+ return result .render ()
368
360
369
361
370
362
class RenameFileInput (BaseModel ):
0 commit comments