agno 2.2.4__py3-none-any.whl → 2.2.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. agno/agent/agent.py +82 -19
  2. agno/culture/manager.py +3 -4
  3. agno/knowledge/chunking/agentic.py +6 -2
  4. agno/memory/manager.py +9 -4
  5. agno/models/anthropic/claude.py +1 -2
  6. agno/models/azure/ai_foundry.py +31 -14
  7. agno/models/azure/openai_chat.py +12 -4
  8. agno/models/base.py +44 -11
  9. agno/models/cerebras/cerebras.py +11 -6
  10. agno/models/groq/groq.py +7 -4
  11. agno/models/meta/llama.py +12 -6
  12. agno/models/meta/llama_openai.py +5 -1
  13. agno/models/openai/chat.py +20 -12
  14. agno/models/openai/responses.py +10 -5
  15. agno/models/utils.py +254 -8
  16. agno/models/vertexai/claude.py +9 -13
  17. agno/os/app.py +48 -21
  18. agno/os/routers/evals/evals.py +8 -8
  19. agno/os/routers/evals/utils.py +1 -0
  20. agno/os/schema.py +48 -33
  21. agno/os/utils.py +27 -0
  22. agno/run/agent.py +5 -0
  23. agno/run/team.py +2 -0
  24. agno/run/workflow.py +39 -0
  25. agno/session/summary.py +8 -2
  26. agno/session/workflow.py +4 -3
  27. agno/team/team.py +50 -14
  28. agno/tools/file.py +153 -25
  29. agno/tools/function.py +5 -1
  30. agno/tools/notion.py +201 -0
  31. agno/utils/events.py +2 -0
  32. agno/utils/print_response/workflow.py +115 -16
  33. agno/vectordb/milvus/milvus.py +5 -0
  34. agno/workflow/__init__.py +2 -0
  35. agno/workflow/agent.py +298 -0
  36. agno/workflow/workflow.py +929 -64
  37. {agno-2.2.4.dist-info → agno-2.2.6.dist-info}/METADATA +4 -1
  38. {agno-2.2.4.dist-info → agno-2.2.6.dist-info}/RECORD +41 -39
  39. {agno-2.2.4.dist-info → agno-2.2.6.dist-info}/WHEEL +0 -0
  40. {agno-2.2.4.dist-info → agno-2.2.6.dist-info}/licenses/LICENSE +0 -0
  41. {agno-2.2.4.dist-info → agno-2.2.6.dist-info}/top_level.txt +0 -0
@@ -356,10 +356,10 @@ def attach_routes(
356
356
  ):
357
357
  default_model = deepcopy(agent.model)
358
358
  if eval_run_input.model_id != agent.model.id or eval_run_input.model_provider != agent.model.provider:
359
- model = get_model(
360
- model_id=eval_run_input.model_id.lower(),
361
- model_provider=eval_run_input.model_provider.lower(),
362
- )
359
+ model_provider = eval_run_input.model_provider.lower()
360
+ model_id = eval_run_input.model_id.lower()
361
+ model_string = f"{model_provider}:{model_id}"
362
+ model = get_model(model_string)
363
363
  agent.model = model
364
364
 
365
365
  team = None
@@ -378,10 +378,10 @@ def attach_routes(
378
378
  ):
379
379
  default_model = deepcopy(team.model)
380
380
  if eval_run_input.model_id != team.model.id or eval_run_input.model_provider != team.model.provider:
381
- model = get_model(
382
- model_id=eval_run_input.model_id.lower(),
383
- model_provider=eval_run_input.model_provider.lower(),
384
- )
381
+ model_provider = eval_run_input.model_provider.lower()
382
+ model_id = eval_run_input.model_id.lower()
383
+ model_string = f"{model_provider}:{model_id}"
384
+ model = get_model(model_string)
385
385
  team.model = model
386
386
 
387
387
  agent = None
@@ -33,6 +33,7 @@ async def run_accuracy_eval(
33
33
  additional_context=eval_run_input.additional_context,
34
34
  num_iterations=eval_run_input.num_iterations or 1,
35
35
  name=eval_run_input.name,
36
+ model=default_model,
36
37
  )
37
38
 
38
39
  result = accuracy_eval.run(print_results=False, print_summary=False)
