smarta2a 0.4.21__py3-none-any.whl → 0.4.22__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.
@@ -37,7 +37,7 @@ class A2AHuman:
37
37
 
38
38
  @self.app.on_send_task(forward_to_webhook=True)
39
39
  async def on_send_task(request: SendTaskRequest, state: StateData):
40
- return "I am human and take some time to respond, but I will definitely respond to your request"
40
+ pass
41
41
 
42
42
  @self.app.webhook()
43
43
  async def on_webhook(request: WebhookRequest, state: StateData):
@@ -1,15 +1,19 @@
1
1
  # Library imports
2
2
  from typing import Callable, Any, Optional
3
+ import copy
4
+ from uuid import uuid4
3
5
 
4
6
  # Local imports
5
7
  from smarta2a.server.state_manager import StateManager
6
- from smarta2a.utils.types import WebhookRequest, WebhookResponse, StateData, Message
8
+ from smarta2a.utils.types import WebhookRequest, WebhookResponse, StateData, Message, TaskState
9
+ from smarta2a.utils.task_builder import TaskBuilder
7
10
  from smarta2a.client.a2a_client import A2AClient
8
11
 
9
12
  class WebhookRequestProcessor:
10
13
  def __init__(self, webhook_fn: Callable[[WebhookRequest], Any], state_manager: Optional[StateManager] = None):
11
14
  self.webhook_fn = webhook_fn
12
15
  self.state_manager = state_manager
16
+ self.task_builder = TaskBuilder(default_status=TaskState.COMPLETED)
13
17
  self.a2a_aclient = A2AClient()
14
18
 
15
19
  async def process_request(self, request: WebhookRequest) -> WebhookResponse:
@@ -18,67 +22,105 @@ class WebhookRequestProcessor:
18
22
  return await self._webhook_handler(request, state_data)
19
23
  else:
20
24
  return await self._webhook_handler(request)
21
-
25
+
22
26
 
23
27
  async def _webhook_handler(self, request: WebhookRequest, state_data: Optional[StateData] = None) -> WebhookResponse:
24
28
  try:
25
- # --- Step 1: Process Incoming Task ---
26
- if request.result:
27
- incoming_task = request.result
28
-
29
- # Initialize state_data if missing
30
- if not state_data:
31
- state_data = StateData(
32
- task_id=incoming_task.id,
33
- task=incoming_task.copy(update={"artifacts": incoming_task.artifacts}),
34
- context_history=[],
35
- push_notification_config=None
36
- )
29
+ # Extract parameters from request
30
+ task_id = request.id
31
+ task = request.result
37
32
 
38
- # --- Step 2: Call Webhook Function ---
39
- webhook_response = await self.webhook_fn(request, state_data) if state_data else await self.webhook_fn(request)
33
+ if state_data:
34
+ session_id = task.sessionId if task and task.sessionId else state_data.task.sessionId
35
+ task_history = task.history if task and task.history is not None else state_data.task.history.copy() if state_data.task.history else []
36
+ context_history = state_data.context_history.copy()
37
+ metadata = task.metadata if task and task.metadata is not None else state_data.task.metadata.copy() if state_data.task.metadata else {}
38
+ # Deep copy of push_notification_config
39
+ push_notification_config = copy.deepcopy(state_data.push_notification_config) if state_data.push_notification_config else None
40
+ else:
41
+ # No state_data so just assign based on task from the request
42
+ session_id = task.sessionId if task and task.sessionId else str(uuid4())
43
+ task_history = task.history if task and task.history else []
44
+ context_history = []
45
+ metadata = task.metadata if task and task.metadata else {}
46
+ push_notification_config = None
40
47
 
