wcgw 1.2.0__py3-none-any.whl → 1.2.2__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.

@@ -223,9 +223,10 @@ You're a cli assistant.
223
223
 
224
224
  Instructions:
225
225
 
226
- - You should use the provided bash execution tool to run script to complete objective.
227
- - First understand about the project by understanding the folder structure (ignoring node_modules or venv, etc.)
228
- - Always read relevant files before making any changes.
226
+ - You should use the provided bash execution, reading and writing file tools to complete objective.
227
+ - First understand about the project by getting the folder structure (ignoring .git, node_modules, venv, etc.)
228
+ - Always read relevant files before editing.
229
+ - Do not provide code snippets unless asked by the user, instead directly edit the code.
229
230
 
230
231
  System information:
231
232
  - System: {uname_sysname}
@@ -1,5 +1,7 @@
1
1
 
2
- Instructions for
2
+ Instructions for editing files.
3
+
4
+
3
5
  Only edit the files using the following SEARCH/REPLACE blocks.
4
6
  ```
5
7
  <<<<<<< SEARCH
@@ -8,7 +10,27 @@ def hello():
8
10
 
9
11
  print("hello")
10
12
  =======
11
- from hello import hello
13
+ from hello import hello as hello_renamed
14
+ >>>>>>> REPLACE
15
+ <<<<<<< SEARCH
16
+ def call_hello():
17
+ "call hello"
18
+
19
+ hello()
20
+ =======
21
+ def call_hello_renamed():
22
+ "call hello renamed"
23
+
24
+ hello_renamed()
25
+ >>>>>>> REPLACE
26
+ <<<<<<< SEARCH
27
+ impl1()
28
+ hello()
29
+ impl2()
30
+ =======
31
+ impl1()
32
+ hello_renamed()
33
+ impl2()
12
34
  >>>>>>> REPLACE
13
35
  ```
14
36
 
@@ -31,5 +53,3 @@ Keep *SEARCH/REPLACE* blocks concise.
31
53
  Break large *SEARCH/REPLACE* blocks into a series of smaller blocks that each change a small portion of the file.
32
54
  Include just the changing lines, and a few surrounding lines if needed for uniqueness.
33
55
  Do not include long runs of unchanging lines in *SEARCH/REPLACE* blocks.
