langroid 0.16.7__py3-none-any.whl → 0.17.1__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.
Files changed (91) hide show
  1. langroid/agent/base.py +45 -21
  2. langroid/agent/chat_agent.py +22 -14
  3. langroid/agent/chat_document.py +22 -13
  4. langroid/agent/tool_message.py +11 -11
  5. langroid/agent/tools/file_tools.py +234 -0
  6. langroid/agent/xml_tool_message.py +179 -45
  7. langroid/utils/constants.py +2 -0
  8. langroid/utils/git_utils.py +251 -0
  9. langroid/utils/system.py +78 -0
  10. {langroid-0.16.7.dist-info → langroid-0.17.1.dist-info}/METADATA +6 -3
  11. {langroid-0.16.7.dist-info → langroid-0.17.1.dist-info}/RECORD +14 -89
  12. pyproject.toml +3 -2
  13. langroid/agent/md_tool_message_grammar.py +0 -455
  14. langroid/agent/tools/code_file_tool_parse.py +0 -150
  15. langroid/agent/tools/code_file_tool_pyparsing.py +0 -194
  16. langroid/agent/tools/code_file_tool_pyparsing2.py +0 -199
  17. langroid/agent/tools/extract_tool.py +0 -96
  18. langroid/agent/tools/formatted_model_custom.py +0 -150
  19. langroid/agent/tools/formatted_model_custom2.py +0 -168
  20. langroid/agent/tools/formatted_model_custom3.py +0 -279
  21. langroid/agent/tools/formatted_model_custom4.py +0 -395
  22. langroid/agent/tools/formatted_model_jinja.py +0 -133
  23. langroid/agent/tools/formatted_model_jinja.py-e +0 -122
  24. langroid/agent/tools/formatted_model_jinja2.py +0 -145
  25. langroid/agent/tools/formatted_model_jinja2.py-e +0 -135
  26. langroid/agent/tools/formatted_model_lark.py +0 -0
  27. langroid/agent/tools/formatted_model_lark2.py +0 -168
  28. langroid/agent/tools/formatted_model_parse.py +0 -105
  29. langroid/agent/tools/formatted_model_parse.py-e +0 -98
  30. langroid/agent/tools/formatted_model_parse2.py +0 -113
  31. langroid/agent/tools/formatted_model_parse2.py-e +0 -109
  32. langroid/agent/tools/formatted_model_parse3.py +0 -114
  33. langroid/agent/tools/formatted_model_parse3.py-e +0 -110
  34. langroid/agent/tools/formatted_model_parsimon.py +0 -194
  35. langroid/agent/tools/formatted_model_parsimon.py-e +0 -186
  36. langroid/agent/tools/formatted_model_pyparsing.py +0 -169
  37. langroid/agent/tools/formatted_model_pyparsing.py-e +0 -149
  38. langroid/agent/tools/formatted_model_pyparsing2.py +0 -159
  39. langroid/agent/tools/formatted_model_pyparsing2.py-e +0 -143
  40. langroid/agent/tools/formatted_model_pyparsing3.py +0 -133
  41. langroid/agent/tools/formatted_model_pyparsing3.py-e +0 -121
  42. langroid/agent/tools/formatted_model_pyparsing4.py +0 -213
  43. langroid/agent/tools/formatted_model_pyparsing4.py-e +0 -176
  44. langroid/agent/tools/formatted_model_pyparsing5.py +0 -173
  45. langroid/agent/tools/formatted_model_pyparsing5.py-e +0 -142
  46. langroid/agent/tools/formatted_model_regex.py +0 -246
  47. langroid/agent/tools/formatted_model_regex.py-e +0 -248
  48. langroid/agent/tools/formatted_model_regex2.py +0 -250
  49. langroid/agent/tools/formatted_model_regex2.py-e +0 -253
  50. langroid/agent/tools/formatted_model_tatsu.py +0 -172
  51. langroid/agent/tools/formatted_model_tatsu.py-e +0 -160
  52. langroid/agent/tools/formatted_model_template.py +0 -217
  53. langroid/agent/tools/formatted_model_template.py-e +0 -200
  54. langroid/agent/tools/formatted_model_xml.py +0 -178
  55. langroid/agent/tools/formatted_model_xml2.py +0 -178
  56. langroid/agent/tools/formatted_model_xml3.py +0 -132
  57. langroid/agent/tools/formatted_model_xml4.py +0 -130
  58. langroid/agent/tools/formatted_model_xml5.py +0 -130
  59. langroid/agent/tools/formatted_model_xml6.py +0 -113
  60. langroid/agent/tools/formatted_model_xml7.py +0 -117
  61. langroid/agent/tools/formatted_model_xml8.py +0 -164
  62. langroid/agent/tools/generator_tool.py +0 -20
  63. langroid/agent/tools/generic_tool.py +0 -165
  64. langroid/agent/tools/generic_tool_tatsu.py +0 -275
  65. langroid/agent/tools/grammar_based_model.py +0 -132
  66. langroid/agent/tools/grammar_based_model.py-e +0 -128
  67. langroid/agent/tools/grammar_based_model_lark.py +0 -156
  68. langroid/agent/tools/grammar_based_model_lark.py-e +0 -153
  69. langroid/agent/tools/grammar_based_model_parse.py +0 -86
  70. langroid/agent/tools/grammar_based_model_parse.py-e +0 -80
  71. langroid/agent/tools/grammar_based_model_parsimonious.py +0 -129
  72. langroid/agent/tools/grammar_based_model_parsimonious.py-e +0 -120
  73. langroid/agent/tools/grammar_based_model_pyparsing.py +0 -105
  74. langroid/agent/tools/grammar_based_model_pyparsing.py-e +0 -103
  75. langroid/agent/tools/grammar_based_model_regex.py +0 -139
  76. langroid/agent/tools/grammar_based_model_regex.py-e +0 -130
  77. langroid/agent/tools/grammar_based_model_regex2.py +0 -124
  78. langroid/agent/tools/grammar_based_model_regex2.py-e +0 -116
  79. langroid/agent/tools/grammar_based_model_tatsu.py +0 -80
  80. langroid/agent/tools/grammar_based_model_tatsu.py-e +0 -77
  81. langroid/agent/tools/lark_earley_example.py +0 -135
  82. langroid/agent/tools/lark_earley_example.py-e +0 -117
  83. langroid/agent/tools/lark_example.py +0 -72
  84. langroid/agent/tools/note_tool.py +0 -0
  85. langroid/agent/tools/parse_example.py +0 -76
  86. langroid/agent/tools/parse_example2.py +0 -87
  87. langroid/agent/tools/parse_example3.py +0 -42
  88. langroid/agent/tools/parse_test.py +0 -791
  89. langroid/agent/tools/run_python_code.py +0 -60
  90. {langroid-0.16.7.dist-info → langroid-0.17.1.dist-info}/LICENSE +0 -0
  91. {langroid-0.16.7.dist-info → langroid-0.17.1.dist-info}/WHEEL +0 -0
