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.
- langroid/agent/base.py +45 -21
- langroid/agent/chat_agent.py +22 -14
- langroid/agent/chat_document.py +22 -13
- langroid/agent/tool_message.py +11 -11
- langroid/agent/tools/file_tools.py +234 -0
- langroid/agent/xml_tool_message.py +179 -45
- langroid/utils/constants.py +2 -0
- langroid/utils/git_utils.py +251 -0
- langroid/utils/system.py +78 -0
- {langroid-0.16.7.dist-info → langroid-0.17.1.dist-info}/METADATA +6 -3
- {langroid-0.16.7.dist-info → langroid-0.17.1.dist-info}/RECORD +14 -89
- pyproject.toml +3 -2
- langroid/agent/md_tool_message_grammar.py +0 -455
- langroid/agent/tools/code_file_tool_parse.py +0 -150
- langroid/agent/tools/code_file_tool_pyparsing.py +0 -194
- langroid/agent/tools/code_file_tool_pyparsing2.py +0 -199
- langroid/agent/tools/extract_tool.py +0 -96
- langroid/agent/tools/formatted_model_custom.py +0 -150
- langroid/agent/tools/formatted_model_custom2.py +0 -168
- langroid/agent/tools/formatted_model_custom3.py +0 -279
- langroid/agent/tools/formatted_model_custom4.py +0 -395
- langroid/agent/tools/formatted_model_jinja.py +0 -133
- langroid/agent/tools/formatted_model_jinja.py-e +0 -122
- langroid/agent/tools/formatted_model_jinja2.py +0 -145
- langroid/agent/tools/formatted_model_jinja2.py-e +0 -135
- langroid/agent/tools/formatted_model_lark.py +0 -0
- langroid/agent/tools/formatted_model_lark2.py +0 -168
- langroid/agent/tools/formatted_model_parse.py +0 -105
- langroid/agent/tools/formatted_model_parse.py-e +0 -98
- langroid/agent/tools/formatted_model_parse2.py +0 -113
- langroid/agent/tools/formatted_model_parse2.py-e +0 -109
- langroid/agent/tools/formatted_model_parse3.py +0 -114
- langroid/agent/tools/formatted_model_parse3.py-e +0 -110
- langroid/agent/tools/formatted_model_parsimon.py +0 -194
- langroid/agent/tools/formatted_model_parsimon.py-e +0 -186
- langroid/agent/tools/formatted_model_pyparsing.py +0 -169
- langroid/agent/tools/formatted_model_pyparsing.py-e +0 -149
- langroid/agent/tools/formatted_model_pyparsing2.py +0 -159
- langroid/agent/tools/formatted_model_pyparsing2.py-e +0 -143
- langroid/agent/tools/formatted_model_pyparsing3.py +0 -133
- langroid/agent/tools/formatted_model_pyparsing3.py-e +0 -121
- langroid/agent/tools/formatted_model_pyparsing4.py +0 -213
- langroid/agent/tools/formatted_model_pyparsing4.py-e +0 -176
- langroid/agent/tools/formatted_model_pyparsing5.py +0 -173
- langroid/agent/tools/formatted_model_pyparsing5.py-e +0 -142
- langroid/agent/tools/formatted_model_regex.py +0 -246
- langroid/agent/tools/formatted_model_regex.py-e +0 -248
- langroid/agent/tools/formatted_model_regex2.py +0 -250
- langroid/agent/tools/formatted_model_regex2.py-e +0 -253
- langroid/agent/tools/formatted_model_tatsu.py +0 -172
- langroid/agent/tools/formatted_model_tatsu.py-e +0 -160
- langroid/agent/tools/formatted_model_template.py +0 -217
- langroid/agent/tools/formatted_model_template.py-e +0 -200
- langroid/agent/tools/formatted_model_xml.py +0 -178
- langroid/agent/tools/formatted_model_xml2.py +0 -178
- langroid/agent/tools/formatted_model_xml3.py +0 -132
- langroid/agent/tools/formatted_model_xml4.py +0 -130
- langroid/agent/tools/formatted_model_xml5.py +0 -130
- langroid/agent/tools/formatted_model_xml6.py +0 -113
- langroid/agent/tools/formatted_model_xml7.py +0 -117
- langroid/agent/tools/formatted_model_xml8.py +0 -164
- langroid/agent/tools/generator_tool.py +0 -20
- langroid/agent/tools/generic_tool.py +0 -165
- langroid/agent/tools/generic_tool_tatsu.py +0 -275
- langroid/agent/tools/grammar_based_model.py +0 -132
- langroid/agent/tools/grammar_based_model.py-e +0 -128
- langroid/agent/tools/grammar_based_model_lark.py +0 -156
- langroid/agent/tools/grammar_based_model_lark.py-e +0 -153
- langroid/agent/tools/grammar_based_model_parse.py +0 -86
- langroid/agent/tools/grammar_based_model_parse.py-e +0 -80
- langroid/agent/tools/grammar_based_model_parsimonious.py +0 -129
- langroid/agent/tools/grammar_based_model_parsimonious.py-e +0 -120
- langroid/agent/tools/grammar_based_model_pyparsing.py +0 -105
- langroid/agent/tools/grammar_based_model_pyparsing.py-e +0 -103
- langroid/agent/tools/grammar_based_model_regex.py +0 -139
- langroid/agent/tools/grammar_based_model_regex.py-e +0 -130
- langroid/agent/tools/grammar_based_model_regex2.py +0 -124
- langroid/agent/tools/grammar_based_model_regex2.py-e +0 -116
- langroid/agent/tools/grammar_based_model_tatsu.py +0 -80
- langroid/agent/tools/grammar_based_model_tatsu.py-e +0 -77
- langroid/agent/tools/lark_earley_example.py +0 -135
- langroid/agent/tools/lark_earley_example.py-e +0 -117
- langroid/agent/tools/lark_example.py +0 -72
- langroid/agent/tools/note_tool.py +0 -0
- langroid/agent/tools/parse_example.py +0 -76
- langroid/agent/tools/parse_example2.py +0 -87
- langroid/agent/tools/parse_example3.py +0 -42
- langroid/agent/tools/parse_test.py +0 -791
- langroid/agent/tools/run_python_code.py +0 -60
- {langroid-0.16.7.dist-info → langroid-0.17.1.dist-info}/LICENSE +0 -0
- {langroid-0.16.7.dist-info → langroid-0.17.1.dist-info}/WHEEL +0 -0
@@ -1,130 +0,0 @@
|
|
1
|
-
from abc import ABC, abstractmethod
|
2
|
-
|
3
|
-
from lxml import etree
|
4
|
-
|
5
|
-
from langroid.pydantic_v1 import BaseModel
|
6
|
-
|
7
|
-
|
8
|
-
class FormattingModel(BaseModel, ABC):
|
9
|
-
@classmethod
|
10
|
-
@abstractmethod
|
11
|
-
def root_element(cls) -> str:
|
12
|
-
pass
|
13
|
-
|
14
|
-
@classmethod
|
15
|
-
def format(cls, instance: "FormattingModel") -> str:
|
16
|
-
root = etree.Element(cls.root_element())
|
17
|
-
for field_name, field in cls.__fields__.items():
|
18
|
-
value = getattr(instance, field_name)
|
19
|
-
elem = etree.SubElement(root, field_name)
|
20
|
-
xml_type = field.field_info.extra.get("xml", {}).get("type", "text")
|
21
|
-
if xml_type == "cdata":
|
22
|
-
elem.text = etree.CDATA(str(value))
|
23
|
-
else:
|
24
|
-
elem.text = str(value)
|
25
|
-
return etree.tostring(root, encoding="unicode", pretty_print=True)
|
26
|
-
|
27
|
-
@classmethod
|
28
|
-
def parse(cls, formatted_string: str) -> "FormattingModel":
|
29
|
-
root = etree.fromstring(formatted_string.encode("utf-8"))
|
30
|
-
if root.tag != cls.root_element():
|
31
|
-
raise ValueError(
|
32
|
-
f"Invalid root element: expected {cls.root_element()}, got {root.tag}"
|
33
|
-
)
|
34
|
-
|
35
|
-
data = {}
|
36
|
-
for field_name, field in cls.__fields__.items():
|
37
|
-
elem = root.find(field_name)
|
38
|
-
if elem is None:
|
39
|
-
raise ValueError(f"Missing field: {field_name}")
|
40
|
-
xml_type = field.field_info.extra.get("xml", {}).get("type", "text")
|
41
|
-
if xml_type == "cdata":
|
42
|
-
data[field_name] = elem.text
|
43
|
-
elif xml_type == "text":
|
44
|
-
data[field_name] = elem.text.strip() if elem.text else ""
|
45
|
-
else:
|
46
|
-
# Handle other field types as needed
|
47
|
-
data[field_name] = elem.text
|
48
|
-
|
49
|
-
return cls(**data)
|
50
|
-
|
51
|
-
|
52
|
-
from langroid.pydantic_v1 import Field
|
53
|
-
|
54
|
-
|
55
|
-
def XmlField(*args, xml_type: str = "text", **kwargs):
|
56
|
-
return Field(*args, xml={"type": xml_type}, **kwargs)
|
57
|
-
|
58
|
-
|
59
|
-
class CodeFileModel(FormattingModel):
|
60
|
-
language: str = XmlField(xml_type="text")
|
61
|
-
file_path: str = XmlField(xml_type="text")
|
62
|
-
code: str = XmlField(xml_type="cdata")
|
63
|
-
|
64
|
-
@classmethod
|
65
|
-
def root_element(cls):
|
66
|
-
return "code_file_model"
|
67
|
-
|
68
|
-
|
69
|
-
# Test cases
|
70
|
-
if __name__ == "__main__":
|
71
|
-
# Test formatting
|
72
|
-
code_file = CodeFileModel(
|
73
|
-
language="Python",
|
74
|
-
file_path="src/main.py",
|
75
|
-
code="def hello():\n print('Hello, World!')",
|
76
|
-
)
|
77
|
-
formatted = CodeFileModel.format(code_file)
|
78
|
-
print("Formatted XML:")
|
79
|
-
print(formatted)
|
80
|
-
|
81
|
-
# Test parsing
|
82
|
-
parsed = CodeFileModel.parse(formatted)
|
83
|
-
assert (
|
84
|
-
parsed == code_file
|
85
|
-
), f"Parsing failed. Expected:\n{code_file}\nGot:\n{parsed}"
|
86
|
-
print("Parsing test passed.")
|
87
|
-
|
88
|
-
# Test round-trip
|
89
|
-
round_trip = CodeFileModel.parse(CodeFileModel.format(code_file))
|
90
|
-
assert (
|
91
|
-
round_trip == code_file
|
92
|
-
), f"Round-trip failed. Expected:\n{code_file}\nGot:\n{round_trip}"
|
93
|
-
print("Round-trip test passed.")
|
94
|
-
|
95
|
-
# Test with different values
|
96
|
-
code_file2 = CodeFileModel(
|
97
|
-
language="JavaScript",
|
98
|
-
file_path="src/app.js",
|
99
|
-
code="function greet() {\n console.log('Hello, World!');\n}",
|
100
|
-
)
|
101
|
-
formatted2 = CodeFileModel.format(code_file2)
|
102
|
-
parsed2 = CodeFileModel.parse(formatted2)
|
103
|
-
assert (
|
104
|
-
parsed2 == code_file2
|
105
|
-
), f"Parsing failed for different values. Expected:\n{code_file2}\nGot:\n{parsed2}"
|
106
|
-
print("Different values test passed.")
|
107
|
-
|
108
|
-
# Test tolerant parsing
|
109
|
-
tolerant_input = """
|
110
|
-
<code_file_model>
|
111
|
-
<language> Python </language>
|
112
|
-
<file_path> src/main.py </file_path>
|
113
|
-
<code><![CDATA[
|
114
|
-
def hello():
|
115
|
-
print('Hello, World!')
|
116
|
-
]]></code>
|
117
|
-
</code_file_model>
|
118
|
-
"""
|
119
|
-
parsed_tolerant = CodeFileModel.parse(tolerant_input)
|
120
|
-
expected_tolerant = CodeFileModel(
|
121
|
-
language="Python",
|
122
|
-
file_path="src/main.py",
|
123
|
-
code="\ndef hello():\n print('Hello, World!')\n ",
|
124
|
-
)
|
125
|
-
assert (
|
126
|
-
parsed_tolerant == expected_tolerant
|
127
|
-
), f"Tolerant parsing failed. Expected:\n{expected_tolerant}\nGot:\n{parsed_tolerant}"
|
128
|
-
print("Tolerant parsing test passed.")
|
129
|
-
|
130
|
-
print("All tests passed successfully!")
|
@@ -1,113 +0,0 @@
|
|
1
|
-
from abc import ABC, abstractmethod
|
2
|
-
|
3
|
-
from lxml import etree
|
4
|
-
|
5
|
-
from langroid.pydantic_v1 import BaseModel
|
6
|
-
|
7
|
-
|
8
|
-
class FormattingModel(BaseModel, ABC):
|
9
|
-
@classmethod
|
10
|
-
@abstractmethod
|
11
|
-
def root_element(cls) -> str:
|
12
|
-
pass
|
13
|
-
|
14
|
-
@classmethod
|
15
|
-
def format(cls, instance: "FormattingModel") -> str:
|
16
|
-
root = etree.Element(cls.root_element())
|
17
|
-
for name, value in instance.dict().items():
|
18
|
-
elem = etree.SubElement(root, name)
|
19
|
-
elem.text = str(value)
|
20
|
-
return etree.tostring(root, encoding="unicode", pretty_print=True)
|
21
|
-
|
22
|
-
@classmethod
|
23
|
-
def parse(cls, formatted_string: str) -> "FormattingModel":
|
24
|
-
root = etree.fromstring(formatted_string.encode("utf-8"))
|
25
|
-
if root.tag != cls.root_element():
|
26
|
-
raise ValueError(
|
27
|
-
f"Invalid root element: expected {cls.root_element()}, got {root.tag}"
|
28
|
-
)
|
29
|
-
|
30
|
-
data = {}
|
31
|
-
for elem in root:
|
32
|
-
if elem.tag == "code":
|
33
|
-
# Preserve whitespace for 'code' field
|
34
|
-
data[elem.tag] = elem.text if elem.text else ""
|
35
|
-
else:
|
36
|
-
# Strip whitespace for other fields
|
37
|
-
data[elem.tag] = elem.text.strip() if elem.text else ""
|
38
|
-
|
39
|
-
return cls(**data)
|
40
|
-
|
41
|
-
|
42
|
-
class CodeFileModel(FormattingModel):
|
43
|
-
language: str
|
44
|
-
file_path: str
|
45
|
-
code: str
|
46
|
-
|
47
|
-
@classmethod
|
48
|
-
def root_element(cls):
|
49
|
-
return "code_file_model"
|
50
|
-
|
51
|
-
|
52
|
-
# Test cases
|
53
|
-
if __name__ == "__main__":
|
54
|
-
# Test formatting
|
55
|
-
code_file = CodeFileModel(
|
56
|
-
language="Python",
|
57
|
-
file_path="src/main.py",
|
58
|
-
code="def hello():\n print('Hello, World!')",
|
59
|
-
)
|
60
|
-
formatted = CodeFileModel.format(code_file)
|
61
|
-
print("Formatted XML:")
|
62
|
-
print(formatted)
|
63
|
-
|
64
|
-
# Test parsing
|
65
|
-
parsed = CodeFileModel.parse(formatted)
|
66
|
-
assert (
|
67
|
-
parsed == code_file
|
68
|
-
), f"Parsing failed. Expected:\n{code_file}\nGot:\n{parsed}"
|
69
|
-
print("Parsing test passed.")
|
70
|
-
|
71
|
-
# Test round-trip
|
72
|
-
round_trip = CodeFileModel.parse(CodeFileModel.format(code_file))
|
73
|
-
assert (
|
74
|
-
round_trip == code_file
|
75
|
-
), f"Round-trip failed. Expected:\n{code_file}\nGot:\n{round_trip}"
|
76
|
-
print("Round-trip test passed.")
|
77
|
-
|
78
|
-
# Test with different values
|
79
|
-
code_file2 = CodeFileModel(
|
80
|
-
language="JavaScript",
|
81
|
-
file_path="src/app.js",
|
82
|
-
code="function greet() {\n console.log('Hello, World!');\n}",
|
83
|
-
)
|
84
|
-
formatted2 = CodeFileModel.format(code_file2)
|
85
|
-
parsed2 = CodeFileModel.parse(formatted2)
|
86
|
-
assert (
|
87
|
-
parsed2 == code_file2
|
88
|
-
), f"Parsing failed for different values. Expected:\n{code_file2}\nGot:\n{parsed2}"
|
89
|
-
print("Different values test passed.")
|
90
|
-
|
91
|
-
# Test tolerant parsing
|
92
|
-
tolerant_input = """
|
93
|
-
<code_file_model>
|
94
|
-
<language> Python </language>
|
95
|
-
<file_path> src/main.py </file_path>
|
96
|
-
<code>
|
97
|
-
def hello():
|
98
|
-
print('Hello, World!')
|
99
|
-
</code>
|
100
|
-
</code_file_model>
|
101
|
-
"""
|
102
|
-
parsed_tolerant = CodeFileModel.parse(tolerant_input)
|
103
|
-
expected_tolerant = CodeFileModel(
|
104
|
-
language="Python",
|
105
|
-
file_path="src/main.py",
|
106
|
-
code="\ndef hello():\n print('Hello, World!')\n ",
|
107
|
-
)
|
108
|
-
assert (
|
109
|
-
parsed_tolerant == expected_tolerant
|
110
|
-
), f"Tolerant parsing failed. Expected:\n{expected_tolerant}\nGot:\n{parsed_tolerant}"
|
111
|
-
print("Tolerant parsing test passed.")
|
112
|
-
|
113
|
-
print("All tests passed successfully!")
|
@@ -1,117 +0,0 @@
|
|
1
|
-
from abc import ABC, abstractmethod
|
2
|
-
|
3
|
-
from lxml import etree
|
4
|
-
|
5
|
-
from langroid.pydantic_v1 import BaseModel
|
6
|
-
|
7
|
-
|
8
|
-
class FormattingModel(BaseModel, ABC):
|
9
|
-
@classmethod
|
10
|
-
@abstractmethod
|
11
|
-
def root_element(cls) -> str:
|
12
|
-
pass
|
13
|
-
|
14
|
-
@classmethod
|
15
|
-
def parse(cls, formatted_string: str) -> "FormattingModel":
|
16
|
-
parser = etree.XMLParser(strip_cdata=False)
|
17
|
-
root = etree.fromstring(formatted_string.encode("utf-8"), parser=parser)
|
18
|
-
if root.tag != cls.root_element():
|
19
|
-
raise ValueError(
|
20
|
-
f"Invalid root element: expected {cls.root_element()}, got {root.tag}"
|
21
|
-
)
|
22
|
-
|
23
|
-
data = {}
|
24
|
-
for elem in root:
|
25
|
-
if elem.tag == "code":
|
26
|
-
# Extract CDATA content
|
27
|
-
data[elem.tag] = elem.text if elem.text else ""
|
28
|
-
else:
|
29
|
-
# Strip whitespace for other fields
|
30
|
-
data[elem.tag] = elem.text.strip() if elem.text else ""
|
31
|
-
|
32
|
-
return cls(**data)
|
33
|
-
|
34
|
-
@classmethod
|
35
|
-
def format(cls, instance: "FormattingModel") -> str:
|
36
|
-
root = etree.Element(cls.root_element())
|
37
|
-
for name, value in instance.dict().items():
|
38
|
-
elem = etree.SubElement(root, name)
|
39
|
-
if name == "code":
|
40
|
-
elem.text = etree.CDATA(value)
|
41
|
-
else:
|
42
|
-
elem.text = str(value)
|
43
|
-
return etree.tostring(root, encoding="unicode", pretty_print=True)
|
44
|
-
|
45
|
-
|
46
|
-
class CodeFileModel(FormattingModel):
|
47
|
-
language: str
|
48
|
-
file_path: str
|
49
|
-
code: str
|
50
|
-
|
51
|
-
@classmethod
|
52
|
-
def root_element(cls):
|
53
|
-
return "code_file_model"
|
54
|
-
|
55
|
-
|
56
|
-
# Test cases
|
57
|
-
if __name__ == "__main__":
|
58
|
-
# Test formatting
|
59
|
-
code_file = CodeFileModel(
|
60
|
-
language="Python",
|
61
|
-
file_path="src/main.py",
|
62
|
-
code="def hello():\n print('Hello, World!')",
|
63
|
-
)
|
64
|
-
formatted = CodeFileModel.format(code_file)
|
65
|
-
print("Formatted XML:")
|
66
|
-
print(formatted)
|
67
|
-
|
68
|
-
# Test parsing
|
69
|
-
parsed = CodeFileModel.parse(formatted)
|
70
|
-
assert (
|
71
|
-
parsed == code_file
|
72
|
-
), f"Parsing failed. Expected:\n{code_file}\nGot:\n{parsed}"
|
73
|
-
print("Parsing test passed.")
|
74
|
-
|
75
|
-
# Test round-trip
|
76
|
-
round_trip = CodeFileModel.parse(CodeFileModel.format(code_file))
|
77
|
-
assert (
|
78
|
-
round_trip == code_file
|
79
|
-
), f"Round-trip failed. Expected:\n{code_file}\nGot:\n{round_trip}"
|
80
|
-
print("Round-trip test passed.")
|
81
|
-
|
82
|
-
# Test with different values
|
83
|
-
code_file2 = CodeFileModel(
|
84
|
-
language="JavaScript",
|
85
|
-
file_path="src/app.js",
|
86
|
-
code="function greet() {\n console.log('Hello, World!');\n}",
|
87
|
-
)
|
88
|
-
formatted2 = CodeFileModel.format(code_file2)
|
89
|
-
parsed2 = CodeFileModel.parse(formatted2)
|
90
|
-
assert (
|
91
|
-
parsed2 == code_file2
|
92
|
-
), f"Parsing failed for different values. Expected:\n{code_file2}\nGot:\n{parsed2}"
|
93
|
-
print("Different values test passed.")
|
94
|
-
|
95
|
-
# Test tolerant parsing
|
96
|
-
tolerant_input = """
|
97
|
-
<code_file_model>
|
98
|
-
<language> Python </language>
|
99
|
-
<file_path> src/main.py </file_path>
|
100
|
-
<code>
|
101
|
-
def hello():
|
102
|
-
print('Hello, World!')
|
103
|
-
</code>
|
104
|
-
</code_file_model>
|
105
|
-
"""
|
106
|
-
parsed_tolerant = CodeFileModel.parse(tolerant_input)
|
107
|
-
expected_tolerant = CodeFileModel(
|
108
|
-
language="Python",
|
109
|
-
file_path="src/main.py",
|
110
|
-
code="\ndef hello():\n print('Hello, World!')\n ",
|
111
|
-
)
|
112
|
-
assert (
|
113
|
-
parsed_tolerant == expected_tolerant
|
114
|
-
), f"Tolerant parsing failed. Expected:\n{expected_tolerant}\nGot:\n{parsed_tolerant}"
|
115
|
-
print("Tolerant parsing test passed.")
|
116
|
-
|
117
|
-
print("All tests passed successfully!")
|
@@ -1,164 +0,0 @@
|
|
1
|
-
from abc import ABC, abstractmethod
|
2
|
-
from typing import get_type_hints
|
3
|
-
|
4
|
-
from lxml import etree
|
5
|
-
|
6
|
-
from langroid.pydantic_v1 import BaseModel
|
7
|
-
|
8
|
-
|
9
|
-
class FormattingModel(BaseModel, ABC):
|
10
|
-
@classmethod
|
11
|
-
@abstractmethod
|
12
|
-
def root_element(cls) -> str:
|
13
|
-
pass
|
14
|
-
|
15
|
-
@classmethod
|
16
|
-
def parse(cls, formatted_string: str) -> "FormattingModel":
|
17
|
-
parser = etree.XMLParser(strip_cdata=False)
|
18
|
-
root = etree.fromstring(formatted_string.encode("utf-8"), parser=parser)
|
19
|
-
if root.tag != cls.root_element():
|
20
|
-
raise ValueError(
|
21
|
-
f"Invalid root element: expected {cls.root_element()}, got {root.tag}"
|
22
|
-
)
|
23
|
-
|
24
|
-
data = {}
|
25
|
-
type_hints = get_type_hints(cls)
|
26
|
-
for elem in root:
|
27
|
-
field_type = type_hints.get(elem.tag, str)
|
28
|
-
if elem.tag == "code":
|
29
|
-
data[elem.tag] = elem.text if elem.text else ""
|
30
|
-
else:
|
31
|
-
# Parse according to the field type
|
32
|
-
value = elem.text.strip() if elem.text else ""
|
33
|
-
if field_type == int:
|
34
|
-
data[elem.tag] = int(value)
|
35
|
-
elif field_type == float:
|
36
|
-
data[elem.tag] = float(value)
|
37
|
-
elif field_type == bool:
|
38
|
-
data[elem.tag] = value.lower() in ("true", "1", "yes")
|
39
|
-
else:
|
40
|
-
data[elem.tag] = value
|
41
|
-
|
42
|
-
return cls(**data)
|
43
|
-
|
44
|
-
@classmethod
|
45
|
-
def instructions(cls) -> str:
|
46
|
-
# Get only the fields defined in the model
|
47
|
-
fields = list(cls.__fields__.keys())
|
48
|
-
|
49
|
-
# Preamble with placeholder variables
|
50
|
-
preamble = "Placeholders:\n"
|
51
|
-
for field in fields:
|
52
|
-
preamble += f"{field.upper()} = [value for {field}]\n"
|
53
|
-
|
54
|
-
# Formatting example
|
55
|
-
example = f"Formatting example:\n\n<{cls.root_element()}>\n"
|
56
|
-
for field in fields:
|
57
|
-
if field == "code":
|
58
|
-
example += f" <{field}><![CDATA[{{{field.upper()}}}]]></{field}>\n"
|
59
|
-
else:
|
60
|
-
example += f" <{field}>{{{field.upper()}}}</{field}>\n"
|
61
|
-
example += f"</{cls.root_element()}>"
|
62
|
-
|
63
|
-
return f"{preamble}\n{example}"
|
64
|
-
|
65
|
-
@classmethod
|
66
|
-
def format(cls, instance: "FormattingModel") -> str:
|
67
|
-
root = etree.Element(cls.root_element())
|
68
|
-
for name, value in instance.dict().items():
|
69
|
-
elem = etree.SubElement(root, name)
|
70
|
-
if name == "code":
|
71
|
-
elem.text = etree.CDATA(str(value))
|
72
|
-
else:
|
73
|
-
elem.text = str(value)
|
74
|
-
return etree.tostring(root, encoding="unicode", pretty_print=True)
|
75
|
-
|
76
|
-
|
77
|
-
class CodeFileModel(FormattingModel):
|
78
|
-
language: str
|
79
|
-
file_path: str
|
80
|
-
code: str
|
81
|
-
line_count: int
|
82
|
-
average_line_length: float
|
83
|
-
is_executable: bool
|
84
|
-
|
85
|
-
@classmethod
|
86
|
-
def root_element(cls):
|
87
|
-
return "code_file_model"
|
88
|
-
|
89
|
-
|
90
|
-
if __name__ == "__main__":
|
91
|
-
# Test formatting
|
92
|
-
code_file = CodeFileModel(
|
93
|
-
language="Python",
|
94
|
-
file_path="src/main.py",
|
95
|
-
code="def hello():\n print('Hello, World!')",
|
96
|
-
line_count=2,
|
97
|
-
average_line_length=20.5,
|
98
|
-
is_executable=True,
|
99
|
-
)
|
100
|
-
formatted = CodeFileModel.format(code_file)
|
101
|
-
print("Formatted XML:")
|
102
|
-
print(formatted)
|
103
|
-
|
104
|
-
# Test parsing
|
105
|
-
parsed = CodeFileModel.parse(formatted)
|
106
|
-
assert (
|
107
|
-
parsed == code_file
|
108
|
-
), f"Parsing failed. Expected:\n{code_file}\nGot:\n{parsed}"
|
109
|
-
print("Parsing test passed.")
|
110
|
-
|
111
|
-
# Test round-trip
|
112
|
-
round_trip = CodeFileModel.parse(CodeFileModel.format(code_file))
|
113
|
-
assert (
|
114
|
-
round_trip == code_file
|
115
|
-
), f"Round-trip failed. Expected:\n{code_file}\nGot:\n{round_trip}"
|
116
|
-
print("Round-trip test passed.")
|
117
|
-
|
118
|
-
# Test with different values
|
119
|
-
code_file2 = CodeFileModel(
|
120
|
-
language="JavaScript",
|
121
|
-
file_path="src/app.js",
|
122
|
-
code="function greet() {\n console.log('Hello, World!');\n}",
|
123
|
-
line_count=3,
|
124
|
-
average_line_length=15.33,
|
125
|
-
is_executable=False,
|
126
|
-
)
|
127
|
-
formatted2 = CodeFileModel.format(code_file2)
|
128
|
-
parsed2 = CodeFileModel.parse(formatted2)
|
129
|
-
assert (
|
130
|
-
parsed2 == code_file2
|
131
|
-
), f"Parsing failed for different values. Expected:\n{code_file2}\nGot:\n{parsed2}"
|
132
|
-
print("Different values test passed.")
|
133
|
-
|
134
|
-
# Test tolerant parsing
|
135
|
-
tolerant_input = """
|
136
|
-
<code_file_model>
|
137
|
-
<language> Python </language>
|
138
|
-
<file_path> src/main.py </file_path>
|
139
|
-
<code><![CDATA[
|
140
|
-
def hello():
|
141
|
-
print('Hello, World!')
|
142
|
-
]]></code>
|
143
|
-
<line_count> 2 </line_count>
|
144
|
-
<average_line_length> 20.5 </average_line_length>
|
145
|
-
<is_executable> True </is_executable>
|
146
|
-
</code_file_model>
|
147
|
-
"""
|
148
|
-
parsed_tolerant = CodeFileModel.parse(tolerant_input)
|
149
|
-
expected_tolerant = CodeFileModel(
|
150
|
-
language="Python",
|
151
|
-
file_path="src/main.py",
|
152
|
-
code="\ndef hello():\n print('Hello, World!')\n ",
|
153
|
-
line_count=2,
|
154
|
-
average_line_length=20.5,
|
155
|
-
is_executable=True,
|
156
|
-
)
|
157
|
-
assert (
|
158
|
-
parsed_tolerant == expected_tolerant
|
159
|
-
), f"Tolerant parsing failed. Expected:\n{expected_tolerant}\nGot:\n{parsed_tolerant}"
|
160
|
-
print("Tolerant parsing test passed.")
|
161
|
-
|
162
|
-
print(CodeFileModel.instructions())
|
163
|
-
|
164
|
-
print("All tests passed successfully!")
|
@@ -1,20 +0,0 @@
|
|
1
|
-
"""
|
2
|
-
A tool to generate a message from previous (numbered) messages in the chat history.
|
3
|
-
The idea is that when an LLM is generating text that is a deterministic transformation
|
4
|
-
of a previous message, then specifying the transformation can be much cheaper
|
5
|
-
than actually generating the transformation.
|
6
|
-
"""
|
7
|
-
|
8
|
-
from langroid.agent.tool_message import ToolMessage
|
9
|
-
|
10
|
-
|
11
|
-
class GeneratorTool(ToolMessage):
|
12
|
-
request: str = ""
|
13
|
-
purpose: str = """
|
14
|
-
To generate a message where the parts within curly braces specify
|
15
|
-
what should be inserted, using a substitution specification.
|
16
|
-
"""
|
17
|
-
rules: str
|
18
|
-
|
19
|
-
def handle(self) -> None:
|
20
|
-
pass
|