41
- # --- Step 3: Process Webhook Response ---
42
- if webhook_response.result:
43
- updated_task = webhook_response.result
44
- existing_task = state_data.task
45
-
46
- # Overwrite artifacts from response
47
- existing_task.artifacts = updated_task.artifacts.copy() if updated_task.artifacts else []
48
-
49
- # Merge metadata
50
- existing_task.metadata = {**(existing_task.metadata or {}), **(updated_task.metadata or {})}
51
-
52
- # Build messages from updated artifacts
53
- updated_parts = [part for artifact in updated_task.artifacts for part in artifact.parts] if updated_task.artifacts else []
54
- updated_messages = [Message(role="agent", parts=updated_parts, metadata=updated_task.metadata)]
55
-
56
- # Update context history again
57
- if self.state_manager:
58
- history_strategy = self.state_manager.get_history_strategy()
59
- state_data.context_history = history_strategy.update_history(
60
- existing_history=state_data.context_history,
61
- new_messages=updated_messages
62
- )
63
- await self.state_manager.update_state(state_data)
64
-
65
- # --- Step 4: Push Notification ---
66
- push_url = state_data.push_notification_config.url if state_data and state_data.push_notification_config else None
48
+ # Call webhook handler
49
+ if state_data:
50
+ # Call webhook_fn with state_data
51
+ raw_result = await self.webhook_fn(request, state_data)
52
+ else:
53
+ # Call webhook_fn with request
54
+ raw_result = await self.webhook_fn(request)
55
+
56
+ # Handle direct WebhookResponse returns
57
+ if isinstance(raw_result, WebhookResponse):
58
+ return raw_result
59
+
60
+ # Process webhook_response in a way that is similar to handle_send_task
61
+ # Build task with updated history
62
+ updated_task = self.task_builder.build(
63
+ content=raw_result,
64
+ task_id=task_id,
65
+ session_id=session_id,
66
+ metadata=metadata,
67
+ history=task_history
68
+ )
69
+
70
+ # Process messages through strategy (similar to handle_send_task)
71
+ messages = []
72
+ if updated_task.artifacts:
73
+ agent_parts = [p for a in updated_task.artifacts for p in a.parts]
74
+ agent_message = Message(
75
+ role="agent",
76
+ parts=agent_parts,
77
+ metadata=updated_task.metadata
78
+ )
79
+ messages.append(agent_message)
80
+
81
+ # Update Task history with a simple append
82
+ task_history.extend(messages)
67
83
 
68
- if push_url:
84
+ if state_data:
85
+ # Update context history with a strategy
86
+ history_strategy = self.state_manager.get_history_strategy()
87
+ context_history = history_strategy.update_history(
88
+ existing_history=context_history,
89
+ new_messages=messages
90
+ )
91
+
92
+ # Update task with final state
93
+ updated_task.history = task_history
94
+
95
+ # State store update (if enabled)
96
+ if state_data:
97
+ await self.state_manager.update_state(
98
+ state_data=StateData(
99
+ task_id=task_id,
100
+ task=updated_task,
101
+ context_history=context_history,
102
+ push_notification_config=push_notification_config,
103
+ )
104
+ )
105
+ print("--- push_notification_config ---")
106
+ print(push_notification_config)
107
+ print("--- end of push_notification_config ---")
108
+ # If push_notification_config is set send the task to the push notification url
109
+ if push_notification_config:
69
110
  try:
70
- self.a2a_aclient.send_to_webhook(webhook_url=push_url, id=state_data.task_id, task=state_data.task)
111
+ await self.a2a_aclient.send_to_webhook(webhook_url=push_notification_config.url,id=task_id,task=updated_task.model_dump())
71
112
  except Exception as e:
72
- return WebhookResponse(
73
- id=request.id,
74
- error=f"Push notification failed: {str(e)}"
75
- )
76
-
77
- # --- Step 5: Return Final Response ---
113
+ pass
114
+
115
+ # Return the updated task
78
116
  return WebhookResponse(
79
117
  id=request.id,
80
- result=state_data.task if state_data else None
118
+ result=updated_task
81
119
  )
82
-
120
+
83
121
  except Exception as e:
