"""Task 69dd4221f309a98be0006b2e – Structured task card parser. The script accepts a single natural‑language description of a course task and returns a validated Pydantic model instance. It demonstrates a one‑shot prompting pattern with a structured output parser. Usage: python main.py "" The script prints the raw model dump and a short human‑readable summary. """ import sys from typing import List from pydantic import BaseModel, Field from langchain_core.prompts import PromptTemplate from langchain_openai import ChatOpenAI from langchain_core.output_parsers import PydanticOutputParser # --------------------------------------------------------------------------- # 1. Pydantic model # --------------------------------------------------------------------------- class TaskCard(BaseModel): """Compact representation of a course task. All fields are optional because the model may not be able to infer every piece of information from a very short description. The parser will still return a valid instance – missing values will be ``None``. """ title: str | None = Field(None, description="Short title of the task") subject: str | None = Field(None, description="Subject or topic of the task") deadline_hint: str | None = Field( None, description="Free‑form hint about the deadline (e.g. 'к пятнице')" ) deliverable_type: str | None = Field( None, description="What is expected to be submitted (report, code, etc.)" ) grading_hints: List[str] | None = Field( None, description="List of hints mentioned about grading" ) # --------------------------------------------------------------------------- # 2. Prompt + chain # --------------------------------------------------------------------------- parser = PydanticOutputParser(pydantic_object=TaskCard) prompt_template = """You are a helper that extracts structured information from a course task description. Return a JSON object that matches the following schema: {schema} The input description is: {description} Respond ONLY with the JSON object. Do not add any extra text. """ prompt = PromptTemplate( template=prompt_template, input_variables=["description"], partial_variables={"schema": parser.get_format_instructions()}, ) # LLM – use the default OpenAI OSS endpoint via environment variables llm = ChatOpenAI(model="openai/gpt-oss-20b:free", temperature=0.2) chain = prompt | llm | parser # --------------------------------------------------------------------------- # 3. Main entry point # --------------------------------------------------------------------------- def main() -> None: if len(sys.argv) < 2: print("Usage: python main.py ''") sys.exit(1) description = sys.argv[1] result: TaskCard = chain.invoke({"description": description}) # Print raw model dump print("\n--- Parsed model ---") print(result.model_dump(indent=2)) # Human‑readable summary print("\n--- Summary ---") print(f"Title: {result.title or 'N/A'}") print(f"Subject: {result.subject or 'N/A'}") print(f"Deadline hint: {result.deadline_hint or 'N/A'}") print(f"Deliverable: {result.deliverable_type or 'N/A'}") if result.grading_hints: print("Grading hints:") for hint in result.grading_hints: print(f"- {hint}") else: print("Grading hints: N/A") if __name__ == "__main__": main()