agno/os/schema.py CHANGED
@@ -13,14 +13,17 @@ from agno.os.utils import (
13
13
  extract_input_media,
14
14
  format_team_tools,
15
15
  format_tools,
16
+ get_agent_input_schema_dict,
16
17
  get_run_input,
17
18
  get_session_name,
19
+ get_team_input_schema_dict,
18
20
  get_workflow_input_schema_dict,
19
21
  )
20
22
  from agno.run.agent import RunOutput
21
23
  from agno.run.team import TeamRunOutput
22
24
  from agno.session import AgentSession, TeamSession, WorkflowSession
23
25
  from agno.team.team import Team
26
+ from agno.workflow.agent import WorkflowAgent
24
27
  from agno.workflow.workflow import Workflow
25
28
 
26
29
 
@@ -166,21 +169,25 @@ class ModelResponse(BaseModel):
166
169
 
167
170
 
168
171
  class AgentResponse(BaseModel):
169
- id: Optional[str] = Field(None, description="Unique identifier for the agent")
170
- name: Optional[str] = Field(None, description="Name of the agent")
171
- db_id: Optional[str] = Field(None, description="Database identifier")
172
- model: Optional[ModelResponse] = Field(None, description="Model configuration")
173
- tools: Optional[Dict[str, Any]] = Field(None, description="Tool configurations")
174
- sessions: Optional[Dict[str, Any]] = Field(None, description="Session configurations")
175
- knowledge: Optional[Dict[str, Any]] = Field(None, description="Knowledge base configurations")
176
- memory: Optional[Dict[str, Any]] = Field(None, description="Memory configurations")
177
- reasoning: Optional[Dict[str, Any]] = Field(None, description="Reasoning configurations")
178
- default_tools: Optional[Dict[str, Any]] = Field(None, description="Default tool settings")
179
- system_message: Optional[Dict[str, Any]] = Field(None, description="System message configurations")
180
- extra_messages: Optional[Dict[str, Any]] = Field(None, description="Extra message configurations")
181
- response_settings: Optional[Dict[str, Any]] = Field(None, description="Response settings")
182
- streaming: Optional[Dict[str, Any]] = Field(None, description="Streaming configurations")
183
- metadata: Optional[Dict[str, Any]] = Field(None, description="Additional metadata")
172
+ id: Optional[str] = None
173
+ name: Optional[str] = None
174
+ db_id: Optional[str] = None
175
+ model: Optional[ModelResponse] = None
176
+ tools: Optional[Dict[str, Any]] = None
177
+ sessions: Optional[Dict[str, Any]] = None
178
+ knowledge: Optional[Dict[str, Any]] = None
179
+ memory: Optional[Dict[str, Any]] = None
180
+ reasoning: Optional[Dict[str, Any]] = None
181
+ default_tools: Optional[Dict[str, Any]] = None
182
+ system_message: Optional[Dict[str, Any]] = None
183
+ extra_messages: Optional[Dict[str, Any]] = None
184
+ response_settings: Optional[Dict[str, Any]] = None
185
+ streaming: Optional[Dict[str, Any]] = None
186
+ metadata: Optional[Dict[str, Any]] = None
187
+ input_schema: Optional[Dict[str, Any]] = None
188
+
189
+ class Config:
190
+ exclude_none = True
184
191
 
185
192
  @classmethod
186
193
  async def from_agent(cls, agent: Agent) -> "AgentResponse":
@@ -375,6 +382,7 @@ class AgentResponse(BaseModel):
375
382
  "stream_events": agent.stream_events,
376
383
  "stream_intermediate_steps": agent.stream_intermediate_steps,
377
384
  }
385
+
378
386
  return AgentResponse(
379
387
  id=agent.id,
380
388
  name=agent.name,
@@ -391,28 +399,28 @@ class AgentResponse(BaseModel):
391
399
  response_settings=filter_meaningful_config(response_settings_info, agent_defaults),
392
400
  streaming=filter_meaningful_config(streaming_info, agent_defaults),
393
401
  metadata=agent.metadata,
402
+ input_schema=get_agent_input_schema_dict(agent),
394
403
  )
395
404
 
396
405
 
397
406
  class TeamResponse(BaseModel):
