wcgw 3.0.1rc2__py3-none-any.whl → 3.0.1rc3__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.
- wcgw/client/bash_state/bash_state.py +64 -56
- wcgw/client/mcp_server/server.py +9 -17
- wcgw/client/tools.py +19 -1
- {wcgw-3.0.1rc2.dist-info → wcgw-3.0.1rc3.dist-info}/METADATA +1 -1
- {wcgw-3.0.1rc2.dist-info → wcgw-3.0.1rc3.dist-info}/RECORD +9 -9
- wcgw_cli/anthropic_client.py +4 -4
- {wcgw-3.0.1rc2.dist-info → wcgw-3.0.1rc3.dist-info}/WHEEL +0 -0
- {wcgw-3.0.1rc2.dist-info → wcgw-3.0.1rc3.dist-info}/entry_points.txt +0 -0
- {wcgw-3.0.1rc2.dist-info → wcgw-3.0.1rc3.dist-info}/licenses/LICENSE +0 -0
|
@@ -32,7 +32,8 @@ from ...types_ import (
|
|
|
32
32
|
from ..encoder import EncoderDecoder
|
|
33
33
|
from ..modes import BashCommandMode, FileEditMode, WriteIfEmptyMode
|
|
34
34
|
|
|
35
|
-
PROMPT_CONST = "
|
|
35
|
+
PROMPT_CONST = "wcgw→" + " "
|
|
36
|
+
PROMPT_STATEMENT = "export GIT_PAGER=cat PAGER=cat PROMPT_COMMAND= PS1='wcgw→'' '"
|
|
36
37
|
BASH_CLF_OUTPUT = Literal["repl", "pending"]
|
|
37
38
|
os.environ["TOKENIZERS_PARALLELISM"] = "false"
|
|
38
39
|
|
|
@@ -79,9 +80,7 @@ def get_tmpdir() -> str:
|
|
|
79
80
|
|
|
80
81
|
def check_if_screen_command_available() -> bool:
|
|
81
82
|
try:
|
|
82
|
-
subprocess.run(
|
|
83
|
-
["screen", "-v"], capture_output=True, check=True, timeout=CONFIG.timeout
|
|
84
|
-
)
|
|
83
|
+
subprocess.run(["screen", "-v"], capture_output=True, check=True, timeout=0.2)
|
|
85
84
|
return True
|
|
86
85
|
except (subprocess.CalledProcessError, FileNotFoundError):
|
|
87
86
|
return False
|
|
@@ -100,7 +99,7 @@ def cleanup_all_screens_with_name(name: str, console: Console) -> None:
|
|
|
100
99
|
capture_output=True,
|
|
101
100
|
text=True,
|
|
102
101
|
check=True,
|
|
103
|
-
timeout=
|
|
102
|
+
timeout=0.2,
|
|
104
103
|
)
|
|
105
104
|
output = result.stdout
|
|
106
105
|
except subprocess.CalledProcessError as e:
|
|
@@ -146,23 +145,21 @@ def start_shell(
|
|
|
146
145
|
**os.environ,
|
|
147
146
|
"PS1": PROMPT_CONST,
|
|
148
147
|
"TMPDIR": get_tmpdir(),
|
|
149
|
-
"TERM": "
|
|
148
|
+
"TERM": "xterm-256color",
|
|
150
149
|
}
|
|
151
150
|
try:
|
|
152
151
|
shell = pexpect.spawn(
|
|
153
152
|
cmd,
|
|
154
153
|
env=overrideenv, # type: ignore[arg-type]
|
|
155
|
-
echo=
|
|
154
|
+
echo=True,
|
|
156
155
|
encoding="utf-8",
|
|
157
156
|
timeout=CONFIG.timeout,
|
|
158
157
|
cwd=initial_dir,
|
|
159
158
|
codec_errors="backslashreplace",
|
|
160
159
|
dimensions=(500, 160),
|
|
161
160
|
)
|
|
162
|
-
shell.sendline(
|
|
163
|
-
|
|
164
|
-
) # Unset prompt command to avoid interfering
|
|
165
|
-
shell.expect(PROMPT_CONST, timeout=CONFIG.timeout)
|
|
161
|
+
shell.sendline(PROMPT_STATEMENT) # Unset prompt command to avoid interfering
|
|
162
|
+
shell.expect(PROMPT_CONST, timeout=0.2)
|
|
166
163
|
except Exception as e:
|
|
167
164
|
console.print(traceback.format_exc())
|
|
168
165
|
console.log(f"Error starting shell: {e}. Retrying without rc ...")
|
|
@@ -170,13 +167,13 @@ def start_shell(
|
|
|
170
167
|
shell = pexpect.spawn(
|
|
171
168
|
"/bin/bash --noprofile --norc",
|
|
172
169
|
env=overrideenv, # type: ignore[arg-type]
|
|
173
|
-
echo=
|
|
170
|
+
echo=True,
|
|
174
171
|
encoding="utf-8",
|
|
175
172
|
timeout=CONFIG.timeout,
|
|
176
173
|
codec_errors="backslashreplace",
|
|
177
174
|
)
|
|
178
|
-
shell.sendline(
|
|
179
|
-
shell.expect(PROMPT_CONST, timeout=
|
|
175
|
+
shell.sendline(PROMPT_STATEMENT)
|
|
176
|
+
shell.expect(PROMPT_CONST, timeout=0.2)
|
|
180
177
|
|
|
181
178
|
shellid = "wcgw." + time.strftime("%H%M%S")
|
|
182
179
|
if over_screen:
|
|
@@ -184,20 +181,11 @@ def start_shell(
|
|
|
184
181
|
raise ValueError("Screen command not available")
|
|
185
182
|
# shellid is just hour, minute, second number
|
|
186
183
|
shell.sendline(f"trap 'screen -X -S {shellid} quit' EXIT")
|
|
187
|
-
shell.expect(PROMPT_CONST, timeout=
|
|
184
|
+
shell.expect(PROMPT_CONST, timeout=0.2)
|
|
188
185
|
|
|
189
186
|
shell.sendline(f"screen -q -S {shellid} /bin/bash --noprofile --norc")
|
|
190
187
|
shell.expect(PROMPT_CONST, timeout=CONFIG.timeout)
|
|
191
188
|
|
|
192
|
-
shell.sendline("stty -icanon -echo")
|
|
193
|
-
shell.expect(PROMPT_CONST, timeout=CONFIG.timeout)
|
|
194
|
-
|
|
195
|
-
shell.sendline("set +o pipefail")
|
|
196
|
-
shell.expect(PROMPT_CONST, timeout=CONFIG.timeout)
|
|
197
|
-
|
|
198
|
-
shell.sendline("export GIT_PAGER=cat PAGER=cat")
|
|
199
|
-
shell.expect(PROMPT_CONST, timeout=CONFIG.timeout)
|
|
200
|
-
|
|
201
189
|
return shell, shellid
|
|
202
190
|
|
|
203
191
|
|
|
@@ -234,7 +222,9 @@ def requires_shell(
|
|
|
234
222
|
) -> Callable[Concatenate["BashState", P], R]:
|
|
235
223
|
def wrapper(self: "BashState", /, *args: P.args, **kwargs: P.kwargs) -> R:
|
|
236
224
|
if not self._shell_loading.is_set():
|
|
237
|
-
if not self._shell_loading.wait(
|
|
225
|
+
if not self._shell_loading.wait(
|
|
226
|
+
timeout=CONFIG.timeout * 2
|
|
227
|
+
): # Twice in worst case if screen fails
|
|
238
228
|
raise RuntimeError("Shell initialization timeout")
|
|
239
229
|
|
|
240
230
|
if self._shell_error:
|
|
@@ -278,7 +268,6 @@ class BashState:
|
|
|
278
268
|
)
|
|
279
269
|
self._mode = mode or Modes.wcgw
|
|
280
270
|
self._whitelist_for_overwrite: set[str] = whitelist_for_overwrite or set()
|
|
281
|
-
self._prompt = PROMPT_CONST
|
|
282
271
|
self._bg_expect_thread: Optional[threading.Thread] = None
|
|
283
272
|
self._bg_expect_thread_stop_event = threading.Event()
|
|
284
273
|
self._shell = None
|
|
@@ -296,6 +285,7 @@ class BashState:
|
|
|
296
285
|
if self._shell is not None:
|
|
297
286
|
return
|
|
298
287
|
self._init_shell()
|
|
288
|
+
self.run_bg_expect_thread()
|
|
299
289
|
except Exception as e:
|
|
300
290
|
self._shell_error = e
|
|
301
291
|
finally:
|
|
@@ -308,18 +298,19 @@ class BashState:
|
|
|
308
298
|
self, shell: "pexpect.spawn[str]", pattern: Any, timeout: Optional[float] = -1
|
|
309
299
|
) -> int:
|
|
310
300
|
self.close_bg_expect_thread()
|
|
311
|
-
|
|
301
|
+
output = shell.expect(pattern, timeout)
|
|
302
|
+
return output
|
|
312
303
|
|
|
313
304
|
@requires_shell
|
|
314
305
|
def send(self, shell: "pexpect.spawn[str]", s: str | bytes) -> int:
|
|
306
|
+
self.close_bg_expect_thread()
|
|
315
307
|
output = shell.send(s)
|
|
316
|
-
self.run_bg_expect_thread()
|
|
317
308
|
return output
|
|
318
309
|
|
|
319
310
|
@requires_shell
|
|
320
311
|
def sendline(self, shell: "pexpect.spawn[str]", s: str | bytes) -> int:
|
|
312
|
+
self.close_bg_expect_thread()
|
|
321
313
|
output = shell.sendline(s)
|
|
322
|
-
self.run_bg_expect_thread()
|
|
323
314
|
return output
|
|
324
315
|
|
|
325
316
|
@property
|
|
@@ -329,6 +320,7 @@ class BashState:
|
|
|
329
320
|
|
|
330
321
|
@requires_shell
|
|
331
322
|
def sendintr(self, shell: "pexpect.spawn[str]") -> None:
|
|
323
|
+
self.close_bg_expect_thread()
|
|
332
324
|
shell.sendintr()
|
|
333
325
|
|
|
334
326
|
@property
|
|
@@ -336,8 +328,7 @@ class BashState:
|
|
|
336
328
|
def before(self, shell: "pexpect.spawn[str]") -> Optional[str]:
|
|
337
329
|
return shell.before
|
|
338
330
|
|
|
339
|
-
|
|
340
|
-
def run_bg_expect_thread(self, shell: "pexpect.spawn[str]") -> None:
|
|
331
|
+
def run_bg_expect_thread(self) -> None:
|
|
341
332
|
"""
|
|
342
333
|
Run background expect thread for handling shell interactions.
|
|
343
334
|
"""
|
|
@@ -346,11 +337,16 @@ class BashState:
|
|
|
346
337
|
while True:
|
|
347
338
|
if self._bg_expect_thread_stop_event.is_set():
|
|
348
339
|
break
|
|
349
|
-
|
|
340
|
+
if self._shell is None:
|
|
341
|
+
time.sleep(0.1)
|
|
342
|
+
continue
|
|
343
|
+
output = self._shell.expect([pexpect.EOF, pexpect.TIMEOUT], timeout=0.1)
|
|
350
344
|
if output == 0:
|
|
351
345
|
break
|
|
352
346
|
|
|
353
|
-
if self._bg_expect_thread:
|
|
347
|
+
if self._bg_expect_thread and self._bg_expect_thread.is_alive():
|
|
348
|
+
if not self._bg_expect_thread_stop_event.is_set():
|
|
349
|
+
return
|
|
354
350
|
self.close_bg_expect_thread()
|
|
355
351
|
|
|
356
352
|
self._bg_expect_thread = threading.Thread(
|
|
@@ -403,28 +399,20 @@ class BashState:
|
|
|
403
399
|
|
|
404
400
|
def _ensure_env_and_bg_jobs(self) -> Optional[int]:
|
|
405
401
|
# Do not add @requires_shell decorator here, as it will cause deadlock
|
|
406
|
-
|
|
407
402
|
self.close_bg_expect_thread()
|
|
408
403
|
assert self._shell is not None, "Bad state, shell is not initialized"
|
|
409
|
-
if self._prompt != PROMPT_CONST:
|
|
410
|
-
return None
|
|
411
404
|
quick_timeout = 0.2 if not self.over_screen else 1
|
|
412
405
|
# First reset the prompt in case venv was sourced or other reasons.
|
|
413
|
-
self._shell.sendline(
|
|
414
|
-
self._shell.expect(
|
|
406
|
+
self._shell.sendline(PROMPT_STATEMENT)
|
|
407
|
+
self._shell.expect(PROMPT_CONST, timeout=quick_timeout)
|
|
415
408
|
# Reset echo also if it was enabled
|
|
416
|
-
|
|
417
|
-
self._shell.
|
|
418
|
-
self._shell.sendline("set +o pipefail")
|
|
419
|
-
self._shell.expect(self._prompt, timeout=quick_timeout)
|
|
420
|
-
self._shell.sendline("export GIT_PAGER=cat PAGER=cat")
|
|
421
|
-
self._shell.expect(self._prompt, timeout=quick_timeout)
|
|
422
|
-
self._shell.sendline("jobs | wc -l")
|
|
409
|
+
command = "jobs | wc -l"
|
|
410
|
+
self._shell.sendline(command)
|
|
423
411
|
before = ""
|
|
424
412
|
counts = 0
|
|
425
413
|
while not _is_int(before): # Consume all previous output
|
|
426
414
|
try:
|
|
427
|
-
self._shell.expect(
|
|
415
|
+
self._shell.expect(PROMPT_CONST, timeout=quick_timeout)
|
|
428
416
|
except pexpect.TIMEOUT:
|
|
429
417
|
self.console.print(f"Couldn't get exit code, before: {before}")
|
|
430
418
|
raise
|
|
@@ -434,20 +422,18 @@ class BashState:
|
|
|
434
422
|
before_val = str(before_val)
|
|
435
423
|
assert isinstance(before_val, str)
|
|
436
424
|
before_lines = render_terminal_output(before_val)
|
|
437
|
-
before = "\n".join(before_lines).strip()
|
|
425
|
+
before = "\n".join(before_lines).replace(command, "").strip()
|
|
438
426
|
counts += 1
|
|
439
427
|
if counts > 100:
|
|
440
428
|
raise ValueError(
|
|
441
429
|
"Error in understanding shell output. This shouldn't happen, likely shell is in a bad state, please reset it"
|
|
442
430
|
)
|
|
443
|
-
|
|
444
431
|
try:
|
|
445
432
|
return int(before)
|
|
446
433
|
except ValueError:
|
|
447
434
|
raise ValueError(f"Malformed output: {before}")
|
|
448
435
|
|
|
449
436
|
def _init_shell(self) -> None:
|
|
450
|
-
self._prompt = PROMPT_CONST
|
|
451
437
|
self._state: Literal["repl"] | datetime.datetime = "repl"
|
|
452
438
|
self._is_in_docker: Optional[str] = ""
|
|
453
439
|
# Ensure self._cwd exists
|
|
@@ -474,13 +460,15 @@ class BashState:
|
|
|
474
460
|
self.over_screen = False
|
|
475
461
|
|
|
476
462
|
self._pending_output = ""
|
|
477
|
-
|
|
463
|
+
try:
|
|
464
|
+
self._ensure_env_and_bg_jobs()
|
|
465
|
+
except ValueError as e:
|
|
466
|
+
self.console.log("Error while running _ensure_env_and_bg_jobs" + str(e))
|
|
478
467
|
|
|
479
468
|
def set_pending(self, last_pending_output: str) -> None:
|
|
480
469
|
if not isinstance(self._state, datetime.datetime):
|
|
481
470
|
self._state = datetime.datetime.now()
|
|
482
471
|
self._pending_output = last_pending_output
|
|
483
|
-
self.run_bg_expect_thread()
|
|
484
472
|
|
|
485
473
|
def set_repl(self) -> None:
|
|
486
474
|
self._state = "repl"
|
|
@@ -505,12 +493,12 @@ class BashState:
|
|
|
505
493
|
|
|
506
494
|
@property
|
|
507
495
|
def prompt(self) -> str:
|
|
508
|
-
return
|
|
496
|
+
return PROMPT_CONST
|
|
509
497
|
|
|
510
498
|
@requires_shell
|
|
511
499
|
def update_cwd(self, shell: "pexpect.spawn[str]") -> str:
|
|
512
500
|
shell.sendline("pwd")
|
|
513
|
-
shell.expect(
|
|
501
|
+
shell.expect(PROMPT_CONST, timeout=0.2)
|
|
514
502
|
before_val = shell.before
|
|
515
503
|
if not isinstance(before_val, str):
|
|
516
504
|
before_val = str(before_val)
|
|
@@ -637,9 +625,8 @@ def _incremental_text(text: str, last_pending_output: str) -> str:
|
|
|
637
625
|
# text = render_terminal_output(text[-100_000:])
|
|
638
626
|
text = text[-100_000:]
|
|
639
627
|
|
|
640
|
-
|
|
641
|
-
last_pending_output_rendered = "\n".join(
|
|
642
|
-
last_rendered_lines = last_pending_output_rendered.split("\n")
|
|
628
|
+
last_rendered_lines = render_terminal_output(last_pending_output)
|
|
629
|
+
last_pending_output_rendered = "\n".join(last_rendered_lines)
|
|
643
630
|
if not last_rendered_lines:
|
|
644
631
|
return rstrip(render_terminal_output(text))
|
|
645
632
|
|
|
@@ -690,6 +677,27 @@ def execute_bash(
|
|
|
690
677
|
bash_arg: BashCommand,
|
|
691
678
|
max_tokens: Optional[int],
|
|
692
679
|
timeout_s: Optional[float],
|
|
680
|
+
) -> tuple[str, float]:
|
|
681
|
+
try:
|
|
682
|
+
output, cost = _execute_bash(bash_state, enc, bash_arg, max_tokens, timeout_s)
|
|
683
|
+
|
|
684
|
+
# Remove echo if it's a command
|
|
685
|
+
if isinstance(bash_arg.action, Command):
|
|
686
|
+
command = bash_arg.action.command.strip()
|
|
687
|
+
if output.startswith(command):
|
|
688
|
+
output = output[len(command) :]
|
|
689
|
+
|
|
690
|
+
finally:
|
|
691
|
+
bash_state.run_bg_expect_thread()
|
|
692
|
+
return output, cost
|
|
693
|
+
|
|
694
|
+
|
|
695
|
+
def _execute_bash(
|
|
696
|
+
bash_state: BashState,
|
|
697
|
+
enc: EncoderDecoder[int],
|
|
698
|
+
bash_arg: BashCommand,
|
|
699
|
+
max_tokens: Optional[int],
|
|
700
|
+
timeout_s: Optional[float],
|
|
693
701
|
) -> tuple[str, float]:
|
|
694
702
|
try:
|
|
695
703
|
is_interrupt = False
|
wcgw/client/mcp_server/server.py
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import importlib
|
|
2
|
-
import json
|
|
3
2
|
import logging
|
|
4
3
|
import os
|
|
5
4
|
from typing import Any
|
|
@@ -9,7 +8,7 @@ import mcp_wcgw.types as types
|
|
|
9
8
|
from mcp_wcgw.server import NotificationOptions, Server
|
|
10
9
|
from mcp_wcgw.server.models import InitializationOptions
|
|
11
10
|
from mcp_wcgw.types import Tool as ToolParam
|
|
12
|
-
from pydantic import AnyUrl
|
|
11
|
+
from pydantic import AnyUrl
|
|
13
12
|
|
|
14
13
|
from wcgw.client.modes import KTS
|
|
15
14
|
from wcgw.client.tool_prompts import TOOL_PROMPTS
|
|
@@ -18,7 +17,13 @@ from ...types_ import (
|
|
|
18
17
|
Initialize,
|
|
19
18
|
)
|
|
20
19
|
from ..bash_state.bash_state import CONFIG, BashState
|
|
21
|
-
from ..tools import
|
|
20
|
+
from ..tools import (
|
|
21
|
+
Context,
|
|
22
|
+
default_enc,
|
|
23
|
+
get_tool_output,
|
|
24
|
+
parse_tool_by_name,
|
|
25
|
+
which_tool_name,
|
|
26
|
+
)
|
|
22
27
|
|
|
23
28
|
server = Server("wcgw")
|
|
24
29
|
|
|
@@ -104,20 +109,7 @@ async def handle_call_tool(
|
|
|
104
109
|
raise ValueError("Missing arguments")
|
|
105
110
|
|
|
106
111
|
tool_type = which_tool_name(name)
|
|
107
|
-
|
|
108
|
-
try:
|
|
109
|
-
tool_call = tool_type(**arguments)
|
|
110
|
-
except ValidationError:
|
|
111
|
-
|
|
112
|
-
def try_json(x: str) -> Any:
|
|
113
|
-
if not isinstance(x, str):
|
|
114
|
-
return x
|
|
115
|
-
try:
|
|
116
|
-
return json.loads(x)
|
|
117
|
-
except json.JSONDecodeError:
|
|
118
|
-
return x
|
|
119
|
-
|
|
120
|
-
tool_call = tool_type(**{k: try_json(v) for k, v in arguments.items()})
|
|
112
|
+
tool_call = parse_tool_by_name(name, arguments)
|
|
121
113
|
|
|
122
114
|
try:
|
|
123
115
|
assert BASH_STATE
|
wcgw/client/tools.py
CHANGED
|
@@ -10,6 +10,7 @@ from os.path import expanduser
|
|
|
10
10
|
from pathlib import Path
|
|
11
11
|
from tempfile import NamedTemporaryFile
|
|
12
12
|
from typing import (
|
|
13
|
+
Any,
|
|
13
14
|
Callable,
|
|
14
15
|
Literal,
|
|
15
16
|
Optional,
|
|
@@ -21,7 +22,7 @@ from typing import (
|
|
|
21
22
|
from openai.types.chat import (
|
|
22
23
|
ChatCompletionMessageParam,
|
|
23
24
|
)
|
|
24
|
-
from pydantic import BaseModel, TypeAdapter
|
|
25
|
+
from pydantic import BaseModel, TypeAdapter, ValidationError
|
|
25
26
|
from syntax_checker import check_syntax
|
|
26
27
|
|
|
27
28
|
from wcgw.client.bash_state.bash_state import get_status
|
|
@@ -549,6 +550,23 @@ def which_tool_name(name: str) -> Type[TOOLS]:
|
|
|
549
550
|
raise ValueError(f"Unknown tool name: {name}")
|
|
550
551
|
|
|
551
552
|
|
|
553
|
+
def parse_tool_by_name(name: str, arguments: dict[str, Any]) -> TOOLS:
|
|
554
|
+
tool_type = which_tool_name(name)
|
|
555
|
+
try:
|
|
556
|
+
return tool_type(**arguments)
|
|
557
|
+
except ValidationError:
|
|
558
|
+
|
|
559
|
+
def try_json(x: str) -> Any:
|
|
560
|
+
if not isinstance(x, str):
|
|
561
|
+
return x
|
|
562
|
+
try:
|
|
563
|
+
return json.loads(x)
|
|
564
|
+
except json.JSONDecodeError:
|
|
565
|
+
return x
|
|
566
|
+
|
|
567
|
+
return tool_type(**{k: try_json(v) for k, v in arguments.items()})
|
|
568
|
+
|
|
569
|
+
|
|
552
570
|
TOOL_CALLS: list[TOOLS] = []
|
|
553
571
|
|
|
554
572
|
|
|
@@ -7,14 +7,14 @@ wcgw/client/diff-instructions.txt,sha256=tmJ9Fu9XdO_72lYXQQNY9RZyx91bjxrXJf9d_KB
|
|
|
7
7
|
wcgw/client/memory.py,sha256=8LdYsOhvCOoC1kfvDr85kNy07WnhPMvE6B2FRM2w85Y,2902
|
|
8
8
|
wcgw/client/modes.py,sha256=dBkiMNQevTFNkhplrDsDuSIyeU-wLmAIfAa9Dqowvk8,10387
|
|
9
9
|
wcgw/client/tool_prompts.py,sha256=j82aYnlr1pcinsOYitSrlyYz4-9K3KcqnAfGqot21NQ,4158
|
|
10
|
-
wcgw/client/tools.py,sha256=
|
|
11
|
-
wcgw/client/bash_state/bash_state.py,sha256=
|
|
10
|
+
wcgw/client/tools.py,sha256=caj10NHeK5tZ5Gi0L_oXzPcKBycgXeNaLEbXAzYTpqo,23170
|
|
11
|
+
wcgw/client/bash_state/bash_state.py,sha256=2cxzYN6x-vEJ4oasrCgoRyVQKpARKONcaNDLfLPDTG8,29476
|
|
12
12
|
wcgw/client/encoder/__init__.py,sha256=Y-8f43I6gMssUCWpX5rLYiAFv3D-JPRs4uNEejPlke8,1514
|
|
13
13
|
wcgw/client/file_ops/diff_edit.py,sha256=sIwXSSkWYff_Dp3oHfefqtSuFqLrxbhKvzkCoLuLqDE,18679
|
|
14
14
|
wcgw/client/file_ops/search_replace.py,sha256=Napa7IWaYPGMNdttunKyRDkb90elZE7r23B_o_htRxo,5585
|
|
15
15
|
wcgw/client/mcp_server/Readme.md,sha256=2Z88jj1mf9daYGW1CWaldcJ0moy8owDumhR2glBY3A8,109
|
|
16
16
|
wcgw/client/mcp_server/__init__.py,sha256=mm7xhBIPwJpRT3u-Qsj4cKVMpVyucJoKRlbMP_gRRB0,343
|
|
17
|
-
wcgw/client/mcp_server/server.py,sha256=
|
|
17
|
+
wcgw/client/mcp_server/server.py,sha256=ayK6qbzCveoQW7RO80m10cAIS3m-hvxzd15XhjiyxmE,5055
|
|
18
18
|
wcgw/client/repo_ops/display_tree.py,sha256=E5q9mrGBb57NyvudSmRIG-fj4FUqupbzjmARpX8X0XY,4166
|
|
19
19
|
wcgw/client/repo_ops/path_prob.py,sha256=SWf0CDn37rtlsYRQ51ufSxay-heaQoVIhr1alB9tZ4M,2144
|
|
20
20
|
wcgw/client/repo_ops/paths_model.vocab,sha256=M1pXycYDQehMXtpp-qAgU7rtzeBbCOiJo4qcYFY0kqk,315087
|
|
@@ -25,7 +25,7 @@ wcgw/relay/serve.py,sha256=Ofq6PjW3zVVA2-9MVviGRiUESTD3sXb-482Q4RV13q8,8664
|
|
|
25
25
|
wcgw/relay/static/privacy.txt,sha256=s9qBdbx2SexCpC_z33sg16TptmAwDEehMCLz4L50JLc,529
|
|
26
26
|
wcgw_cli/__init__.py,sha256=TNxXsTPgb52OhakIda9wTRh91cqoBqgQRx5TxjzQQFU,21
|
|
27
27
|
wcgw_cli/__main__.py,sha256=wcCrL4PjG51r5wVKqJhcoJPTLfHW0wNbD31DrUN0MWI,28
|
|
28
|
-
wcgw_cli/anthropic_client.py,sha256=
|
|
28
|
+
wcgw_cli/anthropic_client.py,sha256=2QLFBLbMeQuixF7Pz9j_hINHTG1CF9IYQZeri7zFuF0,18964
|
|
29
29
|
wcgw_cli/cli.py,sha256=-7FBe_lahKyUOhf65iurTA1M1gXXXAiT0OVKQVcZKKo,948
|
|
30
30
|
wcgw_cli/openai_client.py,sha256=oMFAaOkvXQtOY7choylVRJfaF2SnWvRc02ygQhlhVqY,15995
|
|
31
31
|
wcgw_cli/openai_utils.py,sha256=xGOb3W5ALrIozV7oszfGYztpj0FnXdD7jAxm5lEIVKY,2439
|
|
@@ -51,8 +51,8 @@ mcp_wcgw/shared/memory.py,sha256=dBsOghxHz8-tycdSVo9kSujbsC8xb_tYsGmuJobuZnw,281
|
|
|
51
51
|
mcp_wcgw/shared/progress.py,sha256=ymxOsb8XO5Mhlop7fRfdbmvPodANj7oq6O4dD0iUcnw,1048
|
|
52
52
|
mcp_wcgw/shared/session.py,sha256=e44a0LQOW8gwdLs9_DE9oDsxqW2U8mXG3d5KT95bn5o,10393
|
|
53
53
|
mcp_wcgw/shared/version.py,sha256=d2LZii-mgsPIxpshjkXnOTUmk98i0DT4ff8VpA_kAvE,111
|
|
54
|
-
wcgw-3.0.
|
|
55
|
-
wcgw-3.0.
|
|
56
|
-
wcgw-3.0.
|
|
57
|
-
wcgw-3.0.
|
|
58
|
-
wcgw-3.0.
|
|
54
|
+
wcgw-3.0.1rc3.dist-info/METADATA,sha256=ymiydLYH56IAV_8FKq98BrGf-tt7Vwumtc8nUBvzs50,13005
|
|
55
|
+
wcgw-3.0.1rc3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
56
|
+
wcgw-3.0.1rc3.dist-info/entry_points.txt,sha256=vd3tj1_Kzfp55LscJ8-6WFMM5hm9cWTfNGFCrWBnH3Q,124
|
|
57
|
+
wcgw-3.0.1rc3.dist-info/licenses/LICENSE,sha256=BvY8xqjOfc3X2qZpGpX3MZEmF-4Dp0LqgKBbT6L_8oI,11142
|
|
58
|
+
wcgw-3.0.1rc3.dist-info/RECORD,,
|
wcgw_cli/anthropic_client.py
CHANGED
|
@@ -35,7 +35,7 @@ from wcgw.client.tools import (
|
|
|
35
35
|
default_enc,
|
|
36
36
|
get_tool_output,
|
|
37
37
|
initialize,
|
|
38
|
-
|
|
38
|
+
parse_tool_by_name,
|
|
39
39
|
)
|
|
40
40
|
|
|
41
41
|
|
|
@@ -379,9 +379,9 @@ def loop(
|
|
|
379
379
|
tool_input = str(tc["input"])
|
|
380
380
|
tool_id = str(tc["id"])
|
|
381
381
|
|
|
382
|
-
tool_parsed =
|
|
383
|
-
tool_name
|
|
384
|
-
)
|
|
382
|
+
tool_parsed = parse_tool_by_name(
|
|
383
|
+
tool_name, json.loads(tool_input)
|
|
384
|
+
)
|
|
385
385
|
|
|
386
386
|
system_console.print(
|
|
387
387
|
f"\n---------------------------------------\n# Assistant invoked tool: {tool_parsed}"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|