@@ -1,246 +0,0 @@
1
- import re
2
- from abc import ABC, abstractmethod
3
- from typing import Dict, Type, TypeVar
4
-
5
- from langroid.pydantic_v1 import BaseModel
6
-
7
- T = TypeVar("T", bound="FormattingModel")
8
-
9
-
10
- class FormattingModel(BaseModel, ABC):
11
- @classmethod
12
- @abstractmethod
13
- def format_spec(cls) -> str:
14
- pass
15
-
16
- @classmethod
17
- @abstractmethod
18
- def start_token(cls) -> str:
19
- pass
20
-
21
- @classmethod
22
- @abstractmethod
23
- def end_token(cls) -> str:
24
- pass
25
-
26
- @classmethod
27
- @abstractmethod
28
- def field_mappings(cls) -> Dict[str, str]:
29
- pass
30
-
31
- @classmethod
32
- def parse(cls: Type[T], text: str) -> T:
33
- # Remove start and end tokens
34
- content = text.strip()[len(cls.start_token()) : -len(cls.end_token())].strip()
35
-
36
- # Create regex pattern from format_spec
37
- pattern = cls.format_spec()
38
- for field, token in cls.field_mappings().items():
39
- pattern = pattern.replace(token, f"(?P<{field}>.*?)")
40
-
41
- # Extract data using regex
42
- match = re.match(pattern, content, re.DOTALL)
43
- if not match:
44
- raise ValueError("Invalid format")
45
-
46
- # Create instance with extracted data
47
- data = {field: match.group(field).strip() for field in cls.field_mappings()}
48
- return cls(**data)
49
-
50
- def generate(self) -> str:
51
- # Start with the format spec
52
- result = self.format_spec()
53
-
54
- # Replace tokens with actual values
55
- for field, token in self.field_mappings().items():
56
- value = getattr(self, field)
57
- result = result.replace(token, str(value))
58
-
59
- # Wrap with start and end tokens
60
- return f"{self.start_token()}\n{result}\n{self.end_token()}"
61
-
62
-
63
- class MyFormattedModel(FormattingModel):
64
- name: str
65
- age: int
66
- city: str
67
-
68
- @classmethod
69
- def format_spec(cls) -> str:
70
- return "name: {NAME}\n{AGE} is the age\nlives in {CITY}"
71
-
72
- @classmethod
73
- def start_token(cls) -> str:
74
- return "<format>"
75
-
76
- @classmethod
77
- def end_token(cls) -> str:
78
- return "</format>"
79
-
80
- @classmethod
81
- def field_mappings(cls) -> Dict[str, str]:
82
- return {"name": "{NAME}", "age": "{AGE}", "city": "{CITY}"}
83
-
84
-
85
- if __name__ == "__main__":
86
- # Test object to string
87
- model = MyFormattedModel(name="John", age=30, city="Tokyo")
88
- generated = model.generate()
89
- print("Generated string:")
90
- print(generated)
91
- print()
92
-
93
- # Test string to object
94
- parsed = MyFormattedModel.parse(generated)
95
- print("Parsed object:")
96
- print(parsed)
97
- print()
98
-
99
- # Test round-trip
100
- print("Round-trip test:")
101
- print("Original == Parsed:", model == parsed)
102
-
103
- # Test with different values
104
- another_model = MyFormattedModel(name="Alice", age=25, city="New York")
105
- another_generated = another_model.generate()
106
- print("\nAnother generated string:")
107
- print(another_generated)
108
- print()
109
-
110
- another_parsed = MyFormattedModel.parse(another_generated)
111
- print("Another parsed object:")
112
- print(another_parsed)
113
- print("Another Original == Another Parsed:", another_model == another_parsed)
114
-
115
- # code file model
116
- class CodeFileModel(FormattingModel):
117
- language: str
118
- file_path: str
119
- code: str
120
-
121
- @classmethod
122
- def format_spec(cls) -> str:
123
- return "code_file_model\nfile_path: {FILE_PATH}\n```{LANGUAGE}\n{CODE}\n```"
124
-
125
- @classmethod
126
- def start_token(cls) -> str:
127
- return "<format>"
128
-
129
- @classmethod
130
- def end_token(cls) -> str:
131
- return "</format>"
132
-
133
- @classmethod
134
- def field_mappings(cls) -> Dict[str, str]:
135
- return {
136
- "file_path": "{FILE_PATH}",
137
- "language": "{LANGUAGE}",
138
- "code": "{CODE}",
139
- }
140
-
141
- print("\nTesting CodeFileModel:")
142
- code_model = CodeFileModel(
143
- language="python",
144
- file_path="src/main.py",
145
- code='def hello():\n print("Hello, World!")',
146
- )
147
- code_generated = code_model.generate()
148
- print("Generated CodeFileModel string:")
149
- print(code_generated)
150
- print()
151
-
152
- code_parsed = CodeFileModel.parse(code_generated)
153
- print("Parsed CodeFileModel object:")
154
- print(code_parsed)
155
- print()
156
-
157
- print("CodeFileModel Round-trip test:")
158
- print("Original == Parsed:", code_model == code_parsed)
159
-
160
- # tolerant format
161
- #
162
- class CodeFileModel(FormattingModel):
163
- language: str
164
- file_path: str
165
- code: str
166
-
167
- @classmethod
168
- def format_spec(cls) -> str:
169
- return (
170
- r"code_file_model\s*\n"
171
- r"file_path:\s*{FILE_PATH}\s*\n"
172
- r"```\s*{LANGUAGE}\s*\n"
173
- r"{CODE}\s*"
174
- r"```"
175
- )
176
-
177
- @classmethod
178
- def start_token(cls) -> str:
179
- return "<format>"
180
-
181
- @classmethod
182
- def end_token(cls) -> str:
183
- return "</format>"
184
-
185
- @classmethod
186
- def field_mappings(cls) -> Dict[str, str]:
187
- return {
188
- "file_path": "{FILE_PATH}",
189
- "language": "{LANGUAGE}",
190
- "code": "{CODE}",
191
- }
192
-
193
- print("\nTesting CodeFileModel with various whitespace variations:")
194
-
195
- test_strings = [
196
- # Standard format
197
- """<format>
198
- code_file_model
199
- file_path: src/main.py
200
- ```python
201
- def hello():
202
- print("Hello, World!")
203
- ```
204
- </format>""",
205
- # Extra whitespace
206
- """<format>
207
- code_file_model
208
- file_path: src/main.py
209
- ``` python
210
- def hello():
211
- print("Hello, World!")
212
- ```
213
- </format>""",
214
- # Extra newlines
215
- """<format>
216
- code_file_model
217
-
218
- file_path: src/main.py
219
-
220
- ```python
221
-
222
- def hello():
223
- print("Hello, World!")
224
-
225
- ```
226
-
227
- </format>""",
228
- ]
229
-
230
- for i, test_string in enumerate(test_strings, 1):
231
- print(f"\nTest {i}:")
232
- print("Input string:")
233
- print(test_string)
234
-
235
- parsed = CodeFileModel.parse(test_string)
236
- print("\nParsed object:")
237
- print(parsed)
238
-
239
- regenerated = parsed.generate()
240
- print("\nRegenerated string:")
241
- print(regenerated)
242
-
243
- reparsed = CodeFileModel.parse(regenerated)
244
- print("\nRound-trip test:")
245
- print("Original parsed == Reparsed:", parsed == reparsed)
246
- print("-" * 50)
@@ -1,248 +0,0 @@
1
- from pydantic import BaseModel
2
- from abc import ABC, abstractmethod
3
- import re
4
- from typing import Dict, Type, TypeVar
5
-
6
- T = TypeVar('T', bound='FormattingModel')
7
-
8
- class FormattingModel(BaseModel, ABC):
9
- @classmethod
10
- @abstractmethod
11
- def format_spec(cls) -> str:
12
- pass
13
-
14
- @classmethod
15
- @abstractmethod
16
- def start_token(cls) -> str:
17
- pass
18
-
19
- @classmethod
20
- @abstractmethod
21
- def end_token(cls) -> str:
22
- pass
23
-
24
- @classmethod
25
- @abstractmethod
26
- def field_mappings(cls) -> Dict[str, str]:
27
- pass
28
-
29
- @classmethod
30
- def parse(cls: Type[T], text: str) -> T:
31
- # Remove start and end tokens
32
- content = text.strip()[len(cls.start_token()):-len(cls.end_token())].strip()
33
-
34
- # Create regex pattern from format_spec
35
- pattern = cls.format_spec()
36
- for field, token in cls.field_mappings().items():
37
- pattern = pattern.replace(token, f"(?P<{field}>.*?)")
38
-
39
- # Extract data using regex
40
- match = re.match(pattern, content, re.DOTALL)
41
- if not match:
42
- raise ValueError("Invalid format")
43
-
44
- # Create instance with extracted data
45
- data = {field: match.group(field).strip() for field in cls.field_mappings()}
46
- return cls(**data)
47
-
48
- def generate(self) -> str:
49
- # Start with the format spec
50
- result = self.format_spec()
51
-
52
- # Replace tokens with actual values
53
- for field, token in self.field_mappings().items():
54
- value = getattr(self, field)
55
- result = result.replace(token, str(value))
56
-
57
- # Wrap with start and end tokens
58
- return f"{self.start_token()}\n{result}\n{self.end_token()}"
59
-
60
- class MyFormattedModel(FormattingModel):
61
- name: str
62
- age: int
63
- city: str
64
-
65
- @classmethod
66
- def format_spec(cls) -> str:
67
- return "name: {NAME}\n{AGE} is the age\nlives in {CITY}"
68
-
69
- @classmethod
70
- def start_token(cls) -> str:
71
- return "<format>"
72
-
73
- @classmethod
74
- def end_token(cls) -> str:
75
- return "</format>"
76
-
77
- @classmethod
78
- def field_mappings(cls) -> Dict[str, str]:
79
- return {
80
- "name": "{NAME}",
81
- "age": "{AGE}",
82
- "city": "{CITY}"
83
- }
84
-
85
- if __name__ == "__main__":
86
- # Test object to string
87
- model = MyFormattedModel(name="John", age=30, city="Tokyo")
88
- generated = model.generate()
89
- print("Generated string:")
90
- print(generated)
91
- print()
92
-
93
- # Test string to object
94
- parsed = MyFormattedModel.parse(generated)
95
- print("Parsed object:")
96
- print(parsed)
97
- print()
98
-
99
- # Test round-trip
100
- print("Round-trip test:")
101
- print("Original == Parsed:", model == parsed)
102
-
103
- # Test with different values
104
- another_model = MyFormattedModel(name="Alice", age=25, city="New York")
105
- another_generated = another_model.generate()
106
- print("\nAnother generated string:")
107
- print(another_generated)
108
- print()
109
-
110
- another_parsed = MyFormattedModel.parse(another_generated)
111
- print("Another parsed object:")
112
- print(another_parsed)
113
- print("Another Original == Another Parsed:", another_model == another_parsed)
114
-
115
-
116
- # code file model
117
- class CodeFileModel(FormattingModel):
118
- language: str
119
- file_path: str
120
- code: str
121
-
122
- @classmethod
123
- def format_spec(cls) -> str:
124
- return "code_file_model\nfile_path: {FILE_PATH}\n```{LANGUAGE}\n{CODE}\n```"
125
-
126
- @classmethod
127
- def start_token(cls) -> str:
128
- return "<format>"
129
-
130
- @classmethod
131
- def end_token(cls) -> str:
132
- return "</format>"
133
-
134
- @classmethod
135
- def field_mappings(cls) -> Dict[str, str]:
136
- return {
137
- "file_path": "{FILE_PATH}",
138
- "language": "{LANGUAGE}",
139
- "code": "{CODE}"
140
- }
141
-
142
-
143
- print("\nTesting CodeFileModel:")
144
- code_model = CodeFileModel(
145
- language="python",
146
- file_path="src/main.py",
147
- code="def hello():\n print(\"Hello, World!\")"
148
- )
149
- code_generated = code_model.generate()
150
- print("Generated CodeFileModel string:")
151
- print(code_generated)
152
- print()
153
-
154
- code_parsed = CodeFileModel.parse(code_generated)
155
- print("Parsed CodeFileModel object:")
156
- print(code_parsed)
157
- print()
158
-
159
- print("CodeFileModel Round-trip test:")
160
- print("Original == Parsed:", code_model == code_parsed)
161
-
162
- # tolerant format
163
- #
164
- class CodeFileModel(FormattingModel):
165
- language: str
166
- file_path: str
167
- code: str
168
-
169
- @classmethod
170
- def format_spec(cls) -> str:
171
- return (
172
- r"code_file_model\s*\n"
173
- r"file_path:\s*{FILE_PATH}\s*\n"
174
- r"```\s*{LANGUAGE}\s*\n"
175
- r"{CODE}\s*"
176
- r"```"
177
- )
178
-
179
- @classmethod
180
- def start_token(cls) -> str:
181
- return "<format>"
182
-
183
- @classmethod
184
- def end_token(cls) -> str:
185
- return "</format>"
186
-
187
- @classmethod
188
- def field_mappings(cls) -> Dict[str, str]:
189
- return {
190
- "file_path": "{FILE_PATH}",
191
- "language": "{LANGUAGE}",
192
- "code": "{CODE}"
193
- }
194
-
195
- print("\nTesting CodeFileModel with various whitespace variations:")
196
-
197
- test_strings = [
198
- # Standard format
199
- """<format>
200
- code_file_model
201
- file_path: src/main.py
202
- ```python
203
- def hello():
204
- print("Hello, World!")
205
- ```
206
- </format>""",
207
- # Extra whitespace
208
- """<format>
209
- code_file_model
210
- file_path: src/main.py
211
- ``` python
212
- def hello():
213
- print("Hello, World!")
214
- ```
215
- </format>""",
216
- # Extra newlines
217
- """<format>
218
- code_file_model
219
-
220
- file_path: src/main.py
221
-
222
- ```python
223
-
224
- def hello():
225
- print("Hello, World!")
226
-
227
- ```
228
-
229
- </format>"""
230
- ]
231
-
232
- for i, test_string in enumerate(test_strings, 1):
233
- print(f"\nTest {i}:")
234
- print("Input string:")
235
- print(test_string)
236
-
237
- parsed = CodeFileModel.parse(test_string)
238
- print("\nParsed object:")
239
- print(parsed)
240
-
241
- regenerated = parsed.generate()
242
- print("\nRegenerated string:")
243
- print(regenerated)
244
-
245
- reparsed = CodeFileModel.parse(regenerated)
246
- print("\nRound-trip test:")
247
- print("Original parsed == Reparsed:", parsed == reparsed)
248
- print("-" * 50)