398
- id: Optional[str] = Field(None, description="Unique identifier for the team")
399
- name: Optional[str] = Field(None, description="Name of the team")
400
- db_id: Optional[str] = Field(None, description="Database identifier")
401
- description: Optional[str] = Field(None, description="Description of the team")
402
- model: Optional[ModelResponse] = Field(None, description="Model configuration")
403
- tools: Optional[Dict[str, Any]] = Field(None, description="Tool configurations")
404
- sessions: Optional[Dict[str, Any]] = Field(None, description="Session configurations")
405
- knowledge: Optional[Dict[str, Any]] = Field(None, description="Knowledge base configurations")
406
- memory: Optional[Dict[str, Any]] = Field(None, description="Memory configurations")
407
- reasoning: Optional[Dict[str, Any]] = Field(None, description="Reasoning configurations")
408
- default_tools: Optional[Dict[str, Any]] = Field(None, description="Default tool settings")
409
- system_message: Optional[Dict[str, Any]] = Field(None, description="System message configurations")
410
- response_settings: Optional[Dict[str, Any]] = Field(None, description="Response settings")
411
- streaming: Optional[Dict[str, Any]] = Field(None, description="Streaming configurations")
412
- members: Optional[List[Union[AgentResponse, "TeamResponse"]]] = Field(
413
- None, description="List of team members (agents or teams)"
414
- )
415
- metadata: Optional[Dict[str, Any]] = Field(None, description="Additional metadata")
407
+ id: Optional[str] = None
408
+ name: Optional[str] = None
409
+ db_id: Optional[str] = None
410
+ description: Optional[str] = None
411
+ model: Optional[ModelResponse] = None
412
+ tools: Optional[Dict[str, Any]] = None
413
+ sessions: Optional[Dict[str, Any]] = None
414
+ knowledge: Optional[Dict[str, Any]] = None
415
+ memory: Optional[Dict[str, Any]] = None
416
+ reasoning: Optional[Dict[str, Any]] = None
417
+ default_tools: Optional[Dict[str, Any]] = None
418
+ system_message: Optional[Dict[str, Any]] = None
419
+ response_settings: Optional[Dict[str, Any]] = None
420
+ streaming: Optional[Dict[str, Any]] = None
421
+ members: Optional[List[Union[AgentResponse, "TeamResponse"]]] = None
422
+ metadata: Optional[Dict[str, Any]] = None
423
+ input_schema: Optional[Dict[str, Any]] = None
416
424
 
417
425
  @classmethod
418
426
  async def from_team(cls, team: Team) -> "TeamResponse":
@@ -621,6 +629,7 @@ class TeamResponse(BaseModel):
621
629
  streaming=filter_meaningful_config(streaming_info, team_defaults),
622
630
  members=members if members else None,
623
631
  metadata=team.metadata,
632
+ input_schema=get_team_input_schema_dict(team),
624
633
  )
625
634
 
626
635
 
@@ -634,6 +643,7 @@ class WorkflowResponse(BaseModel):
634
643
  agent: Optional[AgentResponse] = Field(None, description="Agent configuration if used")
635
644
  team: Optional[TeamResponse] = Field(None, description="Team configuration if used")
636
645
  metadata: Optional[Dict[str, Any]] = Field(None, description="Additional metadata")
646
+ workflow_agent: bool = Field(False, description="Whether this workflow uses a WorkflowAgent")
637
647
 
638
648
  @classmethod
639
649
  async def _resolve_agents_and_teams_recursively(cls, steps: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
@@ -685,6 +695,7 @@ class WorkflowResponse(BaseModel):
685
695
  steps=steps,
686
696
  input_schema=get_workflow_input_schema_dict(workflow),
687
697
  metadata=workflow.metadata,
698
+ workflow_agent=isinstance(workflow.agent, WorkflowAgent) if workflow.agent else False,
688
699
  )
689
700
 
690
701
 
@@ -870,6 +881,7 @@ class RunSchema(BaseModel):
870
881
  created_at: Optional[datetime] = Field(None, description="Run creation timestamp")
871
882
  references: Optional[List[dict]] = Field(None, description="References cited in the run")
872
883
  reasoning_messages: Optional[List[dict]] = Field(None, description="Reasoning process messages")
884
+ session_state: Optional[dict] = Field(None, description="Session state at the end of the run")
873
885
  images: Optional[List[dict]] = Field(None, description="Images included in the run")
874
886
  videos: Optional[List[dict]] = Field(None, description="Videos included in the run")
875
887
  audio: Optional[List[dict]] = Field(None, description="Audio files included in the run")
@@ -897,6 +909,7 @@ class RunSchema(BaseModel):
897
909
  events=[event for event in run_dict["events"]] if run_dict.get("events") else None,
