wcgw 2.8.10__py3-none-any.whl → 3.0.1rc1__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 wcgw might be problematic. Click here for more details.

@@ -0,0 +1,47 @@
1
+ import threading
2
+ from typing import Callable, Protocol, TypeVar, cast
3
+
4
+ import tokenizers # type: ignore[import-untyped]
5
+
6
+ T = TypeVar("T")
7
+
8
+
9
+ class EncoderDecoder(Protocol[T]):
10
+ def encoder(self, text: str) -> list[T]: ...
11
+
12
+ def decoder(self, tokens: list[T]) -> str: ...
13
+
14
+
15
+ class LazyEncoder:
16
+ def __init__(self) -> None:
17
+ self._tokenizer: tokenizers.Tokenizer | None = None
18
+ self._init_lock = threading.Lock()
19
+ self._init_thread = threading.Thread(target=self._initialize, daemon=True)
20
+ self._init_thread.start()
21
+
22
+ def _initialize(self) -> None:
23
+ with self._init_lock:
24
+ if self._tokenizer is None:
25
+ self._tokenizer = tokenizers.Tokenizer.from_pretrained(
26
+ "Xenova/claude-tokenizer"
27
+ )
28
+
29
+ def _ensure_initialized(self) -> None:
30
+ if self._tokenizer is None:
31
+ with self._init_lock:
32
+ if self._tokenizer is None:
33
+ self._init_thread.join()
34
+
35
+ def encoder(self, text: str) -> list[int]:
36
+ self._ensure_initialized()
37
+ assert self._tokenizer is not None, "Couldn't initialize tokenizer"
38
+ return cast(list[int], self._tokenizer.encode(text).ids)
39
+
40
+ def decoder(self, tokens: list[int]) -> str:
41
+ self._ensure_initialized()
42
+ assert self._tokenizer is not None, "Couldn't initialize tokenizer"
43
+ return cast(str, self._tokenizer.decode(tokens))
44
+
45
+
46
+ def get_default_encoder() -> EncoderDecoder[int]:
47
+ return LazyEncoder()
@@ -1,89 +1,3 @@
1
- # Claude desktop support
1
+ # The doc has moved to main Readme.md
2
2
 