84
- return WebhookResponse(id=request.id, error=f"Internal error: {str(e)}")
122
+ # Handle exceptions
123
+ return WebhookResponse(
124
+ id=request.id,
125
+ error=str(e)
126
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: smarta2a
3
- Version: 0.4.21
3
+ Version: 0.4.22
4
4
  Summary: a Python framework that helps you build servers and AI agents that communicate using the A2A protocol
5
5
  Project-URL: Homepage, https://github.com/siddharthsma/smarta2a
6
6
  Project-URL: Bug Tracker, https://github.com/siddharthsma/smarta2a/issues
@@ -1,6 +1,6 @@
1
1
  smarta2a/__init__.py,sha256=T_EECYqWrxshix0FbgUv22zlKRX22HFU-HKXcYTOb3w,175
2
2
  smarta2a/agent/a2a_agent.py,sha256=EurcxpV14e3OPWCMutYL0EXMHb5ZKQqAHEGZZF6pNgg,1892
3
- smarta2a/agent/a2a_human.py,sha256=yAW9naxyqStQhWwDamXRZIlw-mT_7RW2wcHyhy3rR6Y,1671
3
+ smarta2a/agent/a2a_human.py,sha256=fJITpCDgUWwe4qCTQtKK3BfxsK0v3R4_yzML3p7xLmE,1579
4
4
  smarta2a/agent/a2a_mcp_server.py,sha256=X_mxkgYgCA_dSNtCvs0rSlOoWYc-8d3Qyxv0e-a7NKY,1015
5
5
  smarta2a/archive/smart_mcp_client.py,sha256=0s2OWFKWSv-_UF7rb9fOrsh1OIYsYOsGukkXXp_E1cU,4158
6
6
  smarta2a/archive/subscription_service.py,sha256=vftmZD94HbdjPFa_1UBvsBm-WkW-s3ZCVq60fF7OCgA,4109
@@ -25,7 +25,7 @@ smarta2a/server/request_handler.py,sha256=tUAoxkrJtOnLPJxdUDMThGPFAxYnNFFofS3QD8
25
25
  smarta2a/server/send_task_handler.py,sha256=fiBeCCHCu9c2H4EJOUc0t3EZgpHVFJy4B_6qZOC140s,6336
26
26
  smarta2a/server/server.py,sha256=E58tvOjAvHf_gYjST76sPEC5piaNyrHePa9k-fSadZA,6797
27
27
  smarta2a/server/state_manager.py,sha256=jFxf9cDxLqjIo87tv_Ynh2dH1vCTFLrVSLPuVg6YWnA,8063
28
- smarta2a/server/webhook_request_processor.py,sha256=PErCC5HbeYsZ7JDf7Cbx_eIf1ZtLGiGe1LsmAD6Oxj0,3985
28
+ smarta2a/server/webhook_request_processor.py,sha256=41GiBn0Arc56xzWV9T6dtHlCtmBnf2JBE4g7iRyR3Tw,5657
29
29
  smarta2a/state_stores/__init__.py,sha256=vafxAqpwvag_cYFH2XKGk3DPmJIWJr4Ioey30yLFkVQ,220
30
30
  smarta2a/state_stores/base_state_store.py,sha256=_3LInM-qepKwwdypJTDNs9-DozBNrKVycwPwUm7bYdU,512
31
31
  smarta2a/state_stores/inmemory_state_store.py,sha256=nEBBUiiqhEluP2MYJjFUImcjIwLJEvL8BWwMbLCb8Fw,1268
@@ -36,7 +36,7 @@ smarta2a/utils/task_builder.py,sha256=wqSyfVHNTaXuGESu09dhlaDi7D007gcN3-8tH-nPQ4
36
36
  smarta2a/utils/task_request_builder.py,sha256=6cOGOqj2Rg43xWM03GRJQzlIZHBptsMCJRp7oD-TDAQ,3362
37
37
  smarta2a/utils/tools_manager.py,sha256=oR5cbwzPZ36hQAsWAgb-c6wFv5BthmCPraD7DSv-Bv8,4332
38
38
  smarta2a/utils/types.py,sha256=kzA6Vv5xXfu1sJuxhEXrglI9e9S6eZVIljMnsrQVyN0,13650
39
- smarta2a-0.4.21.dist-info/METADATA,sha256=q9zzIWTWwn2rIWg2tKHAzmb3CAq204N_XaFQ-NaYBN0,13051
40
- smarta2a-0.4.21.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
41
- smarta2a-0.4.21.dist-info/licenses/LICENSE,sha256=lDbqrxVnzDMY5KJ8JS1WhvkWE8TJaw-O-CHDy-ecsJA,2095
42
- smarta2a-0.4.21.dist-info/RECORD,,
39
+ smarta2a-0.4.22.dist-info/METADATA,sha256=b3qwPx7azGKhLPRY9lgToJeHlXBdp-zAlsyNs_QP2E4,13051
40
+ smarta2a-0.4.22.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
41
+ smarta2a-0.4.22.dist-info/licenses/LICENSE,sha256=lDbqrxVnzDMY5KJ8JS1WhvkWE8TJaw-O-CHDy-ecsJA,2095
42
+ smarta2a-0.4.22.dist-info/RECORD,,