898
910
  references=run_dict.get("references", []),
899
911
  reasoning_messages=run_dict.get("reasoning_messages", []),
912
+ session_state=run_dict.get("session_state"),
900
913
  images=run_dict.get("images", []),
901
914
  videos=run_dict.get("videos", []),
902
915
  audio=run_dict.get("audio", []),
@@ -925,6 +938,7 @@ class TeamRunSchema(BaseModel):
925
938
  created_at: Optional[datetime] = Field(None, description="Run creation timestamp")
926
939
  references: Optional[List[dict]] = Field(None, description="References cited in the run")
927
940
  reasoning_messages: Optional[List[dict]] = Field(None, description="Reasoning process messages")
941
+ session_state: Optional[dict] = Field(None, description="Session state at the end of the run")
928
942
  input_media: Optional[Dict[str, Any]] = Field(None, description="Input media attachments")
929
943
  images: Optional[List[dict]] = Field(None, description="Images included in the run")
930
944
  videos: Optional[List[dict]] = Field(None, description="Videos included in the run")
@@ -954,6 +968,7 @@ class TeamRunSchema(BaseModel):
954
968
  else None,
955
969
  references=run_dict.get("references", []),
956
970
  reasoning_messages=run_dict.get("reasoning_messages", []),
971
+ session_state=run_dict.get("session_state"),
957
972
  images=run_dict.get("images", []),
958
973
  videos=run_dict.get("videos", []),
959
974
  audio=run_dict.get("audio", []),
