lvwerra HF Staff Claude Opus 4.7 (1M context) commited on
Commit
f01f8bd
·
1 Parent(s): 63274c0

Include sync.tools module for generated plans

Browse files

Plans generated by the planner model import from sync.tools.
Ship a minimal copy inside the space so plans can run.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Files changed (2) hide show
  1. sync/__init__.py +0 -0
  2. sync/tools.py +90 -0
sync/__init__.py ADDED
File without changes
sync/tools.py ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import subprocess
2
+ from pathlib import Path
3
+
4
+ try:
5
+ import httpx
6
+ _http = httpx.Client(timeout=30, follow_redirects=True)
7
+ except ImportError:
8
+ _http = None
9
+
10
+
11
+ def search(query: str) -> str:
12
+ """Search the web and return relevant results."""
13
+ if _http is None:
14
+ return (
15
+ f"[search stub for '{query}']: "
16
+ f"install httpx for real search")
17
+ resp = _http.get(
18
+ "https://html.duckduckgo.com/html/",
19
+ params={"q": query})
20
+ from html.parser import HTMLParser
21
+ results = []
22
+
23
+ class DDGParser(HTMLParser):
24
+ in_result = False
25
+ current = ""
26
+
27
+ def handle_starttag(self, tag, attrs):
28
+ attrs = dict(attrs)
29
+ if tag == "a" and "result__a" in attrs.get(
30
+ "class", ""):
31
+ self.in_result = True
32
+ self.current = attrs.get("href", "")
33
+
34
+ def handle_data(self, data):
35
+ if self.in_result:
36
+ results.append(
37
+ f"{data.strip()} ({self.current})")
38
+ self.in_result = False
39
+
40
+ DDGParser().feed(resp.text)
41
+ return "\n".join(results[:10]) or "No results found."
42
+
43
+
44
+ def fetch(url: str) -> str:
45
+ """Fetch a website URL and return its text content."""
46
+ if _http is None:
47
+ return f"[fetch stub for {url}]: install httpx"
48
+ resp = _http.get(url)
49
+ text = resp.text
50
+ if len(text) > 50000:
51
+ text = text[:50000] + "\n... (truncated)"
52
+ return text
53
+
54
+
55
+ def read_file(path: str) -> str:
56
+ """Read a file and return its contents."""
57
+ return Path(path).read_text()
58
+
59
+
60
+ def write_file(path: str, content: str) -> str:
61
+ """Write content to a file."""
62
+ Path(path).parent.mkdir(parents=True, exist_ok=True)
63
+ Path(path).write_text(content)
64
+ return f"Wrote {len(content)} bytes to {path}"
65
+
66
+
67
+ def run_command(command: str) -> str:
68
+ """Run a shell command and return stdout+stderr."""
69
+ result = subprocess.run(
70
+ command, shell=True,
71
+ capture_output=True, text=True, timeout=60)
72
+ output = result.stdout
73
+ if result.stderr:
74
+ output += f"\nSTDERR: {result.stderr}"
75
+ if result.returncode != 0:
76
+ output += f"\nEXIT CODE: {result.returncode}"
77
+ return output
78
+
79
+
80
+ def bash(script: str) -> str:
81
+ """Run a multi-line bash script."""
82
+ result = subprocess.run(
83
+ ["bash", "-c", script],
84
+ capture_output=True, text=True, timeout=300)
85
+ output = result.stdout
86
+ if result.stderr:
87
+ output += f"\nSTDERR: {result.stderr}"
88
+ if result.returncode != 0:
89
+ output += f"\nEXIT CODE: {result.returncode}"
90
+ return output