Skip to content

Commit

Permalink
icalendar
Browse files Browse the repository at this point in the history
  • Loading branch information
seanchatmangpt committed Feb 4, 2024
1 parent d7c6367 commit c3e73ac
Show file tree
Hide file tree
Showing 11 changed files with 332 additions and 60 deletions.
2 changes: 1 addition & 1 deletion experiments/chatgpt_conversation_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def process_conversations_chunk(chunk):
data = Data(**conversation.mapping[key])
if data.message and data.message.author.role == "assistant":
for part in data.message.content.parts:
if "{{" in part:
if "CoRL" in part:
print(part)
# encoding = tiktoken.encoding_for_model("text-embedding-ada-002")
# print(len(encoding.encode(part)))
Expand Down
130 changes: 130 additions & 0 deletions src/rdddy/generators/assertion.log
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,133 @@ fields.3.default_value
fields.3.default_value
Input should be a valid string [type=string_type, input_value=1, input_type=int]
For further information visit https://errors.pydantic.dev/2.5/v/string_type
2024-02-03 00:01:10,514 - dspy.primitives.assertions - ERROR - AssertionError: You need to create a kwargs dict for PydanticClassTemplateSpecificationModel

Validation error:
1 validation error for PydanticClassTemplateSpecificationModel
description
Field required [type=missing, input_value={'class_name': 'VTIMEZONE..., 'constraints': None}]}, input_type=dict]
For further information visit https://errors.pydantic.dev/2.5/v/missing
2024-02-03 00:01:10,516 - dspy.primitives.assertions - ERROR - AssertionError: You need to create a kwargs dict for PydanticClassTemplateSpecificationModel

Validation error:
1 validation error for PydanticClassTemplateSpecificationModel
description
Field required [type=missing, input_value={'class_name': 'VTIMEZONE..., 'constraints': None}]}, input_type=dict]
For further information visit https://errors.pydantic.dev/2.5/v/missing
2024-02-03 00:05:31,409 - dspy.primitives.assertions - ERROR - AssertionError: You need to create a kwargs dict for PydanticClassTemplateSpecificationModel

Validation error:
1 validation error for PydanticClassTemplateSpecificationModel
fields.9.default_value
Input should be a valid string [type=string_type, input_value=0, input_type=int]
For further information visit https://errors.pydantic.dev/2.5/v/string_type
2024-02-03 00:05:31,410 - dspy.primitives.assertions - ERROR - AssertionError: You need to create a kwargs dict for PydanticClassTemplateSpecificationModel

Validation error:
1 validation error for PydanticClassTemplateSpecificationModel
fields.9.default_value
Input should be a valid string [type=string_type, input_value=0, input_type=int]
For further information visit https://errors.pydantic.dev/2.5/v/string_type
2024-02-03 00:06:40,050 - dspy.primitives.assertions - ERROR - AssertionError: You need to create a kwargs dict for PydanticClassTemplateSpecificationModel

Validation error:
10 validation errors for PydanticClassTemplateSpecificationModel
fields.0
Input should be a valid dictionary or instance of FieldTemplateSpecificationModel [type=model_type, input_value='DTSTART', input_type=str]
For further information visit https://errors.pydantic.dev/2.5/v/model_type
fields.1
Input should be a valid dictionary or instance of FieldTemplateSpecificationModel [type=model_type, input_value='DTEND', input_type=str]
For further information visit https://errors.pydantic.dev/2.5/v/model_type
fields.2
Input should be a valid dictionary or instance of FieldTemplateSpecificationModel [type=model_type, input_value='SUMMARY', input_type=str]
For further information visit https://errors.pydantic.dev/2.5/v/model_type
fields.3
Input should be a valid dictionary or instance of FieldTemplateSpecificationModel [type=model_type, input_value='LOCATION', input_type=str]
For further information visit https://errors.pydantic.dev/2.5/v/model_type
fields.4
Input should be a valid dictionary or instance of FieldTemplateSpecificationModel [type=model_type, input_value='DESCRIPTION', input_type=str]
For further information visit https://errors.pydantic.dev/2.5/v/model_type
fields.5
Input should be a valid dictionary or instance of FieldTemplateSpecificationModel [type=model_type, input_value='RRULE', input_type=str]
For further information visit https://errors.pydantic.dev/2.5/v/model_type
fields.6
Input should be a valid dictionary or instance of FieldTemplateSpecificationModel [type=model_type, input_value='EXDATE', input_type=str]
For further information visit https://errors.pydantic.dev/2.5/v/model_type
fields.7
Input should be a valid dictionary or instance of FieldTemplateSpecificationModel [type=model_type, input_value='UID', input_type=str]
For further information visit https://errors.pydantic.dev/2.5/v/model_type
fields.8
Input should be a valid dictionary or instance of FieldTemplateSpecificationModel [type=model_type, input_value='SEQUENCE', input_type=str]
For further information visit https://errors.pydantic.dev/2.5/v/model_type
fields.9
Input should be a valid dictionary or instance of FieldTemplateSpecificationModel [type=model_type, input_value='STATUS', input_type=str]
For further information visit https://errors.pydantic.dev/2.5/v/model_type
2024-02-03 00:06:40,052 - dspy.primitives.assertions - ERROR - AssertionError: You need to create a kwargs dict for PydanticClassTemplateSpecificationModel

Validation error:
10 validation errors for PydanticClassTemplateSpecificationModel
fields.0
Input should be a valid dictionary or instance of FieldTemplateSpecificationModel [type=model_type, input_value='DTSTART', input_type=str]
For further information visit https://errors.pydantic.dev/2.5/v/model_type
fields.1
Input should be a valid dictionary or instance of FieldTemplateSpecificationModel [type=model_type, input_value='DTEND', input_type=str]
For further information visit https://errors.pydantic.dev/2.5/v/model_type
fields.2
Input should be a valid dictionary or instance of FieldTemplateSpecificationModel [type=model_type, input_value='SUMMARY', input_type=str]
For further information visit https://errors.pydantic.dev/2.5/v/model_type
fields.3
Input should be a valid dictionary or instance of FieldTemplateSpecificationModel [type=model_type, input_value='LOCATION', input_type=str]
For further information visit https://errors.pydantic.dev/2.5/v/model_type
fields.4
Input should be a valid dictionary or instance of FieldTemplateSpecificationModel [type=model_type, input_value='DESCRIPTION', input_type=str]
For further information visit https://errors.pydantic.dev/2.5/v/model_type
fields.5
Input should be a valid dictionary or instance of FieldTemplateSpecificationModel [type=model_type, input_value='RRULE', input_type=str]
For further information visit https://errors.pydantic.dev/2.5/v/model_type
fields.6
Input should be a valid dictionary or instance of FieldTemplateSpecificationModel [type=model_type, input_value='EXDATE', input_type=str]
For further information visit https://errors.pydantic.dev/2.5/v/model_type
fields.7
Input should be a valid dictionary or instance of FieldTemplateSpecificationModel [type=model_type, input_value='UID', input_type=str]
For further information visit https://errors.pydantic.dev/2.5/v/model_type
fields.8
Input should be a valid dictionary or instance of FieldTemplateSpecificationModel [type=model_type, input_value='SEQUENCE', input_type=str]
For further information visit https://errors.pydantic.dev/2.5/v/model_type
fields.9
Input should be a valid dictionary or instance of FieldTemplateSpecificationModel [type=model_type, input_value='STATUS', input_type=str]
For further information visit https://errors.pydantic.dev/2.5/v/model_type
2024-02-03 00:07:41,577 - dspy.primitives.assertions - ERROR - AssertionError: You need to create a kwargs dict for PydanticClassTemplateSpecificationModel

Validation error:
1 validation error for PydanticClassTemplateSpecificationModel
fields.6.default_value
Input should be a valid string [type=string_type, input_value=0, input_type=int]
For further information visit https://errors.pydantic.dev/2.5/v/string_type
2024-02-03 00:07:41,578 - dspy.primitives.assertions - ERROR - AssertionError: You need to create a kwargs dict for PydanticClassTemplateSpecificationModel

Validation error:
1 validation error for PydanticClassTemplateSpecificationModel
fields.6.default_value
Input should be a valid string [type=string_type, input_value=0, input_type=int]
For further information visit https://errors.pydantic.dev/2.5/v/string_type
2024-02-03 00:09:33,931 - dspy.primitives.assertions - ERROR - AssertionError: You need to create a kwargs dict for PydanticClassTemplateSpecificationModel

Validation error:
2 validation errors for PydanticClassTemplateSpecificationModel
fields.10.default_value
Input should be a valid string [type=string_type, input_value=0, input_type=int]
For further information visit https://errors.pydantic.dev/2.5/v/string_type
fields.14.default_value
Input should be a valid string [type=string_type, input_value=0, input_type=int]
For further information visit https://errors.pydantic.dev/2.5/v/string_type
2024-02-03 00:09:33,933 - dspy.primitives.assertions - ERROR - AssertionError: You need to create a kwargs dict for PydanticClassTemplateSpecificationModel

Validation error:
2 validation errors for PydanticClassTemplateSpecificationModel
fields.10.default_value
Input should be a valid string [type=string_type, input_value=0, input_type=int]
For further information visit https://errors.pydantic.dev/2.5/v/string_type
fields.14.default_value
Input should be a valid string [type=string_type, input_value=0, input_type=int]
For further information visit https://errors.pydantic.dev/2.5/v/string_type
69 changes: 52 additions & 17 deletions src/rdddy/generators/gen_pydantic_class.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import dspy
import inflection
import jinja2
from dspy import Signature, OutputField, InputField
from pydantic import BaseModel, Field
from typetemp.functional import render

from rdddy.generators.gen_pydantic_instance import GenPydanticInstance
from typetemp.functional import render
Expand All @@ -11,15 +13,15 @@
class FieldTemplateSpecificationModel(BaseModel):
field_name: str = Field(
...,
description="The name of the field in the model. PEP8 naming. No prefixes, suffixes, or abbreviations.",
description="The name of the field in the model. No prefixes, suffixes, or abbreviations.",
)
field_type: str = Field(
...,
description="The data type of the field, e.g., 'str', 'int', 'EmailStr', or 'datetime'. No dict or classes.",
)
default_value: str | None = Field(
default_value: str | int | None = Field(
"...",
description="The default value for the field if not provided.",
description="The default value for the field if not provided. ",
)
description: str = Field(
...,
Expand Down Expand Up @@ -87,7 +89,7 @@ class PydanticClassTemplateSpecificationModel(BaseModel):
)
fields: List[FieldTemplateSpecificationModel] = Field(
...,
description="A list of field specifications for the model. Each field specifies the name, type, default value, description, and constraints. 10 fields max.",
description="A list of field specifications for the model. Each field specifies the name, type, default value, description, and constraints. 15 fields max."
)


Expand All @@ -99,7 +101,7 @@ class PydanticClassTemplateSpecificationModel(BaseModel):
class {{ model.class_name }}(BaseModel):
"""{{ model.description }}"""
{% for field in model.fields %}
{{ field.field_name }}: {{ field.field_type }} = Field(default={{ field.default_value }}, title="{{ field.title }}", description="{{ field.description }}"{% if field.constraints %}, {{ field.constraints }}{% endif %})
{{ field.field_name | underscore }}: {{ field.field_type }} = Field(default={{ field.default_value }}, title="{{ field.title }}", description="{{ field.description }}"{% if field.constraints %}, {{ field.constraints }}{% endif %})
{% endfor %}
{% if model.validators|length > 0 %}
Expand All @@ -119,16 +121,52 @@ class Config:
'''


def render_pydantic_class(model_spec, template_str):
template = jinja2.Template(template_str)
return template.render(model=model_spec)


def write_pydantic_class_to_file(class_str, filename):
with open(filename, 'w') as file:
file.write(class_str)


class PromptToPydanticInstanceSignature(Signature):
"""
Converts a prompt into Pydantic model initialization kwargs.
"""

root_pydantic_model_class_name = InputField(
desc="Class name of the Pydantic model for which `kwargs` are being generated."
)
pydantic_model_definitions = InputField(
desc="Complete Python code string containing the class definitions of the target Pydantic model and any related models."
)
prompt = InputField(
desc="Data structure and values to be converted into `kwargs` for the Pydantic model instantiation."
)
root_model_kwargs_dict = OutputField(
prefix="kwargs_dict: dict = ",
desc="Python dictionary (as a string) representing the keyword arguments for initializing the Pydantic model. The dictionary is minimized in terms of whitespace and includes only JSON-compatible values."
)


class PromptToPydanticInstanceErrorSignature(Signature):
error = InputField(
desc="An error message indicating issues with previously generated `kwargs`, used to guide adjustments in the synthesis process."
)
# Inheriting fields from PromptToPydanticInstanceSignature
root_pydantic_model_class_name = InputField(
desc="Class name of the Pydantic model to be corrected based on the error."
)
pydantic_model_definitions = InputField(
desc="Python class definitions of the Pydantic model and any dependencies, provided as a string."
)
prompt = InputField(
desc="Original natural language prompt, potentially adjusted to incorporate insights from the error message."
)
root_model_kwargs_dict = OutputField(
prefix="kwargs_dict = ",
desc="Refined Python dictionary (as a string) for model initialization, adjusted to address the provided error message. Ensures minimized whitespace and JSON-compatible values."
)


# Example usage
def main():
lm = dspy.OpenAI(max_tokens=1000)
Expand Down Expand Up @@ -161,29 +199,26 @@ def main():

def generate_icalendar_models():
for entity, description in icalendar_entities.items():
# generate_answer = dspy.ChainOfThought("question -> answer")
# prompt = f"What are the exact fields or attributes of the {entity} in RFC 5545?"
# answer = generate_answer(question=prompt).answer
# print(f"{entity}: {answer}")

# Define a Pydantic class dynamically for each entity
model_prompt = f'I need a model named {entity}Model that has all of the relevant fields for RFC 5545 compliance.'

model_module = GenPydanticInstance(root_model=PydanticClassTemplateSpecificationModel,
child_models=[FieldTemplateSpecificationModel])
child_models=[FieldTemplateSpecificationModel],
generate_sig=PromptToPydanticInstanceSignature,
correct_generate_sig=PromptToPydanticInstanceErrorSignature)

model_inst = model_module.forward(model_prompt)

print(model_inst)

# Render the Pydantic class from the specification
rendered_class_str = render_pydantic_class(model_inst, template_str)
rendered_class_str = render(template_str, model=model_inst)

# Write the rendered class to a Python file
write_pydantic_class_to_file(rendered_class_str, f"ical/{inflection.underscore(model_inst.class_name)}.py")

print(f"{model_inst.class_name} written to {model_inst.class_name}.py")


if __name__ == '__main__':
lm = dspy.OpenAI(max_tokens=3000)
dspy.settings.configure(lm=lm)
Expand Down
10 changes: 6 additions & 4 deletions src/rdddy/generators/gen_pydantic_instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class PromptToPydanticInstanceSignature(Signature):
)


class PromptToPydanticInstanceErrorSignature(PromptToPydanticInstanceSignature):
class PromptToPydanticInstanceErrorSignature(Signature):
"""Synthesize the prompt into the kwargs fit the model"""

error = InputField(desc="Error message to fix the kwargs")
Expand Down Expand Up @@ -62,7 +62,9 @@ class GenPydanticInstance(Module):
with a prompt to generate Pydantic model instances based on the provided prompt.
"""

def __init__(self, root_model: Type[T], child_models: list[Type[BaseModel]] = None):
def __init__(self, root_model: Type[T], child_models: list[Type[BaseModel]] = None,
generate_sig=PromptToPydanticInstanceSignature,
correct_generate_sig=PromptToPydanticInstanceErrorSignature):
super().__init__()

if not issubclass(root_model, BaseModel):
Expand All @@ -88,8 +90,8 @@ def __init__(self, root_model: Type[T], child_models: list[Type[BaseModel]] = No
)

# Initialize DSPy ChainOfThought modules for generation and correction
self.generate = ChainOfThought(PromptToPydanticInstanceSignature)
self.correct_generate = ChainOfThought(PromptToPydanticInstanceErrorSignature)
self.generate = ChainOfThought(generate_sig)
self.correct_generate = ChainOfThought(correct_generate_sig)
self.validation_error = None

def validate_root_model(self, output: str) -> bool:
Expand Down
23 changes: 23 additions & 0 deletions src/rdddy/generators/ical/valarm_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from pydantic import BaseModel, Field, validator, root_validator, EmailStr, UrlStr
from typing import List, Optional
from datetime import datetime


class VALARMModel(BaseModel):
"""A Pydantic model for RFC 5545 compliance."""
action: str = Field(default=None, title="", description="The action associated with the alarm.")
trigger: str = Field(default=None, title="", description="The trigger for the alarm.")
duration: str = Field(default=None, title="", description="The duration of the alarm.")
repeat: int = Field(default=None, title="", description="The number of times the alarm should be repeated.", ge=0)
description: str = Field(default=None, title="", description="A description of the alarm.")
summary: str = Field(default=None, title="", description="A summary of the alarm.")
attendees: List[str] = Field(default=None, title="", description="A list of attendees for the alarm.")
acknowledged: datetime = Field(default=None, title="", description="The date and time the alarm was acknowledged.")
related_to: str = Field(default=None, title="", description="The related event or to-do for the alarm.")
uid: str = Field(default=None, title="", description="The unique identifier for the alarm.")
created: datetime = Field(default=None, title="", description="The date and time the alarm was created.")
last_modified: datetime = Field(default=None, title="", description="The date and time the alarm was last modified.")
sequence: int = Field(default=None, title="", description="The sequence number for the alarm.", ge=0)
x_prop: str = Field(default=None, title="", description="Any additional custom properties for the alarm.")
attach: List[str] = Field(default=None, title="", description="A list of attachments for the alarm.")

Loading

0 comments on commit c3e73ac

Please sign in to comment.