agno/os/utils.py CHANGED
@@ -274,6 +274,33 @@ def get_workflow_by_id(workflow_id: str, workflows: Optional[List[Workflow]] = N
274
274
  return None
275
275
 
276
276
 
277
+ # INPUT SCHEMA VALIDATIONS
278
+
279
+
280
+ def get_agent_input_schema_dict(agent: Agent) -> Optional[Dict[str, Any]]:
281
+ """Get input schema as dictionary for API responses"""
282
+
283
+ if agent.input_schema is not None:
284
+ try:
285
+ return agent.input_schema.model_json_schema()
286
+ except Exception:
287
+ return None
288
+
289
+ return None
290
+
291
+
292
+ def get_team_input_schema_dict(team: Team) -> Optional[Dict[str, Any]]:
293
+ """Get input schema as dictionary for API responses"""
294
+
295
+ if team.input_schema is not None:
296
+ try:
297
+ return team.input_schema.model_json_schema()
298
+ except Exception:
299
+ return None
300
+
301
+ return None
302
+
303
+
277
304
  def get_workflow_input_schema_dict(workflow: Workflow) -> Optional[Dict[str, Any]]:
278
305
  """Get input schema as dictionary for API responses"""
279
306
 
agno/run/agent.py CHANGED
@@ -221,6 +221,9 @@ class RunContentEvent(BaseAgentRunEvent):
221
221
 
222
222
  event: str = RunEvent.run_content.value
223
223
  content: Optional[Any] = None
224
+ workflow_agent: bool = (
225
+ False # Used by consumers of the events to distinguish between workflow agent and regular agent
226
+ )
224
227
  content_type: str = "str"
225
228
  reasoning_content: Optional[str] = None
226
229
  model_provider_data: Optional[Dict[str, Any]] = None
@@ -263,6 +266,7 @@ class RunCompletedEvent(BaseAgentRunEvent):
263
266
  reasoning_messages: Optional[List[Message]] = None
264
267
  metadata: Optional[Dict[str, Any]] = None
265
268
  metrics: Optional[Metrics] = None
269
+ session_state: Optional[Dict[str, Any]] = None
266
270
 
267
271
 
268
272
  @dataclass
@@ -527,6 +531,7 @@ class RunOutput:
527
531
  references: Optional[List[MessageReferences]] = None
528
532
 
529
533
  metadata: Optional[Dict[str, Any]] = None
534
+ session_state: Optional[Dict[str, Any]] = None
530
535
 
531
536
  created_at: int = field(default_factory=lambda: int(time()))
532
537
 
agno/run/team.py CHANGED
@@ -261,6 +261,7 @@ class RunCompletedEvent(BaseTeamRunEvent):
261
261
  member_responses: List[Union["TeamRunOutput", RunOutput]] = field(default_factory=list)
262
262
  metadata: Optional[Dict[str, Any]] = None
263
263
  metrics: Optional[Metrics] = None
264
+ session_state: Optional[Dict[str, Any]] = None
264
265
 
265
266
 
266
267
  @dataclass
@@ -500,6 +501,7 @@ class TeamRunOutput:
500
501
  citations: Optional[Citations] = None
501
502
  model_provider_data: Optional[Dict[str, Any]] = None
502
503
  metadata: Optional[Dict[str, Any]] = None
504
+ session_state: Optional[Dict[str, Any]] = None
503
505
 
504
506
  references: Optional[List[MessageReferences]] = None
505
507
  additional_input: Optional[List[Message]] = None
agno/run/workflow.py CHANGED
@@ -31,6 +31,9 @@ class WorkflowRunEvent(str, Enum):
31
31
  workflow_cancelled = "WorkflowCancelled"
32
32
  workflow_error = "WorkflowError"
33
33
 
34
+ workflow_agent_started = "WorkflowAgentStarted"
35
+ workflow_agent_completed = "WorkflowAgentCompleted"
36
+
34
37
  step_started = "StepStarted"
35
38
  step_completed = "StepCompleted"
36
39
  step_error = "StepError"
@@ -126,6 +129,21 @@ class WorkflowStartedEvent(BaseWorkflowRunOutputEvent):
126
129
  event: str = WorkflowRunEvent.workflow_started.value
127
130
 
128
131
 
132
+ @dataclass
133
+ class WorkflowAgentStartedEvent(BaseWorkflowRunOutputEvent):
134
+ """Event sent when workflow agent starts (before deciding to run workflow or answer directly)"""
135
+
136
+ event: str = WorkflowRunEvent.workflow_agent_started.value
137
+
138
+
139
+ @dataclass
140
+ class WorkflowAgentCompletedEvent(BaseWorkflowRunOutputEvent):
141
+ """Event sent when workflow agent completes (after running workflow or answering directly)"""
142
+
143
+ event: str = WorkflowRunEvent.workflow_agent_completed.value
144
+ content: Optional[Any] = None
145
+
146
+
129
147
  @dataclass
130
148
  class WorkflowCompletedEvent(BaseWorkflowRunOutputEvent):
131
149
  """Event sent when workflow execution completes"""
@@ -403,6 +421,8 @@ class CustomEvent(BaseWorkflowRunOutputEvent):
403
421
  # Union type for all workflow run response events
404
422
  WorkflowRunOutputEvent = Union[
405
423
  WorkflowStartedEvent,
424
+ WorkflowAgentStartedEvent,
425
+ WorkflowAgentCompletedEvent,
406
426
  WorkflowCompletedEvent,
407
427
  WorkflowErrorEvent,
408
428
  WorkflowCancelledEvent,
@@ -428,6 +448,8 @@ WorkflowRunOutputEvent = Union[
428
448
  # Map event string to dataclass for workflow events
429
449
  WORKFLOW_RUN_EVENT_TYPE_REGISTRY = {
430
450
  WorkflowRunEvent.workflow_started.value: WorkflowStartedEvent,
451
+ WorkflowRunEvent.workflow_agent_started.value: WorkflowAgentStartedEvent,
452
+ WorkflowRunEvent.workflow_agent_completed.value: WorkflowAgentCompletedEvent,
431
453
  WorkflowRunEvent.workflow_completed.value: WorkflowCompletedEvent,
432
454
  WorkflowRunEvent.workflow_cancelled.value: WorkflowCancelledEvent,
433
455
  WorkflowRunEvent.workflow_error.value: WorkflowErrorEvent,
@@ -491,6 +513,10 @@ class WorkflowRunOutput:
491
513
  # Store agent/team responses separately with parent_run_id references
492
514
  step_executor_runs: Optional[List[Union[RunOutput, TeamRunOutput]]] = None
493
515
 
516
+ # Workflow agent run - stores the full agent RunOutput when workflow agent is used
517
+ # The agent's parent_run_id will point to this workflow run's run_id to establish the relationship
518
+ workflow_agent_run: Optional[RunOutput] = None
519
+
494
520
  # Store events from workflow execution
495
521
  events: Optional[List[WorkflowRunOutputEvent]] = None
496
522
 
@@ -522,6 +548,7 @@ class WorkflowRunOutput:
522
548
  "step_executor_runs",
523
549
  "events",
524
550
  "metrics",
551
+ "workflow_agent_run",
525
552
  ]
526
553
  }
527
554
 
@@ -557,6 +584,9 @@ class WorkflowRunOutput:
557
584
  if self.step_executor_runs:
558
585
  _dict["step_executor_runs"] = [run.to_dict() for run in self.step_executor_runs]
559
586
 
587
+ if self.workflow_agent_run is not None:
588
+ _dict["workflow_agent_run"] = self.workflow_agent_run.to_dict()
589
+
560
590
  if self.metrics is not None:
561
591
  _dict["metrics"] = self.metrics.to_dict()
562
592
 
@@ -604,6 +634,14 @@ class WorkflowRunOutput:
604
634
  else:
605
635
  step_executor_runs.append(RunOutput.from_dict(run_data))
606
636
 
637
+ workflow_agent_run_data = data.pop("workflow_agent_run", None)
638
+ workflow_agent_run = None
639
+ if workflow_agent_run_data:
640
+ if isinstance(workflow_agent_run_data, dict):
641
+ workflow_agent_run = RunOutput.from_dict(workflow_agent_run_data)
642
+ elif isinstance(workflow_agent_run_data, RunOutput):
643
+ workflow_agent_run = workflow_agent_run_data
644
+
607
645
  metadata = data.pop("metadata", None)
608
646
 
609
647
  images = reconstruct_images(data.pop("images", []))
@@ -640,6 +678,7 @@ class WorkflowRunOutput:
640
678
 
641
679
  return cls(
642
680
  step_results=parsed_step_results,
681
+ workflow_agent_run=workflow_agent_run,
643
682
  metadata=metadata,
644
683
  images=images,
645
684
  videos=videos,
agno/session/summary.py CHANGED
@@ -1,11 +1,12 @@
1
1
  from dataclasses import dataclass
2
2
  from datetime import datetime
3
3
  from textwrap import dedent
4
- from typing import TYPE_CHECKING, Any, Dict, List, Optional, Type, Union, cast
4
+ from typing import TYPE_CHECKING, Any, Dict, List, Optional, Type, Union
5
5
 
6
6
  from pydantic import BaseModel, Field
7
7
 
8
8
  from agno.models.base import Model
9
+ from agno.models.utils import get_model
9
10
  from agno.run.agent import Message
10
11
  from agno.utils.log import log_debug, log_warning
11
12
 
@@ -142,7 +143,10 @@ class SessionSummaryManager:
142
143
  if not session:
143
144
  return None
144
145
 
145
- self.model = cast(Model, self.model)
146
+ self.model = get_model(self.model)
147
+ if self.model is None:
148
+ return None
149
+
146
150
  response_format = self.get_response_format(self.model)
147
151
 
148
152
  system_message = self.get_system_message(
@@ -210,6 +214,7 @@ class SessionSummaryManager:
210
214
  ) -> Optional[SessionSummary]:
211
215
  """Creates a summary of the session"""
212
216
  log_debug("Creating session summary", center=True)
217
+ self.model = get_model(self.model)
213
218
  if self.model is None:
214
219
  return None
215
220
 
@@ -237,6 +242,7 @@ class SessionSummaryManager:
237
242
  ) -> Optional[SessionSummary]:
238
243
  """Creates a summary of the session"""
239
244
  log_debug("Creating session summary", center=True)
245
+ self.model = get_model(self.model)
240
246
  if self.model is None:
241
247
  return None
242
248
 
agno/session/workflow.py CHANGED
@@ -129,12 +129,12 @@ class WorkflowSession:
129
129
  context_parts = ["<workflow_history_context>"]
130
130
 
131
131
  for i, (input_str, response_str) in enumerate(history_data, 1):
132
- context_parts.append(f"[run-{i}]")
132
+ context_parts.append(f"[Workflow Run-{i}]")
133
133
 
134
134
  if input_str:
135
- context_parts.append(f"input: {input_str}")
135
+ context_parts.append(f"User input: {input_str}")
136
136
  if response_str:
137
- context_parts.append(f"response: {response_str}")
137
+ context_parts.append(f"Workflow output: {response_str}")
138
138
 
139
139
  context_parts.append("") # Empty line between runs
140
140
 
@@ -154,6 +154,7 @@ class WorkflowSession:
154
154
  runs_data.append(run.to_dict())
155
155
  except Exception as e:
156
156
  raise ValueError(f"Serialization failed: {str(e)}")
157
+
157
158
  return {
158
159
  "session_id": self.session_id,
159
160
  "user_id": self.user_id,