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,160 +0,0 @@
1
- from abc import ABC, abstractmethod
2
- from pydantic import BaseModel
3
- import tatsu
4
- from tatsu.model import ModelBuilderSemantics
5
-
6
- class FormattingModel(BaseModel, ABC):
7
- @classmethod
8
- @abstractmethod
9
- def format_spec(cls):
10
- pass
11
-
12
- @classmethod
13
- @abstractmethod
14
- def parse_spec(cls):
15
- pass
16
-
17
- @classmethod
18
- @abstractmethod
19
- def start_token(cls) -> str:
20
- pass
21
-
22
- @classmethod
23
- @abstractmethod
24
- def end_token(cls) -> str:
25
- pass
26
-
27
- @classmethod
28
- def format(cls, instance: 'FormattingModel') -> str:
29
- spec = cls.format_spec()
30
- formatted = spec.format(**instance.dict())
31
- return f"{cls.start_token()}\n{formatted}\n{cls.end_token()}"
32
-
33
- @classmethod
34
- def parse(cls, formatted_string: str) -> 'FormattingModel':
35
- lines = formatted_string.strip().split('\n')
36
- if lines[0] != cls.start_token() or lines[-1] != cls.end_token():
37
- raise ValueError("Invalid start or end token")
38
- content = '\n'.join(lines[1:-1])
39
-
40
- parser = tatsu.compile(cls.parse_spec())
41
- ast = parser.parse(content)
42
- return cls(**ast)
43
-
44
- class CodeFileModel(FormattingModel):
45
- language: str
46
- file_path: str
47
- code: str
48
-
49
- @classmethod
50
- def format_spec(cls):
51
- return "code_file_model\n{file_path}\n```{language}\n{code}\n```"
52
-
53
- @classmethod
54
- def parse_spec(cls):
55
- return '''
56
- @@grammar::CodeFileModel
57
-
58
- start = header file_path language code $ ;
59
-
60
- header = "code_file_model" ~;
61
- file_path = /[^\n]+/ ~;
62
- language = "```" /[a-zA-Z]+/ ~;
63
- code = /(?s).*?(?=```)/ "```" ~;
64
-
65
- @@whitespace :: /\s*/
66
- '''
67
-
68
- @classmethod
69
- def start_token(cls):
70
- return '<format>'
71
-
72
- @classmethod
73
- def end_token(cls):
74
- return '</format>'
75
-
76
- @classmethod
77
- def parse(cls, formatted_string: str) -> 'CodeFileModel':
78
- lines = formatted_string.strip().split('\n')
79
- if lines[0] != cls.start_token() or lines[-1] != cls.end_token():
80
- raise ValueError("Invalid start or end token")
81
- content = '\n'.join(lines[1:-1])
82
-
83
- class CodeFileModelSemantics(ModelBuilderSemantics):
84
- def file_path(self, ast):
85
- return ast.strip()
86
-
87
- def language(self, ast):
88
- return ast[1].strip()
89
-
90
- def code(self, ast):
91
- return ast[0].strip()
92
-
93
- parser = tatsu.compile(cls.parse_spec(), semantics=CodeFileModelSemantics())
94
- ast = parser.parse(content)
95
- return cls(**ast)
96
-
97
-
98
-
99
- # Test cases
100
- if __name__ == "__main__":
101
- # Test formatting
102
- code_file = CodeFileModel(
103
- language="Python",
104
- file_path="src/main.py",
105
- code="def hello():\n print('Hello, World!')"
106
- )
107
- formatted = CodeFileModel.format(code_file)
108
- expected_format = """<format>
109
- code_file_model
110
- src/main.py
111
- ```Python
112
- def hello():
113
- print('Hello, World!')
114
- ```
115
- </format>"""
116
- assert formatted == expected_format, f"Formatting failed. Expected:\n{expected_format}\nGot:\n{formatted}"
117
- print("Formatting test passed.")
118
-
119
- # Test parsing
120
- parsed = CodeFileModel.parse(formatted)
121
- assert parsed == code_file, f"Parsing failed. Expected:\n{code_file}\nGot:\n{parsed}"
122
- print("Parsing test passed.")
123
-
124
- # Test round-trip
125
- round_trip = CodeFileModel.parse(CodeFileModel.format(code_file))
126
- assert round_trip == code_file, f"Round-trip failed. Expected:\n{code_file}\nGot:\n{round_trip}"
127
- print("Round-trip test passed.")
128
-
129
- # Test with different values
130
- code_file2 = CodeFileModel(
131
- language="JavaScript",
132
- file_path="src/app.js",
133
- code="function greet() {\n console.log('Hello, World!');\n}"
134
- )
135
- formatted2 = CodeFileModel.format(code_file2)
136
- parsed2 = CodeFileModel.parse(formatted2)
137
- assert parsed2 == code_file2, f"Parsing failed for different values. Expected:\n{code_file2}\nGot:\n{parsed2}"
138
- print("Different values test passed.")
139
-
140
- # Test tolerant parsing
141
- tolerant_input = """<format>
142
- code_file_model
143
- src/main.py
144
-
145
- ``` Python
146
- def hello():
147
- print('Hello, World!')
148
- ```
149
- </format>"""
150
- parsed_tolerant = CodeFileModel.parse(tolerant_input)
151
- expected_tolerant = CodeFileModel(
152
- language="Python",
153
- file_path="src/main.py",
154
- code="def hello():\n print('Hello, World!')"
155
- )
156
- assert parsed_tolerant == expected_tolerant, f"Tolerant parsing failed. Expected:\n{expected_tolerant}\nGot:\n{parsed_tolerant}"
157
- print("Tolerant parsing test passed.")
158
-
159
- print("All tests passed successfully!")
160
-
@@ -1,217 +0,0 @@
1
- from abc import ABC, abstractmethod
2
- from string import Template
3
- from typing import Any, Dict
4
-
5
- from langroid.pydantic_v1 import BaseModel
6
-
7
-
8
- class FormattingModel(BaseModel, ABC):
9
- @classmethod
10
- @abstractmethod
11
- def format_spec(cls) -> Dict[str, Any]:
12
- pass
13
-
14
- @classmethod
15
- @abstractmethod
16
- def parse_spec(cls) -> Dict[str, Any]:
17
- pass
18
-
19
- @classmethod
20
- @abstractmethod
21
- def start_token(cls) -> str:
22
- pass
23
-
24
- @classmethod
25
- @abstractmethod
26
- def end_token(cls) -> str:
27
- pass
28
-
29
- @classmethod
30
- def format(cls, instance: "FormattingModel") -> str:
31
- spec = cls.format_spec()
32
- template = Template(spec["template"])
33
- formatted = template.substitute(instance.dict())
34
- return f"{cls.start_token()}\n{formatted}\n{cls.end_token()}"
35
-
36
- @classmethod
37
- def parse(cls, formatted_string: str) -> "FormattingModel":
38
- spec = cls.parse_spec()
39
- lines = formatted_string.strip().split("\n")
40
-
41
- if lines[0] != cls.start_token() or lines[-1] != cls.end_token():
42
- raise ValueError("Invalid start or end token")
43
-
44
- content = "\n".join(lines[1:-1])
45
-
46
- parsed_data = {}
47
- for field, token in spec["tokens"].items():
48
- if token:
49
- parts = content.split(token, 1)
50
- if len(parts) > 1:
51
- value = parts[1].split("\n")[0].strip()
52
- else:
53
- raise ValueError(
54
- f"Could not find token '{token}' for field '{field}'"
55
- )
56
- else:
57
- # For fields without a specific token (like age in our example)
58
- value = (
59
- content.split("\n")[spec["field_order"].index(field)]
60
- .split(" ")[0]
61
- .strip()
62
- )
63
-
64
- # Convert to appropriate type based on the model's field types
65
- field_type = cls.__annotations__[field]
66
- if field_type == int:
67
- parsed_data[field] = int(value)
68
- elif field_type == float:
69
- parsed_data[field] = float(value)
70
- else:
71
- parsed_data[field] = value
72
-
73
- return cls(**parsed_data)
74
-
75
-
76
- class PersonModel(FormattingModel):
77
- name: str
78
- age: int
79
- city: str
80
-
81
- @classmethod
82
- def format_spec(cls):
83
- return {"template": "name: $name\n$age is the age\nlives in $city"}
84
-
85
- @classmethod
86
- def parse_spec(cls):
87
- return {
88
- "template": "name: $name\n$age is the age\nlives in $city",
89
- "tokens": {"name": "name: ", "age": "", "city": "lives in "},
90
- "field_order": ["name", "age", "city"],
91
- }
92
-
93
- @classmethod
94
- def start_token(cls):
95
- return "<format>"
96
-
97
- @classmethod
98
- def end_token(cls):
99
- return "</format>"
100
-
101
-
102
- # Test cases
103
- if __name__ == "__main__":
104
- # Test formatting
105
- person = PersonModel(name="John", age=30, city="Tokyo")
106
- formatted = PersonModel.format(person)
107
- expected_format = """<format>
108
- name: John
109
- 30 is the age
110
- lives in Tokyo
111
- </format>"""
112
- assert (
113
- formatted == expected_format
114
- ), f"Formatting failed. Expected:\n{expected_format}\nGot:\n{formatted}"
115
- print("Formatting test passed.")
116
-
117
- # Test parsing
118
- parsed = PersonModel.parse(formatted)
119
- assert parsed == person, f"Parsing failed. Expected:\n{person}\nGot:\n{parsed}"
120
- print("Parsing test passed.")
121
-
122
- # Test round-trip
123
- round_trip = PersonModel.parse(PersonModel.format(person))
124
- assert (
125
- round_trip == person
126
- ), f"Round-trip failed. Expected:\n{person}\nGot:\n{round_trip}"
127
- print("Round-trip test passed.")
128
-
129
- # Test with different values
130
- person2 = PersonModel(name="Alice", age=25, city="New York")
131
- formatted2 = PersonModel.format(person2)
132
- parsed2 = PersonModel.parse(formatted2)
133
- assert (
134
- parsed2 == person2
135
- ), f"Parsing failed for different values. Expected:\n{person2}\nGot:\n{parsed2}"
136
- print("Different values test passed.")
137
-
138
- print("All tests passed successfully!")
139
-
140
- class CodeFileModel(FormattingModel):
141
- language: str
142
- file_path: str
143
- code: str
144
-
145
- @classmethod
146
- def format_spec(cls):
147
- return {"template": "code_file_model\n$file_path\n```$language\n$code\n```"}
148
-
149
- @classmethod
150
- def parse_spec(cls):
151
- return {
152
- "template": "code_file_model\n$file_path\n```$language\n$code\n```",
153
- "tokens": {
154
- "language": "```",
155
- "file_path": "code_file_model\n",
156
- "code": "\n",
157
- },
158
- "field_order": ["file_path", "language", "code"],
159
- }
160
-
161
- @classmethod
162
- def start_token(cls):
163
- return "<format>"
164
-
165
- @classmethod
166
- def end_token(cls):
167
- return "</format>"
168
-
169
- # Test formatting
170
-
171
- code_file = CodeFileModel(
172
- language="Python",
173
- file_path="src/main.py",
174
- code="def hello():\n print('Hello, World!')",
175
- )
176
- formatted = CodeFileModel.format(code_file)
177
- expected_format = """<format>
178
- code_file_model
179
- src/main.py
180
- ```Python
181
- def hello():
182
- print('Hello, World!')
183
- ```
184
- </format>"""
185
- assert (
186
- formatted == expected_format
187
- ), f"Formatting failed. Expected:\n{expected_format}\nGot:\n{formatted}"
188
- print("Formatting test passed.")
189
-
190
- # Test parsing
191
- parsed = CodeFileModel.parse(formatted)
192
- assert (
193
- parsed == code_file
194
- ), f"Parsing failed. Expected:\n{code_file}\nGot:\n{parsed}"
195
- print("Parsing test passed.")
196
-
197
- # Test round-trip
198
- round_trip = CodeFileModel.parse(CodeFileModel.format(code_file))
199
- assert (
200
- round_trip == code_file
201
- ), f"Round-trip failed. Expected:\n{code_file}\nGot:\n{round_trip}"
202
- print("Round-trip test passed.")
203
-
204
- # Test with different values
205
- code_file2 = CodeFileModel(
206
- language="JavaScript",
207
- file_path="src/app.js",
208
- code="function greet() {\n console.log('Hello, World!');\n}",
209
- )
210
- formatted2 = CodeFileModel.format(code_file2)
211
- parsed2 = CodeFileModel.parse(formatted2)
212
- assert (
213
- parsed2 == code_file2
214
- ), f"Parsing failed for different values. Expected:\n{code_file2}\nGot:\n{parsed2}"
215
- print("Different values test passed.")
216
-
217
- print("All tests passed successfully!")
@@ -1,200 +0,0 @@
1
- from abc import ABC, abstractmethod
2
- from pydantic import BaseModel
3
- from string import Template
4
- from typing import Dict, Any
5
-
6
- class FormattingModel(BaseModel, ABC):
7
- @classmethod
8
- @abstractmethod
9
- def format_spec(cls) -> Dict[str, Any]:
10
- pass
11
-
12
- @classmethod
13
- @abstractmethod
14
- def parse_spec(cls) -> Dict[str, Any]:
15
- pass
16
-
17
- @classmethod
18
- @abstractmethod
19
- def start_token(cls) -> str:
20
- pass
21
-
22
- @classmethod
23
- @abstractmethod
24
- def end_token(cls) -> str:
25
- pass
26
-
27
- @classmethod
28
- def format(cls, instance: 'FormattingModel') -> str:
29
- spec = cls.format_spec()
30
- template = Template(spec['template'])
31
- formatted = template.substitute(instance.dict())
32
- return f"{cls.start_token()}\n{formatted}\n{cls.end_token()}"
33
-
34
- @classmethod
35
- def parse(cls, formatted_string: str) -> 'FormattingModel':
36
- spec = cls.parse_spec()
37
- lines = formatted_string.strip().split('\n')
38
-
39
- if lines[0] != cls.start_token() or lines[-1] != cls.end_token():
40
- raise ValueError("Invalid start or end token")
41
-
42
- content = '\n'.join(lines[1:-1])
43
-
44
- parsed_data = {}
45
- for field, token in spec['tokens'].items():
46
- if token:
47
- parts = content.split(token, 1)
48
- if len(parts) > 1:
49
- value = parts[1].split('\n')[0].strip()
50
- else:
51
- raise ValueError(f"Could not find token '{token}' for field '{field}'")
52
- else:
53
- # For fields without a specific token (like age in our example)
54
- value = content.split('\n')[spec['field_order'].index(field)].split(' ')[0].strip()
55
-
56
- # Convert to appropriate type based on the model's field types
57
- field_type = cls.__annotations__[field]
58
- if field_type == int:
59
- parsed_data[field] = int(value)
60
- elif field_type == float:
61
- parsed_data[field] = float(value)
62
- else:
63
- parsed_data[field] = value
64
-
65
- return cls(**parsed_data)
66
-
67
- class PersonModel(FormattingModel):
68
- name: str
69
- age: int
70
- city: str
71
-
72
- @classmethod
73
- def format_spec(cls):
74
- return {
75
- 'template': 'name: $name\n$age is the age\nlives in $city'
76
- }
77
-
78
- @classmethod
79
- def parse_spec(cls):
80
- return {
81
- 'template': 'name: $name\n$age is the age\nlives in $city',
82
- 'tokens': {
83
- 'name': 'name: ',
84
- 'age': '',
85
- 'city': 'lives in '
86
- },
87
- 'field_order': ['name', 'age', 'city']
88
- }
89
-
90
- @classmethod
91
- def start_token(cls):
92
- return '<format>'
93
-
94
- @classmethod
95
- def end_token(cls):
96
- return '</format>'
97
-
98
- # Test cases
99
- if __name__ == "__main__":
100
- # Test formatting
101
- person = PersonModel(name="John", age=30, city="Tokyo")
102
- formatted = PersonModel.format(person)
103
- expected_format = """<format>
104
- name: John
105
- 30 is the age
106
- lives in Tokyo
107
- </format>"""
108
- assert formatted == expected_format, f"Formatting failed. Expected:\n{expected_format}\nGot:\n{formatted}"
109
- print("Formatting test passed.")
110
-
111
- # Test parsing
112
- parsed = PersonModel.parse(formatted)
113
- assert parsed == person, f"Parsing failed. Expected:\n{person}\nGot:\n{parsed}"
114
- print("Parsing test passed.")
115
-
116
- # Test round-trip
117
- round_trip = PersonModel.parse(PersonModel.format(person))
118
- assert round_trip == person, f"Round-trip failed. Expected:\n{person}\nGot:\n{round_trip}"
119
- print("Round-trip test passed.")
120
-
121
- # Test with different values
122
- person2 = PersonModel(name="Alice", age=25, city="New York")
123
- formatted2 = PersonModel.format(person2)
124
- parsed2 = PersonModel.parse(formatted2)
125
- assert parsed2 == person2, f"Parsing failed for different values. Expected:\n{person2}\nGot:\n{parsed2}"
126
- print("Different values test passed.")
127
-
128
- print("All tests passed successfully!")
129
-
130
- class CodeFileModel(FormattingModel):
131
- language: str
132
- file_path: str
133
- code: str
134
-
135
- @classmethod
136
- def format_spec(cls):
137
- return {
138
- 'template': 'code_file_model\n$file_path\n```$language\n$code\n```'
139
- }
140
-
141
- @classmethod
142
- def parse_spec(cls):
143
- return {
144
- 'template': 'code_file_model\n$file_path\n```$language\n$code\n```',
145
- 'tokens': {
146
- 'language': '```',
147
- 'file_path': 'code_file_model\n',
148
- 'code': '\n'
149
- },
150
- 'field_order': ['file_path', 'language', 'code']
151
- }
152
-
153
- @classmethod
154
- def start_token(cls):
155
- return '<format>'
156
-
157
- @classmethod
158
- def end_token(cls):
159
- return '</format>'
160
-
161
- # Test formatting
162
- code_file = CodeFileModel(
163
- language="Python",
164
- file_path="src/main.py",
165
- code="def hello():\n print('Hello, World!')"
166
- )
167
- formatted = CodeFileModel.format(code_file)
168
- expected_format = """<format>
169
- code_file_model
170
- src/main.py
171
- ```Python
172
- def hello():
173
- print('Hello, World!')
174
- ```
175
- </format>"""
176
- assert formatted == expected_format, f"Formatting failed. Expected:\n{expected_format}\nGot:\n{formatted}"
177
- print("Formatting test passed.")
178
-
179
- # Test parsing
180
- parsed = CodeFileModel.parse(formatted)
181
- assert parsed == code_file, f"Parsing failed. Expected:\n{code_file}\nGot:\n{parsed}"
182
- print("Parsing test passed.")
183
-
184
- # Test round-trip
185
- round_trip = CodeFileModel.parse(CodeFileModel.format(code_file))
186
- assert round_trip == code_file, f"Round-trip failed. Expected:\n{code_file}\nGot:\n{round_trip}"
187
- print("Round-trip test passed.")
188
-
189
- # Test with different values
190
- code_file2 = CodeFileModel(
191
- language="JavaScript",
192
- file_path="src/app.js",
193
- code="function greet() {\n console.log('Hello, World!');\n}"
194
- )
195
- formatted2 = CodeFileModel.format(code_file2)
196
- parsed2 = CodeFileModel.parse(formatted2)
197
- assert parsed2 == code_file2, f"Parsing failed for different values. Expected:\n{code_file2}\nGot:\n{parsed2}"
198
- print("Different values test passed.")
199
-
200
- print("All tests passed successfully!")