3
- `wcgw` enables Claude desktop app on Mac to access shell and file system in order to automate tasks, run code, etc.
4
-
5
- It also has a computer use feature to connect to linux running on docker. Claude can fully control it including mouse and keyboard.
6
-
7
- ## Setup
8
-
9
- Update `claude_desktop_config.json` (~/Library/Application Support/Claude/claude_desktop_config.json)
10
-
11
- ```json
12
- {
13
- "mcpServers": {
14
- "wcgw": {
15
- "command": "uv",
16
- "args": [
17
- "tool",
18
- "run",
19
- "--from",
20
- "wcgw@latest",
21
- "--python",
22
- "3.12",
23
- "wcgw_mcp"
24
- ]
25
- }
26
- }
27
- }
28
- ```
29
-
30
- Then restart claude app.
31
-
32
- ### [Optional] Computer use support using desktop on docker
33
-
34
- Computer use is disabled by default. Add `--computer-use` to enable it. This will add necessary tools to Claude including ScreenShot, Mouse and Keyboard control.
35
-
36
- ```json
37
- {
38
- "mcpServers": {
39
- "wcgw": {
40
- "command": "uv",
41
- "args": [
42
- "tool",
43
- "run",
44
- "--from",
45
- "wcgw@latest",
46
- "--python",
47
- "3.12",
48
- "wcgw_mcp",
49
- "--computer-use"
50
- ]
51
- }
52
- }
53
- }
54
- ```
55
-
56
- Claude will be able to connect to any docker container with linux environment. Native system control isn't supported outside docker.
57
-
58
- You'll need to run a docker image with desktop and optional VNC connection. Here's a demo image:
59
-
60
- ```sh
61
- docker run -p 6080:6080 ghcr.io/anthropics/anthropic-quickstarts:computer-use-demo-latest
62
- ```
63
-
64
- Then ask claude desktop app to control the docker os. It'll connect to the docker container and control it.
65
-
66
- Connect to `http://localhost:6080/vnc.html` for desktop view (VNC) of the system running in the docker.
67
-
68
- ## Usage
69
-
70
- Wait for a few seconds. You should be able to see this icon if everything goes right.
71
-
72
- ![mcp icon](https://github.com/rusiaaman/wcgw/blob/main/static/rocket-icon.png?raw=true)
73
- over here
74
-
75
- ![mcp icon](https://github.com/rusiaaman/wcgw/blob/main/static/claude-ss.jpg?raw=true)
76
-
77
- Then ask claude to execute shell commands, read files, edit files, run your code, etc.
78
-
79
- If you've run the docker for LLM to access, you can ask it to control the "docker os". If you don't provide the docker container id to it, it'll try to search for available docker using `docker ps` command.
80
-
81
- ## Example
82
-
83
- ### Computer use example
84
-
85
- ![computer-use](https://github.com/rusiaaman/wcgw/blob/main/static/computer-use.jpg?raw=true)
86
-
87
- ### Shell example
88
-
89
- ![example](https://github.com/rusiaaman/wcgw/blob/main/static/example.jpg?raw=true)
3
+ ![main readme](https://github.com/rusiaaman/wcgw/blob/main/README.md)
@@ -7,9 +7,9 @@ main = Typer()
7
7
 
8
8
 
9
9
  @main.command()
10
- def app(computer_use: bool = False) -> None:
10
+ def app() -> None:
11
11
  """Main entry point for the package."""
12
- asyncio.run(server.main(computer_use))
12
+ asyncio.run(server.main())
13
13
 
14
14
 
15
15
  # Optionally expose other important items at package level
@@ -11,27 +11,14 @@ from mcp_wcgw.server.models import InitializationOptions
11
11
  from mcp_wcgw.types import Tool as ToolParam
12
12
  from pydantic import AnyUrl, ValidationError
13
13
 
14
+ from wcgw.client.modes import KTS
15
+ from wcgw.client.tool_prompts import TOOL_PROMPTS
16
+
14
17
  from ...types_ import (
15
- BashCommand,
16
- BashInteraction,
17
- ContextSave,
18
- FileEdit,
19
- GetScreenInfo,
20
18
  Initialize,
21
- Keyboard,
22
- Mouse,
23
- ReadFiles,
24
- ReadImage,
25
- ResetShell,
26
- ScreenShot,
27
- WriteIfEmpty,
28
19
  )
29
- from .. import tools
30
- from ..computer_use import SLEEP_TIME_MAX_S
31
- from ..modes import get_kt_prompt
32
- from ..tools import DoneFlag, default_enc, get_tool_output, which_tool_name
33
-
34
- COMPUTER_USE_ON_DOCKER_ENABLED = False
20
+ from ..bash_state.bash_state import CONFIG, BashState
21
+ from ..tools import Context, default_enc, get_tool_output, which_tool_name
35
22
 
36
23
  server = Server("wcgw")
37
24
 
@@ -64,7 +51,7 @@ PROMPTS = {
64
51
  name="KnowledgeTransfer",
65
52
  description="Prompt for invoking ContextSave tool in order to do a comprehensive knowledge transfer of a coding task. Prompts to save detailed error log and instructions.",
66
53
  ),
67
- get_kt_prompt,
54
+ KTS,
68
55
  )
69
56
  }
70
57
 
@@ -78,12 +65,12 @@ async def handle_list_prompts() -> list[types.Prompt]:
78
65
  async def handle_get_prompt(
79
66
  name: str, arguments: dict[str, str] | None
80
67
  ) -> types.GetPromptResult:
68
+ assert BASH_STATE
81
69
  messages = [
82
70
  types.PromptMessage(
83
71
  role="user",
84
72
  content=types.TextContent(
85
- type="text",
86
- text=PROMPTS[name][1](),
73
+ type="text", text=PROMPTS[name][1][BASH_STATE.mode]
87
74
  ),
88
75
  )
89
76
  ]
@@ -97,165 +84,22 @@ async def handle_list_tools() -> list[types.Tool]:
97
84
  Each tool specifies its arguments using JSON Schema validation.
98
85
  """
99
86
 
100
- with open(
101
- os.path.join(
102
- os.path.dirname(os.path.dirname(__file__)), "diff-instructions.txt"
103
- )
104
- ) as f:
105
- diffinstructions = f.read()
106
-
107
- tools = [
108
- ToolParam(
109
- inputSchema=Initialize.model_json_schema(),
110
- name="Initialize",
111
- description="""
112
- - Always call this at the start of the conversation before using any of the shell tools from wcgw.
113
- - This will reset the shell.
114
- - Use `any_workspace_path` to initialize the shell in the appropriate project directory.
115
- - If the user has mentioned a workspace or project root, use it to set `any_workspace_path`.
116
- - If the user has mentioned a folder or file with unclear project root, use the file or folder as `any_workspace_path`.
117
- - If user has mentioned any files use `initial_files_to_read` to read, use absolute paths only.
118
- - If `any_workspace_path` is provided, a tree structure of the workspace will be shown.
119
- - Leave `any_workspace_path` as empty if no file or folder is mentioned.
120
- - By default use mode "wcgw"
121
- - In "code-writer" mode, set the commands and globs which user asked to set, otherwise use 'all'.
122
- - In order to change the mode later, call this tool again but be sure to not provide any other argument like task_id_to_resume unnecessarily.
123
- """,
124
- ),
125
- ToolParam(
126
- inputSchema=BashCommand.model_json_schema(),
127
- name="BashCommand",
128
- description=f"""
129
- - Execute a bash command. This is stateful (beware with subsequent calls).
130
- - Do not use interactive commands like nano. Prefer writing simpler commands.
131
- - Status of the command and the current working directory will always be returned at the end.
132
- - Optionally `exit shell has restarted` is the output, in which case environment resets, you can run fresh commands.
133
- - The first or the last line might be `(...truncated)` if the output is too long.
134
- - Always run `pwd` if you get any file or directory not found error to make sure you're not lost.
135
- - The control will return to you in {SLEEP_TIME_MAX_S} seconds regardless of the status. For heavy commands, keep checking status using BashInteraction till they are finished.
136
- - Run long running commands in background using screen instead of "&".
137
- - Use longer wait_for_seconds if the command is expected to run for a long time.
138
- - Do not use 'cat' to read files, use ReadFiles tool instead.
139
- """,
140
- ),
141
- ToolParam(
142
- inputSchema=BashInteraction.model_json_schema(),
143
- name="BashInteraction",
144
- description=f"""
145
- - Interact with running program using this tool
146
- - Special keys like arrows, interrupts, enter, etc.
147
- - Send text input to the running program.
148
- - Send send_specials=["Enter"] to recheck status of a running program.
149
- - Only one of send_text, send_specials, send_ascii should be provided.
150
- - This returns within {SLEEP_TIME_MAX_S} seconds, for heavy programs keep checking status for upto 10 turns before asking user to continue checking again.
151
- - Programs don't hang easily, so most likely explanation for no output is usually that the program is still running, and you need to check status again using ["Enter"].
152
- - Do not send Ctrl-c before checking for status till 10 minutes or whatever is appropriate for the program to finish.
153
- - Set longer wait_for_seconds when program is expected to run for a long time.
154
- """,
155
- ),
156
- ToolParam(
157
- inputSchema=ReadFiles.model_json_schema(),
158
- name="ReadFiles",
159
- description="""
160
- - Read full file content of one or more files.
161
- - Provide absolute file paths only
162
- """,
163
- ),
164
- ToolParam(
165
- inputSchema=WriteIfEmpty.model_json_schema(),
166
- name="WriteIfEmpty",
167
- description="""
168
- - Write content to an empty or non-existent file. Provide file path and content. Use this instead of BashCommand for writing new files.
169
- - Provide absolute file path only.
170
- - For editing existing files, use FileEdit instead of this tool.
171
- """,
172
- ),
173
- ToolParam(
174
- inputSchema=ReadImage.model_json_schema(),
175
- name="ReadImage",
176
- description="Read an image from the shell.",
177
- ),
87
+ tools_ = [
178
88
  ToolParam(
179
- inputSchema=ResetShell.model_json_schema(),
180
- name="ResetShell",
181
- description="Resets the shell. Use only if all interrupts and prompt reset attempts have failed repeatedly.\nAlso exits the docker environment.\nYou need to call GetScreenInfo again.",
182
- ),
183
- ToolParam(
184
- inputSchema=FileEdit.model_json_schema(),
185
- name="FileEdit",
186
- description="""
187
- - Use absolute file path only.
188
- - Use SEARCH/REPLACE blocks to edit the file.
189
- - If the edit fails due to block not matching, please retry with correct block till it matches. Re-read the file to ensure you've all the lines correct.
190
- """
191
- + diffinstructions,
192
- ),
193
- ToolParam(
194
- inputSchema=ContextSave.model_json_schema(),
195
- name="ContextSave",
196
- description="""
197
- Saves provided description and file contents of all the relevant file paths or globs in a single text file.
198
- - Provide random unqiue id or whatever user provided.
199
- - Leave project path as empty string if no project path""",
200
- ),
89
+ inputSchema=tool.inputSchema,
90
+ name=tool.name,
91
+ description=tool.description,
92
+ )
93
+ for tool in TOOL_PROMPTS
201
94
  ]
202
- if COMPUTER_USE_ON_DOCKER_ENABLED:
203
- tools += [
204
- ToolParam(
205
- inputSchema=GetScreenInfo.model_json_schema(),
206
- name="GetScreenInfo",
207
- description="""
208
- - Important: call this first in the conversation before ScreenShot, Mouse, and Keyboard tools.
209
- - Get display information of a linux os running on docker using image "ghcr.io/anthropics/anthropic-quickstarts:computer-use-demo-latest"
210
- - If user hasn't provided docker image id, check using `docker ps` and provide the id.
211
- - If the docker is not running, run using `docker run -d -p 6080:6080 ghcr.io/anthropics/anthropic-quickstarts:computer-use-demo-latest`
212
- - Connects shell to the docker environment.
213
- - Note: once this is called, the shell enters the docker environment. All bash commands will run over there.
214
- """,
215
- ),
216
- ToolParam(
217
- inputSchema=ScreenShot.model_json_schema(),
218
- name="ScreenShot",
219
- description="""
220
- - Capture screenshot of the linux os on docker.
221
- - All actions on UI using mouse and keyboard return within 0.5 seconds.
222
- * So if you're doing something that takes longer for UI to update like heavy page loading, keep checking UI for update using ScreenShot upto 10 turns.
223
- * Notice for smallest of the loading icons to check if your action worked.
224
- * After 10 turns of no change, ask user for permission to keep checking.
225
- * If you don't notice even slightest of the change, it's likely you clicked on the wrong place.
226
- """,
227
- ),
228
- ToolParam(
229
- inputSchema=Mouse.model_json_schema(),
230
- name="Mouse",
231
- description="""
232
- - Interact with the linux os on docker using mouse.
233
- - Uses xdotool
234
- - About left_click_drag: the current mouse position will be used as the starting point, click and drag to the given x, y coordinates. Useful in things like sliders, moving things around, etc.
235
- - The output of this command has the screenshot after doing this action. Use this to verify if the action was successful.
236
- """,
237
- ),
238
- ToolParam(
239
- inputSchema=Keyboard.model_json_schema(),
240
- name="Keyboard",
241
- description="""
242
- - Interact with the linux os on docker using keyboard.
243
- - Emulate keyboard input to the screen
244
- - Uses xdootool to send keyboard input, keys like Return, BackSpace, Escape, Page_Up, etc. can be used.
245
- - Do not use it to interact with Bash tool.
246
- - Make sure you've selected a text area or an editable element before sending text.
247
- - The output of this command has the screenshot after doing this action. Use this to verify if the action was successful.
248
- """,
249
- ),
250
- ]
251
-
252
- return tools
95
+ return tools_
253
96
 
254
97
 
255
98
  @server.call_tool() # type: ignore
256
99
  async def handle_call_tool(
257
100
  name: str, arguments: dict[str, Any] | None
258
101
  ) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]:
102
+ global BASH_STATE
259
103
  if not arguments:
260
104
  raise ValueError("Missing arguments")
261
105
 
@@ -276,8 +120,14 @@ async def handle_call_tool(
276
120
  tool_call = tool_type(**{k: try_json(v) for k, v in arguments.items()})
277
121
 
278
122
  try:
123
+ assert BASH_STATE
279
124
  output_or_dones, _ = get_tool_output(
280
- tool_call, default_enc, 0.0, lambda x, y: ("", 0), 8000
125
+ Context(BASH_STATE, BASH_STATE.console),
126
+ tool_call,
127
+ default_enc,
128
+ 0.0,
129
+ lambda x, y: ("", 0),
130
+ 8000,
281
131
  )
282
132
 
283
133
  except Exception as e:
@@ -285,7 +135,6 @@ async def handle_call_tool(
285
135
 
286
136
  content: list[types.TextContent | types.ImageContent | types.EmbeddedResource] = []
287
137
  for output_or_done in output_or_dones:
288
- assert not isinstance(output_or_done, DoneFlag)
289
138
  if isinstance(output_or_done, str):
290
139
  if issubclass(tool_type, Initialize):
291
140
  output_or_done += """
@@ -307,31 +156,30 @@ Initialize call done.
307
156
  return content
308
157
 
309
158
 
310
- async def main(computer_use: bool) -> None:
311
- global COMPUTER_USE_ON_DOCKER_ENABLED
312
-
313
- tools.TIMEOUT = SLEEP_TIME_MAX_S
314
- tools.TIMEOUT_WHILE_OUTPUT = 55
315
- tools.OUTPUT_WAIT_PATIENCE = 5
316
- tools.console = Console()
159
+ BASH_STATE = None
317
160
 
318
- if computer_use:
319
- COMPUTER_USE_ON_DOCKER_ENABLED = True
320
161
 
162
+ async def main() -> None:
163
+ global BASH_STATE
164
+ CONFIG.update(3, 55, 5)
321
165
  version = str(importlib.metadata.version("wcgw"))
322
- tools.console.log("wcgw version: " + version)
323
- # Run the server using stdin/stdout streams
324
- async with mcp_wcgw.server.stdio.stdio_server() as (read_stream, write_stream):
325
- await server.run(
326
- read_stream,
327
- write_stream,
328
- InitializationOptions(
329
- server_name="wcgw",
330
- server_version=version,
331
- capabilities=server.get_capabilities(
332
- notification_options=NotificationOptions(),
333
- experimental_capabilities={},
166
+ home_dir = os.path.expanduser("~")
167
+ with BashState(
168
+ Console(), home_dir, None, None, None, None, False, None
169
+ ) as BASH_STATE:
170
+ BASH_STATE.console.log("wcgw version: " + version)
171
+ # Run the server using stdin/stdout streams
172
+ async with mcp_wcgw.server.stdio.stdio_server() as (read_stream, write_stream):
173
+ await server.run(
174
+ read_stream,
175
+ write_stream,
176
+ InitializationOptions(
177
+ server_name="wcgw",
178
+ server_version=version,
179
+ capabilities=server.get_capabilities(
180
+ notification_options=NotificationOptions(),
181
+ experimental_capabilities={},
182
+ ),
334
183
  ),
335
- ),
336
- raise_exceptions=False,
337
- )
184
+ raise_exceptions=False,
185
+ )
wcgw/client/modes.py CHANGED
@@ -61,7 +61,7 @@ You are now running in "code_writer" mode.
61
61
  if allowed_file_edit_globs != "all":
62
62
  if allowed_file_edit_globs:
63
63
  path_prompt = f"""
64
- - You are allowed to run FileEdit for files matching only the following globs: {', '.join(allowed_file_edit_globs)}
64
+ - You are allowed to run FileEdit for files matching only the following globs: {", ".join(allowed_file_edit_globs)}
65
65
  """
66
66
  else:
67
67
  path_prompt = """
@@ -76,7 +76,7 @@ You are now running in "code_writer" mode.
76
76
  if all_write_new_globs != "all":
77
77
  if all_write_new_globs:
78
78
  path_prompt = f"""
79
- - You are allowed to run WriteIfEmpty files matching only the following globs: {', '.join(allowed_file_edit_globs)}
79
+ - You are allowed to run WriteIfEmpty files matching only the following globs: {", ".join(allowed_file_edit_globs)}
80
80
  """
81
81
  else:
82
82
  path_prompt = """
@@ -101,7 +101,7 @@ You are now running in "code_writer" mode.
101
101
  if allowed_commands != "all":
102
102
  if allowed_commands:
103
103
  command_prompt = f"""
104
- - You are only allowed to run the following commands: {', '.join(allowed_commands)}
104
+ - You are only allowed to run the following commands: {", ".join(allowed_commands)}
105
105
  {run_command_common}
106
106
  """
107
107
  else:
@@ -234,9 +234,3 @@ Provide all relevant file paths in order to understand and solve the the task. E
234
234
  """
235
235
 
236
236
  KTS = {Modes.wcgw: WCGW_KT, Modes.architect: ARCHITECT_KT, Modes.code_writer: WCGW_KT}
237
-
238
-
239
- def get_kt_prompt() -> str:
240
- from .tools import BASH_STATE
241
-
242
- return KTS[BASH_STATE.mode]
@@ -109,18 +109,7 @@ class DirectoryTree:
109
109
  current_path, shown_items
110
110
  )
111
111
  if hidden_files > 0 or hidden_dirs > 0:
112
- hidden_msg = []
113
- if hidden_dirs > 0:
114
- hidden_msg.append(
115
- f"{hidden_dirs} director{'ies' if hidden_dirs != 1 else 'y'}"
116
- )
117
- if hidden_files > 0:
118
- hidden_msg.append(
119
- f"{hidden_files} file{'s' if hidden_files != 1 else ''}"
120
- )
121
- writer.write(
122
- f"{' ' * (indent + 2)}... {' and '.join(hidden_msg)} hidden\n"
123
- )
112
+ writer.write(f"{' ' * (indent + 2)}...\n")
124
113
 
125
114
  _display_recursive(self.root, depth=0)
126
115
 
@@ -0,0 +1,105 @@
1
+ import os
2
+ from dataclasses import dataclass
3
+ from typing import Any
4
+
5
+ from ..types_ import (
6
+ BashCommand,
7
+ ContextSave,
8
+ FileEdit,
9
+ Initialize,
10
+ ReadFiles,
11
+ ReadImage,
12
+ ResetWcgw,
13
+ WriteIfEmpty,
14
+ )
15
+
16
+ with open(os.path.join(os.path.dirname(__file__), "diff-instructions.txt")) as f:
17
+ diffinstructions = f.read()
18
+
19
+
20
+ @dataclass
21
+ class Prompts:
22
+ inputSchema: dict[str, Any]
23
+ name: str
24
+ description: str
25
+
26
+
27
+ TOOL_PROMPTS = [
28
+ Prompts(
29
+ inputSchema=Initialize.model_json_schema(),
30
+ name="Initialize",
31
+ description="""
32
+ - Always call this at the start of the conversation before using any of the shell tools from wcgw.
33
+ - This will reset the shell.
34
+ - Use `any_workspace_path` to initialize the shell in the appropriate project directory.
35
+ - If the user has mentioned a workspace or project root, use it to set `any_workspace_path`.
36
+ - If the user has mentioned a folder or file with unclear project root, use the file or folder as `any_workspace_path`.
37
+ - If user has mentioned any files use `initial_files_to_read` to read, use absolute paths only.
38
+ - Leave `any_workspace_path` as empty if no file or folder is mentioned.
39
+ - By default use mode "wcgw"
40
+ - In "code-writer" mode, set the commands and globs which user asked to set, otherwise use 'all'.
41
+ - Call `ResetWcgw` if you want to change the mode later.
42
+ """,
43
+ ),
44
+ Prompts(
45
+ inputSchema=BashCommand.model_json_schema(),
46
+ name="BashCommand",
47
+ description="""
48
+ - Execute a bash command. This is stateful (beware with subsequent calls).
49
+ - Status of the command and the current working directory will always be returned at the end.
50
+ - The first or the last line might be `(...truncated)` if the output is too long.
51
+ - Always run `pwd` if you get any file or directory not found error to make sure you're not lost.
52
+ - Run long running commands in background using screen instead of "&".
53
+ - Do not use 'cat' to read files, use ReadFiles tool instead
54
+ - In order to check status of previous command, use `status_check` with empty command argument.
55
+ - Only command is allowed to run at a time. You need to wait for any previous command to finish before running a new one.
56
+ - Programs don't hang easily, so most likely explanation for no output is usually that the program is still running, and you need to check status again.
57
+ - Do not send Ctrl-c before checking for status till 10 minutes or whatever is appropriate for the program to finish.
58
+ """,
59
+ ),
60
+ Prompts(
61
+ inputSchema=ReadFiles.model_json_schema(),
62
+ name="ReadFiles",
63
+ description="""
64
+ - Read full file content of one or more files.
65
+ - Provide absolute file paths only
66
+ """,
67
+ ),
68
+ Prompts(
69
+ inputSchema=WriteIfEmpty.model_json_schema(),
70
+ name="WriteIfEmpty",
71
+ description="""
72
+ - Write content to an empty or non-existent file. Provide file path and content. Use this instead of BashCommand for writing new files.
73
+ - Provide absolute file path only.
74
+ - For editing existing files, use FileEdit instead of this tool.
75
+ """,
76
+ ),
77
+ Prompts(
78
+ inputSchema=ReadImage.model_json_schema(),
79
+ name="ReadImage",
80
+ description="Read an image from the shell.",
81
+ ),
82
+ Prompts(
83
+ inputSchema=ResetWcgw.model_json_schema(),
84
+ name="ResetWcgw",
85
+ description="Resets the shell. Use either when changing mode, or when all interrupts and prompt reset attempts have failed repeatedly.",
86
+ ),
87
+ Prompts(
88
+ inputSchema=FileEdit.model_json_schema(),
89
+ name="FileEdit",
90
+ description="""
91
+ - Use absolute file path only.
92
+ - Use SEARCH/REPLACE blocks to edit the file.
93
+ - If the edit fails due to block not matching, please retry with correct block till it matches. Re-read the file to ensure you've all the lines correct.
94
+ """
95
+ + diffinstructions,
96
+ ),
97
+ Prompts(
98
+ inputSchema=ContextSave.model_json_schema(),
99
+ name="ContextSave",
100
+ description="""
101
+ Saves provided description and file contents of all the relevant file paths or globs in a single text file.
102
+ - Provide random unqiue id or whatever user provided.
103
+ - Leave project path as empty string if no project path""",
104
+ ),
105
+ ]