wcgw 1.2.0__tar.gz → 1.2.2__tar.gz
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.
- {wcgw-1.2.0 → wcgw-1.2.2}/PKG-INFO +1 -1
- {wcgw-1.2.0 → wcgw-1.2.2}/gpt_action_json_schema.json +12 -2
- {wcgw-1.2.0 → wcgw-1.2.2}/gpt_instructions.txt +25 -7
- {wcgw-1.2.0 → wcgw-1.2.2}/pyproject.toml +1 -1
- {wcgw-1.2.0 → wcgw-1.2.2}/src/wcgw/client/anthropic_client.py +4 -3
- {wcgw-1.2.0 → wcgw-1.2.2}/src/wcgw/client/diff-instructions.txt +24 -4
- {wcgw-1.2.0 → wcgw-1.2.2}/src/wcgw/client/openai_client.py +6 -4
- {wcgw-1.2.0 → wcgw-1.2.2}/src/wcgw/client/tools.py +82 -51
- {wcgw-1.2.0 → wcgw-1.2.2}/src/wcgw/types_.py +2 -24
- {wcgw-1.2.0 → wcgw-1.2.2}/.github/workflows/python-publish.yml +0 -0
- {wcgw-1.2.0 → wcgw-1.2.2}/.github/workflows/python-tests.yml +0 -0
- {wcgw-1.2.0 → wcgw-1.2.2}/.gitignore +0 -0
- {wcgw-1.2.0 → wcgw-1.2.2}/.python-version +0 -0
- {wcgw-1.2.0 → wcgw-1.2.2}/.vscode/settings.json +0 -0
- {wcgw-1.2.0 → wcgw-1.2.2}/README.md +0 -0
- {wcgw-1.2.0 → wcgw-1.2.2}/src/__init__.py +0 -0
- {wcgw-1.2.0 → wcgw-1.2.2}/src/wcgw/__init__.py +0 -0
- {wcgw-1.2.0 → wcgw-1.2.2}/src/wcgw/client/__init__.py +0 -0
- {wcgw-1.2.0 → wcgw-1.2.2}/src/wcgw/client/__main__.py +0 -0
- {wcgw-1.2.0 → wcgw-1.2.2}/src/wcgw/client/cli.py +0 -0
- {wcgw-1.2.0 → wcgw-1.2.2}/src/wcgw/client/common.py +0 -0
- {wcgw-1.2.0 → wcgw-1.2.2}/src/wcgw/client/openai_utils.py +0 -0
- {wcgw-1.2.0 → wcgw-1.2.2}/src/wcgw/relay/serve.py +0 -0
- {wcgw-1.2.0 → wcgw-1.2.2}/src/wcgw/relay/static/privacy.txt +0 -0
- {wcgw-1.2.0 → wcgw-1.2.2}/static/ss1.png +0 -0
- {wcgw-1.2.0 → wcgw-1.2.2}/tests/test_basic.py +0 -0
- {wcgw-1.2.0 → wcgw-1.2.2}/tests/test_tools.py +0 -0
- {wcgw-1.2.0 → wcgw-1.2.2}/uv.lock +0 -0
|
@@ -255,6 +255,14 @@
|
|
|
255
255
|
"schemas": {
|
|
256
256
|
"BashInteractionWithUUID": {
|
|
257
257
|
"properties": {
|
|
258
|
+
"type": {
|
|
259
|
+
"type": "string",
|
|
260
|
+
"enum": [
|
|
261
|
+
"BashInteraction"
|
|
262
|
+
],
|
|
263
|
+
"const": "BashInteraction",
|
|
264
|
+
"title": "Type"
|
|
265
|
+
},
|
|
258
266
|
"send_text": {
|
|
259
267
|
"anyOf": [
|
|
260
268
|
{
|
|
@@ -312,7 +320,8 @@
|
|
|
312
320
|
},
|
|
313
321
|
"type": "object",
|
|
314
322
|
"required": [
|
|
315
|
-
"user_id"
|
|
323
|
+
"user_id",
|
|
324
|
+
"type"
|
|
316
325
|
],
|
|
317
326
|
"title": "BashInteractionWithUUID"
|
|
318
327
|
},
|
|
@@ -443,7 +452,8 @@
|
|
|
443
452
|
},
|
|
444
453
|
"type": "object",
|
|
445
454
|
"required": [
|
|
446
|
-
"user_id"
|
|
455
|
+
"user_id",
|
|
456
|
+
"should_reset"
|
|
447
457
|
],
|
|
448
458
|
"title": "ResetShellWithUUID"
|
|
449
459
|
},
|
|
@@ -29,6 +29,7 @@ Instructions for `BashInteraction`
|
|
|
29
29
|
- Interact with running program using this tool
|
|
30
30
|
- Special keys like arrows, interrupts, enter, etc.
|
|
31
31
|
- Send text input to the running program.
|
|
32
|
+
- Send send_specials=["Enter"] to recheck status of a running program.
|
|
32
33
|
- Only one of send_text, send_specials, send_ascii should be provided.
|
|
33
34
|
|
|
34
35
|
Instructions for `ResetShell`
|
|
@@ -38,16 +39,35 @@ Instructions for `FileEdit`:
|
|
|
38
39
|
- Use absolute file path only.
|
|
39
40
|
- Use SEARCH/REPLACE blocks to edit the file.
|
|
40
41
|
Only edit the files using the following SEARCH/REPLACE blocks.
|
|
42
|
+
|
|
41
43
|
```
|
|
42
44
|
<<<<<<< SEARCH
|
|
43
|
-
|
|
45
|
+
def hello():
|
|
46
|
+
"print a greeting"
|
|
47
|
+
|
|
48
|
+
print("hello")
|
|
49
|
+
=======
|
|
50
|
+
from hello import hello as hello_renamed
|
|
51
|
+
>>>>>>> REPLACE
|
|
52
|
+
<<<<<<< SEARCH
|
|
53
|
+
def call_hello():
|
|
54
|
+
"call hello"
|
|
55
|
+
|
|
56
|
+
hello()
|
|
44
57
|
=======
|
|
45
|
-
|
|
58
|
+
def call_hello_renamed():
|
|
59
|
+
"call hello renamed"
|
|
60
|
+
|
|
61
|
+
hello_renamed()
|
|
46
62
|
>>>>>>> REPLACE
|
|
47
63
|
<<<<<<< SEARCH
|
|
48
|
-
|
|
64
|
+
impl1()
|
|
65
|
+
hello()
|
|
66
|
+
impl2()
|
|
49
67
|
=======
|
|
50
|
-
|
|
68
|
+
impl1()
|
|
69
|
+
hello_renamed()
|
|
70
|
+
impl2()
|
|
51
71
|
>>>>>>> REPLACE
|
|
52
72
|
```
|
|
53
73
|
|
|
@@ -71,11 +91,9 @@ Instructions for `FileEdit`:
|
|
|
71
91
|
Include just the changing lines, and a few surrounding lines if needed for uniqueness.
|
|
72
92
|
Do not include long runs of unchanging lines in *SEARCH/REPLACE* blocks.
|
|
73
93
|
|
|
74
|
-
Include context lines before and after the code to edit for better matching in "<<<<<<< SEARCH" and ">>>>>>> REPLACE". Recommended to add 3 lines on each side.
|
|
75
|
-
|
|
76
94
|
---
|
|
77
95
|
Always run `pwd` if you get any file or directory not found error to make sure you're not lost, or to get absolute cwd.
|
|
78
96
|
|
|
79
97
|
Always write production ready, syntactically correct code.
|
|
80
98
|
---
|
|
81
|
-
Ask the user for the user_id `UUID` if they haven't provided in the first message.
|
|
99
|
+
Ask the user for the user_id `UUID` if they haven't provided in the first message.
|
|
@@ -223,9 +223,10 @@ You're a cli assistant.
|
|
|
223
223
|
|
|
224
224
|
Instructions:
|
|
225
225
|
|
|
226
|
-
- You should use the provided bash execution
|
|
227
|
-
- First understand about the project by
|
|
228
|
-
- Always read relevant files before
|
|
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
|
|
230
|
-
- First understand about the project by
|
|
231
|
-
- Always read relevant files before
|
|
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}
|
|
@@ -251,55 +251,71 @@ def execute_bash(
|
|
|
251
251
|
)
|
|
252
252
|
|
|
253
253
|
SHELL.sendline(command)
|
|
254
|
-
|
|
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
|
|
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:
|
|
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
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
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
|
-
|
|
474
|
-
|
|
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
|
-
|
|
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
|
|
@@ -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]
|
|
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'")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|