import os import asyncio from langchain_openai import ChatOpenAI from langchain_core.messages import HumanMessage from langchain.tools import tool from deepagents import create_deep_agent from deepagents.backends import CompositeBackend, LocalShellBackend, FilesystemBackend from pydantic import BaseModel, Field from langchain_core.output_parsers import PydanticOutputParser # LLM configuration – OpenRouter llm = ChatOpenAI( model="openai/gpt-oss-20b:free", base_url="https://openrouter.ai/api/v1", api_key=os.getenv("OPENAI_API_KEY"), temperature=0.0, ) # Backend for file operations and shell execution (not used directly but required by deepagents) backend = CompositeBackend([ LocalShellBackend(workspace_dir="./workspace"), FilesystemBackend(), ]) # Structured output model for the AI fluency plan class FluencyPlan(BaseModel): goal: str = Field(description="Overall goal of the AI fluency plan") timeline: str = Field(description="High‑level timeline (e.g., 3 months, 6 months)") milestones: list[str] = Field(description="Key milestones to achieve along the way") resources: list[str] = Field(description="Recommended courses, books, tools, and communities") assessment: str = Field(description="How to assess progress and adjust the plan") parser = PydanticOutputParser(pydantic_object=FluencyPlan) # Simple validation tool to ensure the plan is not empty @tool def validate_plan(plan: str) -> str: """Validate that the plan contains at least one milestone and resources.""" if "milestones" not in plan.lower() or "resources" not in plan.lower(): return "Plan is missing essential sections." return "OK" # Create the deep agent agent = create_deep_agent( model=llm, tools=[validate_plan], backend=backend, system_prompt="You are an expert educational planner. Your task is to create a detailed personal AI fluency plan based on the course " "Ai Fluency and the Build a personal AI fluency plan assignment. The output must be a JSON object that matches the FluencyPlan schema." ) async def main(): # Human message with the assignment description human_msg = HumanMessage(content="Create a personal AI fluency plan for completing the Ai Fluency course and the Build a personal AI fluency plan assignment. Use the provided schema.") # Invoke the agent result = await agent.ainvoke( {"messages": [human_msg]}, {"configurable": {"thread_id": "ai-fluency-plan"}}, ) # Extract the assistant message assistant_msg = result["messages"][-1].content # Parse the JSON using the Pydantic parser to ensure correctness try: plan_obj = parser.parse(assistant_msg) print("✅ Generated AI Fluency Plan:\n", plan_obj.json(indent=2)) except Exception as e: print("❌ Failed to parse plan:", e) print("Raw output:", assistant_msg) if __name__ == "__main__": asyncio.run(main())