Step with Function using Additional Data
This example demonstrates **Workflows 2.0** support for passing metadata and contextual information to steps via `additional_data`.
This example shows how to pass metadata and contextual information to steps via additional_data. This allows separation of workflow logic from configuration, enabling dynamic behavior based on external context.
Key Features:
- Context-Aware Steps: Access
step_input.additional_datain custom functions - Flexible Metadata: Pass user info, priorities, settings, etc.
- Clean Separation: Keep workflow logic focused while enriching steps with context
1from kern.agent import Agent2from kern.db.sqlite import SqliteDb3from kern.models.openai import OpenAIResponses4from kern.team import Team5from kern.tools.hackernews import HackerNewsTools6from kern.tools.yfinance import YFinanceTools7from kern.workflow.step import Step, StepInput, StepOutput8from kern.workflow.workflow import Workflow910# Define agents11hackernews_agent = Agent(12 name="Hackernews Agent",13 model=OpenAIResponses(id="gpt-5.2"),14 tools=[HackerNewsTools()],15 instructions="Extract key insights and content from Hackernews posts",16)1718finance_agent = Agent(19 name="Finance Agent",20 model=OpenAIResponses(id="gpt-5.2"),21 tools=[YFinanceTools()],22 instructions="Get stock prices and financial data",23)2425# Define research team for complex analysis26research_team = Team(27 name="Research Team",28 members=[hackernews_agent, finance_agent],29 instructions="Analyze content and create comprehensive social media strategy",30)3132content_planner = Agent(33 name="Content Planner",34 model=OpenAIResponses(id="gpt-5.2"),35 instructions=[36 "Plan a content schedule over 4 weeks for the provided topic and research content",37 "Ensure that I have posts for 3 posts per week",38 ],39)404142def custom_content_planning_function(step_input: StepInput) -> StepOutput:43 """44 Custom function that does intelligent content planning with context awareness45 Now also uses additional_data for extra context46 """47 message = step_input.input48 previous_step_content = step_input.previous_step_content4950 # Access additional_data that was passed with the workflow51 additional_data = step_input.additional_data or {}52 user_email = additional_data.get("user_email", "No email provided")53 priority = additional_data.get("priority", "normal")54 client_type = additional_data.get("client_type", "standard")5556 # Create intelligent planning prompt57 planning_prompt = f"""58 STRATEGIC CONTENT PLANNING REQUEST:5960 Core Topic: {message}6162 Research Results: {previous_step_content[:500] if previous_step_content else "No research results"}6364 Additional Context:65 - Client Type: {client_type}66 - Priority Level: {priority}67 - Contact Email: {user_email}6869 Planning Requirements:70 1. Create a comprehensive content strategy based on the research71 2. Leverage the research findings effectively72 3. Identify content formats and channels73 4. Provide timeline and priority recommendations74 5. Include engagement and distribution strategies75 {"6. Mark as HIGH PRIORITY delivery" if priority == "high" else "6. Standard delivery timeline"}7677 Please create a detailed, actionable content plan.78 """7980 try:81 response = content_planner.run(planning_prompt)8283 enhanced_content = f"""84 ## Strategic Content Plan8586 **Planning Topic:** {message}8788 **Client Details:**89 - Type: {client_type}90 - Priority: {priority.upper()}91 - Contact: {user_email}9293 **Research Integration:** {"Research-based" if previous_step_content else "No research foundation"}9495 **Content Strategy:**96 {response.content}9798 **Custom Planning Enhancements:**99 - Research Integration: {"High" if previous_step_content else "Baseline"}100 - Strategic Alignment: Optimized for multi-channel distribution101 - Execution Ready: Detailed action items included102 - Priority Level: {priority.upper()}103 """.strip()104105 return StepOutput(content=enhanced_content, response=response)106107 except Exception as e:108 return StepOutput(109 content=f"Custom content planning failed: {str(e)}",110 success=False,111 )112113114# Define steps using different executor types115116research_step = Step(117 name="Research Step",118 team=research_team,119)120121content_planning_step = Step(122 name="Content Planning Step",123 executor=custom_content_planning_function,124)125126127# Define and use examples128if __name__ == "__main__":129 content_creation_workflow = Workflow(130 name="Content Creation Workflow",131 description="Automated content creation with custom execution options",132 db=SqliteDb(133 session_table="workflow_session",134 db_file="tmp/workflow.db",135 ),136 steps=[research_step, content_planning_step],137 )138139 # Run workflow with additional_data140 content_creation_workflow.print_response(141 input="AI trends in 2024",142 additional_data={143 "user_email": "michael@dundermifflin.com",144 "priority": "high",145 "client_type": "enterprise",146 },147 markdown=True,148 stream=True,149 )150151 print("\n" + "=" * 60 + "\n")