diff --git a/langdspy/__init__.py b/langdspy/__init__.py
index 506e8eb..8bff5f5 100644
--- a/langdspy/__init__.py
+++ b/langdspy/__init__.py
@@ -1,4 +1,4 @@
-from .field_descriptors import InputField, OutputField, InputFieldList, HintField, OutputFieldEnum, OutputFieldEnumList, OutputFieldBool, OutputFieldChooseOne
+from .field_descriptors import InputField, OutputField, InputFieldList, HintField, OutputFieldEnum, OutputFieldEnumList, OutputFieldBool, OutputFieldChooseOne, InputFieldDict, InputFieldDictList
from .prompt_strategies import PromptSignature, PromptStrategy, DefaultPromptStrategy
from .prompt_runners import PromptRunner, RunnableConfig, Prediction, MultiPromptRunner
from .model import Model, TrainedModelState
diff --git a/langdspy/field_descriptors.py b/langdspy/field_descriptors.py
index 0f6ec53..2baec30 100644
--- a/langdspy/field_descriptors.py
+++ b/langdspy/field_descriptors.py
@@ -99,6 +99,52 @@ def format_prompt_value(self, value, llm_type: str):
res += f"{self._start_format_anthropic()}NO VALUES SPECIFIED{self.name}>"
return res
+class InputFieldDict(InputField):
+ def format_prompt_value(self, value, llm_type: str):
+ if llm_type == "openai":
+ return self._format_openai_prompt_value(value)
+ elif llm_type == "anthropic":
+ return self._format_anthropic_prompt_value(value)
+
+ def _format_openai_prompt_value(self, value):
+ formatted_dict = ""
+ for key, val in value.items():
+ formatted_dict += f"{self._start_format_openai()} {key}: {val}\n"
+ return formatted_dict.strip()
+
+ def _format_anthropic_prompt_value(self, value):
+ formatted_dict = f"<{self.name}>\n"
+ for key, val in value.items():
+ formatted_dict += f" <{key}>{val}{key}>\n"
+ formatted_dict += f"{self.name}>"
+ return formatted_dict
+
+class InputFieldDictList(InputField):
+ def format_prompt_value(self, value, llm_type: str):
+ if llm_type == "openai":
+ return self._format_openai_prompt_value(value)
+ elif llm_type == "anthropic":
+ return self._format_anthropic_prompt_value(value)
+
+ def _format_openai_prompt_value(self, value):
+ formatted_list = ""
+ for i, item in enumerate(value):
+ formatted_list += f"{self._start_format_openai()} Item {i+1}:\n"
+ for key, val in item.items():
+ formatted_list += f" {key}: {val}\n"
+ formatted_list += "\n"
+ return formatted_list.strip()
+
+ def _format_anthropic_prompt_value(self, value):
+ formatted_list = f"<{self.name}>\n"
+ for i, item in enumerate(value):
+ formatted_list += f" <{self.name} {i + 1}>\n"
+ for key, val in item.items():
+ formatted_list += f" <{key}>{val}{key}>\n"
+ formatted_list += f" {self.name} {i + 1}>\n"
+ formatted_list += f"{self.name}>"
+ return formatted_list
+
class OutputField(FieldDescriptor):
START_TOKEN_OPENAI = "🔑"
START_TOKEN_ANTHROPIC = None
diff --git a/tests/test_field_descriptors.py b/tests/test_field_descriptors.py
index fcf5d5c..7918970 100644
--- a/tests/test_field_descriptors.py
+++ b/tests/test_field_descriptors.py
@@ -1,6 +1,6 @@
import pytest
from enum import Enum
-from langdspy.field_descriptors import InputField, InputFieldList, OutputField, OutputFieldEnum, OutputFieldEnumList, OutputFieldBool, OutputFieldChooseOne
+from langdspy.field_descriptors import InputField, InputFieldList, OutputField, OutputFieldEnum, OutputFieldEnumList, OutputFieldBool, OutputFieldChooseOne, InputFieldDict, InputFieldDictList
def test_input_field_initialization():
field = InputField("name", "description")
@@ -87,4 +87,66 @@ def test_output_field_choose_one_format_prompt_description():
field = OutputFieldChooseOne("name", "description", choices)
assert "One of: Option 1, Option 2, Option 3" in field.format_prompt_description("openai")
- assert "One of: Option 1, Option 2, Option 3" in field.format_prompt_description("anthropic")
\ No newline at end of file
+ assert "One of: Option 1, Option 2, Option 3" in field.format_prompt_description("anthropic")
+
+def test_format_prompt_value_openai():
+ field = InputFieldDict("input_dict", "A dictionary input")
+ input_dict = {
+ "name": "John Doe",
+ "age": 30,
+ "city": "New York"
+ }
+ expected_output = "✅input_dict name: John Doe\n✅input_dict age: 30\n✅input_dict city: New York"
+ print(field.format_prompt_value(input_dict, "openai"))
+ print(expected_output)
+ assert field.format_prompt_value(input_dict, "openai") == expected_output
+
+def test_format_prompt_value_anthropic():
+ field = InputFieldDict("input_dict", "A dictionary input")
+ input_dict = {
+ "name": "John Doe",
+ "age": 30,
+ "city": "New York"
+ }
+ expected_output = "\n John Doe\n 30\n New York\n"
+ assert field.format_prompt_value(input_dict, "anthropic") == expected_output
+
+# tests/test_input_field_dict_list.py
+import pytest
+from langdspy.field_descriptors import InputFieldDictList
+
+def test_format_prompt_value_openai():
+ field = InputFieldDictList("input_list", "A list of dictionaries")
+ input_list = [
+ {
+ "name": "John Doe",
+ "age": 30,
+ "city": "New York"
+ },
+ {
+ "name": "Jane Smith",
+ "age": 25,
+ "city": "London"
+ }
+ ]
+ expected_output = "✅input_list Item 1:\n name: John Doe\n age: 30\n city: New York\n\n✅input_list Item 2:\n name: Jane Smith\n age: 25\n city: London"
+ print(field.format_prompt_value(input_list, "openai"))
+ print(expected_output)
+ assert field.format_prompt_value(input_list, "openai") == expected_output
+
+def test_format_prompt_value_anthropic():
+ field = InputFieldDictList("input_list", "A list of dictionaries")
+ input_list = [
+ {
+ "name": "John Doe",
+ "age": 30,
+ "city": "New York"
+ },
+ {
+ "name": "Jane Smith",
+ "age": 25,
+ "city": "London"
+ }
+ ]
+ expected_output = "\n \n John Doe\n 30\n New York\n \n \n Jane Smith\n 25\n London\n \n"
+ assert field.format_prompt_value(input_list, "anthropic") == expected_output
\ No newline at end of file