34
-
35
- Include context lines before and after the code to edit for better matching in "<<<<<<< SEARCH". Recommended to add 3 lines on each side.
@@ -185,6 +185,7 @@ def loop(
185
185
  - Interact with running program using this tool
186
186
  - Special keys like arrows, interrupts, enter, etc.
187
187
  - Send text input to the running program.
188
+ - Send send_specials=["Enter"] to recheck status of a running program.
188
189
  - Only one of send_text, send_specials, send_ascii should be provided.""",
189
190
  ),
190
191
  openai.pydantic_function_tool(
@@ -226,10 +227,11 @@ You're a cli assistant.
226
227
 
227
228
  Instructions:
228
229
 
229
- - You should use the provided bash execution tool to run script to complete objective.
230
- - First understand about the project by understanding the folder structure (ignoring node_modules or venv, etc.)
231
- - Always read relevant files before making any changes.
232
-
230
+ - You should use the provided bash execution, reading and writing file tools to complete objective.
231
+ - First understand about the project by getting the folder structure (ignoring .git, node_modules, venv, etc.)
232
+ - Always read relevant files before editing.
233
+ - Do not provide code snippets unless asked by the user, instead directly edit the code.
234
+
233
235
  System information:
234
236
  - System: {uname_sysname}
235
237
  - Machine: {uname_machine}
wcgw/client/tools.py CHANGED
@@ -251,55 +251,71 @@ def execute_bash(
251
251
  )
252
252
 
253
253
  SHELL.sendline(command)
254
- elif bash_arg.send_specials:
255
- console.print(f"Sending special sequence: {bash_arg.send_specials}")
256
- for char in bash_arg.send_specials:
257
- if char == "Key-up":
258
- SHELL.send("\033[A")
259
- elif char == "Key-down":
260
- SHELL.send("\033[B")
261
- elif char == "Key-left":
262
- SHELL.send("\033[D")
263
- elif char == "Key-right":
264
- SHELL.send("\033[C")
265
- elif char == "Enter":
266
- SHELL.send("\n")
267
- elif char == "Ctrl-c":
268
- SHELL.sendintr()
269
- is_interrupt = True
270
- elif char == "Ctrl-d":
271
- SHELL.sendintr()
272
- is_interrupt = True
273
- elif char == "Ctrl-z":
274
- SHELL.send("\x1a")
275
- else:
276
- raise Exception(f"Unknown special character: {char}")
277
- elif bash_arg.send_ascii:
278
- console.print(f"Sending ASCII sequence: {bash_arg.send_ascii}")
279
- for ascii_char in bash_arg.send_ascii:
280
- SHELL.send(chr(ascii_char))
281
- if ascii_char == 3:
282
- is_interrupt = True
254
+
283
255
  else:
284
- if bash_arg.send_text is None:
256
+ if (
257
+ sum(
258
+ [
259
+ int(bool(bash_arg.send_text)),
260
+ int(bool(bash_arg.send_specials)),
261
+ int(bool(bash_arg.send_ascii)),
262
+ ]
263
+ )
264
+ != 1
265
+ ):
285
266
  return (
286
- "Failure: at least one of send_text, send_specials or send_ascii should be provided",
267
+ "Failure: exactly one of send_text, send_specials or send_ascii should be provided",
287
268
  0.0,
288
269
  )
270
+ if bash_arg.send_specials:
271
+ console.print(f"Sending special sequence: {bash_arg.send_specials}")
272
+ for char in bash_arg.send_specials:
273
+ if char == "Key-up":
274
+ SHELL.send("\033[A")
275
+ elif char == "Key-down":
276
+ SHELL.send("\033[B")
277
+ elif char == "Key-left":
278
+ SHELL.send("\033[D")
279
+ elif char == "Key-right":
280
+ SHELL.send("\033[C")
281
+ elif char == "Enter":
282
+ SHELL.send("\n")
283
+ elif char == "Ctrl-c":
284
+ SHELL.sendintr()
285
+ is_interrupt = True
286
+ elif char == "Ctrl-d":
287
+ SHELL.sendintr()
288
+ is_interrupt = True
289
+ elif char == "Ctrl-z":
290
+ SHELL.send("\x1a")
291
+ else:
292
+ raise Exception(f"Unknown special character: {char}")
293
+ elif bash_arg.send_ascii:
294
+ console.print(f"Sending ASCII sequence: {bash_arg.send_ascii}")
295
+ for ascii_char in bash_arg.send_ascii:
296
+ SHELL.send(chr(ascii_char))
297
+ if ascii_char == 3:
298
+ is_interrupt = True
299
+ else:
300
+ if bash_arg.send_text is None:
301
+ return (
302
+ "Failure: at least one of send_text, send_specials or send_ascii should be provided",
303
+ 0.0,
304
+ )
289
305
 
290
- updated_repl_mode = update_repl_prompt(bash_arg.send_text)
291
- if updated_repl_mode:
292
- BASH_STATE = "repl"
293
- response = (
294
- "Prompt updated, you can execute REPL lines using BashCommand now"
295
- )
296
- console.print(response)
297
- return (
298
- response,
299
- 0,
300
- )
301
- console.print(f"Interact text: {bash_arg.send_text}")
302
- SHELL.sendline(bash_arg.send_text)
306
+ updated_repl_mode = update_repl_prompt(bash_arg.send_text)
307
+ if updated_repl_mode:
308
+ BASH_STATE = "repl"
309
+ response = (
310
+ "Prompt updated, you can execute REPL lines using BashCommand now"
311
+ )
312
+ console.print(response)
313
+ return (
314
+ response,
315
+ 0,
316
+ )
317
+ console.print(f"Interact text: {bash_arg.send_text}")
318
+ SHELL.sendline(bash_arg.send_text)
303
319
 
304
320
  BASH_STATE = "repl"
305
321
 
@@ -453,6 +469,14 @@ def find_least_edit_distance_substring(
453
469
  content_lines = [
454
470
  line.strip() for line in orig_content_lines
455
471
  ] # Remove trailing and leading space for calculating edit distance
472
+ new_to_original_indices = {}
473
+ new_content_lines = []
474
+ for i in range(len(content_lines)):
475
+ if not content_lines[i]:
476
+ continue
477
+ new_content_lines.append(content_lines[i])
478
+ new_to_original_indices[len(new_content_lines) - 1] = i
479
+ content_lines = new_content_lines
456
480
  find_lines = find_str.split("\n")
457
481
  find_lines = [
458
482
  line.strip() for line in find_lines
@@ -470,8 +494,9 @@ def find_least_edit_distance_substring(
470
494
  edit_distance_sum += len(find_lines[j])
471
495
  if edit_distance_sum < min_edit_distance:
472
496
  min_edit_distance = edit_distance_sum
473
- min_edit_distance_lines = orig_content_lines[i: i + len(
474
- find_lines)]
497
+ orig_start_index = new_to_original_indices[i]
498
+ orig_end_index = new_to_original_indices.get(i + len(find_lines) - 1, len(orig_content_lines) - 1) + 1
499
+ min_edit_distance_lines = orig_content_lines[orig_start_index:orig_end_index]
475
500
  return "\n".join(min_edit_distance_lines), min_edit_distance
476
501
 
477
502
 
@@ -481,12 +506,12 @@ def edit_content(content: str, find_lines: str, replace_with_lines: str) -> str:
481
506
  closest_match, min_edit_distance = find_least_edit_distance_substring(
482
507
  content, find_lines
483
508
  )
484
- print(
485
- f"Exact match not found, found with whitespace removed edit distance: {min_edit_distance}"
486
- )
487
- if min_edit_distance / len(find_lines) < 1 / 100:
488
- print("Editing file with closest match")
509
+ if min_edit_distance == 0:
489
510
  return edit_content(content, closest_match, replace_with_lines)
511
+ else:
512
+ print(
513
+ f"Exact match not found, found with whitespace removed edit distance: {min_edit_distance}"
514
+ )
490
515
  raise Exception(
491
516
  f"Error: no match found for the provided `find_lines` in the file. Closest match:\n---\n{closest_match}\n---\nFile not edited"
492
517
  )
@@ -511,6 +536,12 @@ def do_diff_edit(fedit: FileEdit) -> str:
511
536
  apply_diff_to = f.read()
512
537
 
513
538
  lines = fedit.file_edit_using_search_replace_blocks.split("\n")
539
+
540
+ if not lines or not re.match(r"^<<<<<<+\s*SEARCH\s*$", lines[0]):
541
+ raise Exception(
542
+ "Error: first line should be `<<<<<< SEARCH` to start a search-replace block"
543
+ )
544
+
514
545
  n_lines = len(lines)
515
546
  i = 0
516
547
  replacement_count = 0
wcgw/types_.py CHANGED
@@ -13,26 +13,11 @@ Specials = Literal[
13
13
 
14
14
 
15
15
  class BashInteraction(BaseModel):
16
+ type: Literal["BashInteraction"]
16
17
  send_text: Optional[str] = None
17
18
  send_specials: Optional[Sequence[Specials]] = None
18
19
  send_ascii: Optional[Sequence[int]] = None
19
20
 
20
- def model_post_init(self, __context: object) -> None:
21
- # Ensure only one of the fields is set
22
- if (
23
- sum(
24
- [
25
- int(bool(self.send_text)),
26
- int(bool(self.send_specials)),
27
- int(bool(self.send_ascii)),
28
- ]
29
- )
30
- != 1
31
- ):
32
- raise ValueError(
33
- "Exactly one of 'send_text', 'send_specials', or 'send_ascii' must be set"
34
- )
35
-
36
21
 
37
22
  class ReadImage(BaseModel):
38
23
  file_path: str
@@ -61,16 +46,9 @@ class FileEditFindReplace(BaseModel):
61
46
 
62
47
 
63
48
  class ResetShell(BaseModel):
64
- should_reset: Literal[True] = True
49
+ should_reset: Literal[True]
65
50
 
66
51
 
67
52
  class FileEdit(BaseModel):
68
53
  file_path: str
69
54
  file_edit_using_search_replace_blocks: str
70
-
71
- def model_post_init(self, __context: object) -> None:
72
- # Ensure first line is "<<<<<<< SEARCH"
73
-
74
- if not re.match(r"^<<<<<<+\s*SEARCH\s*$", self.file_edit_using_search_replace_blocks.split("\n")[0]):
75
-
76
- raise ValueError("First line of file_edit_using_search_replace_blocks must be '<<<<<<< SEARCH'")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: wcgw
3
- Version: 1.2.0
3
+ Version: 1.2.2
4
4
  Summary: What could go wrong giving full shell access to chatgpt?
5
5
  Project-URL: Homepage, https://github.com/rusiaaman/wcgw
6
6
  Author-email: Aman Rusia <gapypi@arcfu.com>
@@ -1,17 +1,17 @@
1
1
  wcgw/__init__.py,sha256=PNWvBvjUKA3aj4bHOtIqBKCAtOW88pr0hAXZ7RylVr8,68
2
- wcgw/types_.py,sha256=a0sE4hPj4qylQFqMJwysLYy_FVYsueJTjq5fmHmNWGo,1855
2
+ wcgw/types_.py,sha256=HND4V3KruqkAhzzEf2ve7HhF8y_o5w11Fu784U8xN_I,1062
3
3
  wcgw/client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  wcgw/client/__main__.py,sha256=ngI_vBcLAv7fJgmS4w4U7tuWtalGB8c7W5qebuT6Z6o,30
5
- wcgw/client/anthropic_client.py,sha256=g5dj7tP_wkLMjQawil4PxhrEemlrIKYttWUXBI5SZ4Q,15260
5
+ wcgw/client/anthropic_client.py,sha256=YQ2puVKlrgbI6QvV_DQjWkvq2qw6KhPPrivm0OGfRsc,15353
6
6
  wcgw/client/cli.py,sha256=Oja42CHkVO8puqOXflko9NeephYCMa85aBmQTEjBZtI,932
7
7
  wcgw/client/common.py,sha256=grH-yV_4tnTQZ29xExn4YicGLxEq98z-HkEZwH0ReSg,1410
8
- wcgw/client/diff-instructions.txt,sha256=I_qroE6_aMpWtOeywPSDCTxmz-P6VPopdp1kR2r0D8w,1375
9
- wcgw/client/openai_client.py,sha256=Vsj8TzYj22fawU1LagAU7bn21Va50KXwpYZpGZ0BUZ0,17310
8
+ wcgw/client/diff-instructions.txt,sha256=Fy6op3wkr5gYgMHCRcitG4804zLrTxMbs-VSMB1oIzA,1548
9
+ wcgw/client/openai_client.py,sha256=v6ZBW4oh1CJpyWLTt16S-7ew8Gmq6YrJzaTux2ffywI,17470
10
10
  wcgw/client/openai_utils.py,sha256=YNwCsA-Wqq7jWrxP0rfQmBTb1dI0s7dWXzQqyTzOZT4,2629
11
- wcgw/client/tools.py,sha256=NeGIZ8AJ9-XAiW6gUXf7GWs1UJjw8f7ecxUBBEAtyEI,25994
11
+ wcgw/client/tools.py,sha256=zeUOemmFwReY1jEJnnAkhPbBwkL4pjZvQ6G5BWPux4c,27301
12
12
  wcgw/relay/serve.py,sha256=sMbERQTM1GhpnPWLzdtpcb23TIsgbP-ZuqVj-vjp5Rw,8186
13
13
  wcgw/relay/static/privacy.txt,sha256=s9qBdbx2SexCpC_z33sg16TptmAwDEehMCLz4L50JLc,529
14
- wcgw-1.2.0.dist-info/METADATA,sha256=1AJa0M-m_tvHNpANqak4-q7bKTgg07_qgjddGwQaOhs,5255
15
- wcgw-1.2.0.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
16
- wcgw-1.2.0.dist-info/entry_points.txt,sha256=WlIB825-Vm9ZtNzgENQsbHj4DRMkbpVR7uSkQyBlaPA,93
17
- wcgw-1.2.0.dist-info/RECORD,,
14
+ wcgw-1.2.2.dist-info/METADATA,sha256=0zQpOcQD8eRiQMVibiksflPhrngU49FSgpEHAmXQ_DA,5255
15
+ wcgw-1.2.2.dist-info/WHEEL,sha256=C2FUgwZgiLbznR-k0b_5k3Ai_1aASOXDss3lzCUsUug,87
16
+ wcgw-1.2.2.dist-info/entry_points.txt,sha256=WlIB825-Vm9ZtNzgENQsbHj4DRMkbpVR7uSkQyBlaPA,93
17
+ wcgw-1.2.2.dist-info/RECORD,,
File without changes