quraite 0.1.2__py3-none-any.whl → 0.1.4__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 (50) hide show
  1. quraite/__init__.py +4 -0
  2. quraite/adapters/__init__.py +1 -1
  3. quraite/adapters/agno_adapter.py +50 -92
  4. quraite/adapters/base.py +26 -76
  5. quraite/adapters/bedrock_agents_adapter.py +23 -76
  6. quraite/adapters/flowise_adapter.py +31 -72
  7. quraite/adapters/google_adk_adapter.py +28 -94
  8. quraite/adapters/http_adapter.py +28 -44
  9. quraite/adapters/langchain_adapter.py +51 -118
  10. quraite/adapters/langchain_server_adapter.py +37 -89
  11. quraite/adapters/langflow_adapter.py +15 -60
  12. quraite/adapters/n8n_adapter.py +19 -63
  13. quraite/adapters/openai_agents_adapter.py +35 -59
  14. quraite/adapters/pydantic_ai_adapter.py +27 -97
  15. quraite/adapters/smolagents_adapter.py +21 -82
  16. quraite/constants/framework.py +14 -0
  17. quraite/schema/__init__.py +4 -0
  18. quraite/schema/invoke.py +46 -0
  19. quraite/schema/message.py +20 -21
  20. quraite/serve/__init__.py +4 -0
  21. quraite/serve/cloudflared.py +3 -2
  22. quraite/serve/server.py +305 -0
  23. quraite/tracing/__init__.py +8 -5
  24. quraite/tracing/constants.py +0 -14
  25. quraite/tracing/setup.py +129 -0
  26. quraite/tracing/span_exporter.py +6 -6
  27. quraite/tracing/span_processor.py +6 -7
  28. quraite/tracing/tool_extractors.py +1 -1
  29. quraite/tracing/trace.py +36 -24
  30. quraite/utils/json_utils.py +2 -2
  31. {quraite-0.1.2.dist-info → quraite-0.1.4.dist-info}/METADATA +54 -62
  32. quraite-0.1.4.dist-info/RECORD +37 -0
  33. quraite/schema/response.py +0 -16
  34. quraite/serve/local_agent.py +0 -360
  35. quraite/traces/traces_adk_openinference.json +0 -379
  36. quraite/traces/traces_agno_multi_agent.json +0 -669
  37. quraite/traces/traces_agno_openinference.json +0 -321
  38. quraite/traces/traces_crewai_openinference.json +0 -155
  39. quraite/traces/traces_langgraph_openinference.json +0 -349
  40. quraite/traces/traces_langgraph_openinference_multi_agent.json +0 -2705
  41. quraite/traces/traces_langgraph_traceloop.json +0 -510
  42. quraite/traces/traces_openai_agents_multi_agent_1.json +0 -402
  43. quraite/traces/traces_openai_agents_openinference.json +0 -341
  44. quraite/traces/traces_pydantic_openinference.json +0 -286
  45. quraite/traces/traces_pydantic_openinference_multi_agent_1.json +0 -399
  46. quraite/traces/traces_pydantic_openinference_multi_agent_2.json +0 -398
  47. quraite/traces/traces_smol_agents_openinference.json +0 -397
  48. quraite/traces/traces_smol_agents_tool_calling_openinference.json +0 -704
  49. quraite-0.1.2.dist-info/RECORD +0 -49
  50. {quraite-0.1.2.dist-info → quraite-0.1.4.dist-info}/WHEEL +0 -0
quraite/__init__.py CHANGED
@@ -1,3 +1,7 @@
1
1
  """Quraite Python SDK"""
2
2
 
3
+ from quraite.serve import create_app, run_agent, setup_tunnel
4
+
3
5
  __version__ = "0.6.0"
6
+
7
+ __all__ = ["create_app", "run_agent", "setup_tunnel"]
@@ -8,9 +8,9 @@ if TYPE_CHECKING:
8
8
  from quraite.adapters.bedrock_agents_adapter import BedrockAgentsAdapter
9
9
  from quraite.adapters.flowise_adapter import FlowiseAdapter
10
10
  from quraite.adapters.google_adk_adapter import GoogleADKAdapter
11
- from quraite.adapters.langflow_adapter import LangflowAdapter
12
11
  from quraite.adapters.langchain_adapter import LangchainAdapter
13
12
  from quraite.adapters.langchain_server_adapter import LangchainServerAdapter
13
+ from quraite.adapters.langflow_adapter import LangflowAdapter
14
14
  from quraite.adapters.n8n_adapter import N8nAdapter
15
15
  from quraite.adapters.openai_agents_adapter import OpenaiAgentsAdapter
16
16
  from quraite.adapters.pydantic_ai_adapter import PydanticAIAdapter
@@ -1,135 +1,93 @@
1
- from typing import List, Union
1
+ import uuid
2
2
 
3
3
  from agno.agent import Agent
4
4
  from agno.team import Team
5
+ from openinference.instrumentation.agno.utils import _AGNO_PARENT_NODE_CONTEXT_KEY
6
+ from opentelemetry import context as context_api
5
7
  from opentelemetry.trace import TracerProvider
6
8
 
7
9
  from quraite.adapters.base import BaseAdapter
10
+ from quraite.constants.framework import Framework
8
11
  from quraite.logger import get_logger
9
- from quraite.schema.message import AgentMessage
10
- from quraite.schema.response import AgentInvocationResponse
11
- from quraite.tracing.constants import Framework
12
+ from quraite.schema.invoke import InvokeInput, InvokeOutput
12
13
  from quraite.tracing.trace import AgentSpan, AgentTrace
13
14
 
14
15
  logger = get_logger(__name__)
15
16
 
16
17
 
17
18
  class AgnoAdapter(BaseAdapter):
18
- """
19
- Agno adapter wrapper that converts any Agno agent or team
20
- to a standardized callable interface (invoke) and converts the output to List[AgentMessage].
21
-
22
- This class wraps any Agno Agent or Team and provides:
23
- - Asynchronous invocation via ainvoke()
24
- - Automatic conversion to List[AgentMessage] format
25
- - Access to message history and traces
26
- - Support for both single agents and multi-agent teams
27
- """
19
+ """Agno adapter for Agent and Team (requires tracing)."""
28
20
 
29
21
  def __init__(
30
22
  self,
31
- agent: Union[Agent, Team],
23
+ agent: Agent | Team,
24
+ *,
25
+ tracer_provider: TracerProvider | None = None,
32
26
  agent_name: str = "Agno Agent",
33
- tracer_provider: TracerProvider = None,
34
27
  ):
35
28
  """
36
- Initialize with a pre-configured Agno agent or team
29
+ Initialize Agno adapter.
37
30
 
38
31
  Args:
39
- agent: An Agno Agent or Team instance
40
- agent_name: Name of the agent for trajectory metadata
41
- tracer_provider: TracerProvider for tracing (required)
32
+ agent: Agno Agent or Team instance
33
+ tracer_provider: TracerProvider from setup_tracing() (required)
34
+ agent_name: Agent name for metadata
42
35
  """
43
- logger.debug("Initializing AgnoAdapter with agent_name=%s", agent_name)
44
- self._init_tracing(tracer_provider, required=True)
36
+ if tracer_provider is None:
37
+ raise ValueError(
38
+ "Agno adapter requires tracing. Use setup_tracing([Framework.AGNO]) first."
39
+ )
45
40
 
46
- self.agent: Union[Agent, Team] = agent
41
+ self.agent: Agent | Team = agent
47
42
  self.agent_name = agent_name
48
- logger.info(
49
- "AgnoAdapter initialized successfully (tracing_enabled=%s)",
50
- bool(tracer_provider),
51
- )
52
-
53
- def _prepare_input(self, input: List[AgentMessage]) -> str:
54
- """
55
- Prepare input for Agno agent from List[AgentMessage].
56
-
57
- Args:
58
- input: List[AgentMessage] containing user_message
59
-
60
- Returns:
61
- str: User message text
62
- """
63
- logger.debug("Preparing input from %d messages", len(input))
64
- if not input or input[-1].role != "user":
65
- logger.error("Invalid input: no user message found")
66
- raise ValueError("No user message found in the input")
67
-
68
- last_user_message = input[-1]
69
- if not last_user_message.content:
70
- logger.error("User message has no content")
71
- raise ValueError("User message has no content")
72
-
73
- text_content = None
74
- for content_item in last_user_message.content:
75
- if content_item.type == "text" and content_item.text:
76
- text_content = content_item.text
77
- break
78
-
79
- if not text_content:
80
- logger.error("No text content found in user message")
81
- raise ValueError("No text content found in user message")
43
+ self._init_tracer(tracer_provider)
44
+ logger.info("AgnoAdapter initialized")
82
45
 
83
- logger.debug("Prepared input with text_content length=%d", len(text_content))
84
- return text_content
85
-
86
- async def ainvoke(
87
- self,
88
- input: List[AgentMessage],
89
- session_id: Union[str, None] = None,
90
- ) -> AgentInvocationResponse:
91
- """
92
- Asynchronous invocation method - invokes the Agno agent/team with tracing
93
-
94
- Args:
95
- input: List[AgentMessage] containing user_message
96
- session_id: Optional conversation ID for maintaining context
97
-
98
- Returns:
99
- AgentInvocationResponse - response containing agent trace, trajectory, and final response.
100
- """
101
- logger.info(
102
- "ainvoke called (session_id=%s, input_messages=%d)", session_id, len(input)
103
- )
104
- agent_input = self._prepare_input(input)
105
- session_id = session_id or "default"
46
+ async def ainvoke(self, input: InvokeInput) -> InvokeOutput:
47
+ """Invoke Agno agent and return response with trace."""
48
+ logger.info("ainvoke called (session_id=%s)", input.session_id)
49
+ session_id = input.session_id or str(uuid.uuid4())
106
50
 
107
51
  try:
108
- logger.debug("Invoking Agno agent with tracing (session_id=%s)", session_id)
109
- return await self._ainvoke_with_tracing(agent_input, session_id)
110
-
111
- except ValueError:
112
- logger.exception("Invalid input during ainvoke")
113
- raise
52
+ return await self._ainvoke_with_tracing(
53
+ input.user_message_str(), session_id
54
+ )
114
55
  except Exception as e:
115
- logger.exception("Unexpected error invoking Agno agent")
56
+ logger.exception("Error invoking Agno agent")
116
57
  raise RuntimeError(f"Error invoking Agno agent: {e}") from e
117
58
 
118
59
  async def _ainvoke_with_tracing(
119
60
  self,
120
- agent_input: str,
61
+ user_message: str,
121
62
  session_id: str,
122
- ) -> AgentInvocationResponse:
63
+ ) -> InvokeOutput:
123
64
  """Execute ainvoke with tracing enabled."""
124
65
  with self.tracer.start_as_current_span("agno_invocation") as span:
66
+ # Workaround: openinference-instrumentation-agno>=0.1.25 forces a new root
67
+ # trace for Team instances unless _AGNO_PARENT_NODE_CONTEXT_KEY is set.
68
+ # This ensures child spans inherit our trace_id.
69
+ # See: https://github.com/Arize-ai/openinference/pull/2533
70
+ #
71
+ # Context API notes:
72
+ # - set_value() creates a new Context with the key-value pair (doesn't activate it)
73
+ # - attach() makes the context active and returns a token (restore point)
74
+ # - detach(token) restores the previous context (cleanup)
75
+ ctx = context_api.set_value(
76
+ _AGNO_PARENT_NODE_CONTEXT_KEY,
77
+ format(span.get_span_context().span_id, '016x')
78
+ )
79
+ token = context_api.attach(ctx)
125
80
  trace_id = span.get_span_context().trace_id
81
+
126
82
  logger.debug(
127
83
  "Starting traced invocation (session_id=%s) with trace_id=%s",
128
84
  session_id,
129
85
  trace_id,
130
86
  )
131
- # Run the agent/team
132
- await self.agent.arun(agent_input, session_id=session_id)
87
+ try:
88
+ await self.agent.arun(user_message, session_id=session_id)
89
+ finally:
90
+ context_api.detach(token)
133
91
 
134
92
  # Get trace spans
135
93
  trace_readable_spans = self.quraite_span_exporter.get_spans_by_trace_id(
@@ -151,7 +109,7 @@ class AgnoAdapter(BaseAdapter):
151
109
  else:
152
110
  logger.warning("No spans found for trace_id=%s", trace_id)
153
111
 
154
- return AgentInvocationResponse(
112
+ return InvokeOutput(
155
113
  agent_trace=agent_trace,
156
114
  agent_trajectory=agent_trace.to_agent_trajectory(framework=Framework.AGNO),
157
115
  )
quraite/adapters/base.py CHANGED
@@ -1,49 +1,28 @@
1
1
  from abc import ABC, abstractmethod
2
- from typing import Any, List, Optional, Union
3
2
 
3
+ from opentelemetry.sdk.trace import TracerProvider as SDKTracerProvider
4
4
  from opentelemetry.trace import Tracer, TracerProvider
5
5
 
6
- from quraite.schema.message import AgentMessage, AssistantMessage, MessageContentText
7
- from quraite.schema.response import AgentInvocationResponse
6
+ from quraite.logger import get_logger
7
+ from quraite.schema.invoke import InvokeInput, InvokeOutput
8
+ from quraite.schema.message import AssistantMessage, MessageContentText
8
9
  from quraite.tracing.constants import QURAITE_TRACER_NAME
9
- from quraite.tracing.span_exporter import QuraiteInMemorySpanExporter
10
- from quraite.tracing.span_processor import QuraiteSimpleSpanProcessor
10
+ from quraite.tracing.span_exporter import QuraiteSpanExporter
11
+ from quraite.tracing.span_processor import QuraiteSpanProcessor
11
12
 
13
+ logger = get_logger(__name__)
12
14
 
13
- class BaseAdapter(ABC):
14
- """
15
- Abstract base class for all adapter providers.
16
-
17
- Subclasses must implement the asynchronous adapter method,
18
- which take List[Message] and return agent Message outputs.
19
-
20
- Methods:
21
- ainvoke: Asynchronously invoke an agent call for the provided input.
22
- """
23
15
 
24
- tracer_provider: Optional[TracerProvider] = None
25
- tracer: Optional[Tracer] = None
26
- quraite_span_exporter: Optional[QuraiteInMemorySpanExporter] = None
16
+ class BaseAdapter(ABC):
17
+ """Base adapter for all framework adapters."""
27
18
 
28
- def _init_tracing(
29
- self,
30
- tracer_provider: Optional[TracerProvider],
31
- required: bool = False,
32
- ) -> None:
33
- """
34
- Initialize tracing components from a TracerProvider.
19
+ tracer_provider: TracerProvider | None = None
20
+ tracer: Tracer | None = None
21
+ quraite_span_exporter: QuraiteSpanExporter = QuraiteSpanExporter()
35
22
 
36
- Args:
37
- tracer_provider: TracerProvider for tracing
38
- span_exporter: SpanExporter for exporting spans
39
- required: If True, raises ValueError when tracer_provider is None
40
- """
23
+ def _init_tracer(self, tracer_provider: SDKTracerProvider | None) -> None:
24
+ """Initialize tracer components from TracerProvider."""
41
25
  if tracer_provider is None:
42
- if required:
43
- raise ValueError(
44
- "tracer_provider is required. "
45
- "Please provide a TracerProvider instance."
46
- )
47
26
  return
48
27
 
49
28
  self.tracer_provider = tracer_provider
@@ -54,7 +33,7 @@ class BaseAdapter(ABC):
54
33
  (
55
34
  processor.span_exporter
56
35
  for processor in tracer_provider._active_span_processor._span_processors
57
- if isinstance(processor, QuraiteSimpleSpanProcessor)
36
+ if isinstance(processor, QuraiteSpanProcessor)
58
37
  ),
59
38
  None,
60
39
  )
@@ -62,7 +41,7 @@ class BaseAdapter(ABC):
62
41
  if quraite_span_exporter is None:
63
42
  raise ValueError(
64
43
  "Quraite span exporter not found. "
65
- "Please ensure QuraiteSimpleSpanProcessor is used in the tracer provider."
44
+ "Use setup_tracing() to configure tracing properly."
66
45
  )
67
46
 
68
47
  self.quraite_span_exporter = quraite_span_exporter
@@ -70,54 +49,25 @@ class BaseAdapter(ABC):
70
49
  @abstractmethod
71
50
  async def ainvoke(
72
51
  self,
73
- input: List[AgentMessage],
74
- session_id: Union[str, None],
75
- ) -> AgentInvocationResponse:
76
- """
77
- Asynchronously invoke the agent with the given input.
78
-
79
- Args:
80
- input (List[AgentMessage]): List of AgentMessage objects.
81
- session_id (str or None): ID for conversation thread/context.
82
-
83
- Returns:
84
- AgentInvocationResponse: Response containing agent trace, trajectory, and final response.
85
-
86
- Raises:
87
- NotImplementedError: If not implemented by subclass.
88
- """
52
+ input: InvokeInput,
53
+ ) -> InvokeOutput:
54
+ """Invoke agent with input and return response."""
89
55
  raise NotImplementedError("Not implemented")
90
56
 
91
57
 
92
58
  class DummyAdapter(BaseAdapter):
93
- """
94
- A dummy implementation of BaseAdapter, used mainly for testing and scaffolding.
95
- Always returns a fixed dummy response.
96
-
97
- Methods:
98
- ainvoke: Returns a static assistant message asynchronously.
99
- """
59
+ """Dummy adapter for testing."""
100
60
 
101
61
  async def ainvoke(
102
62
  self,
103
- input: Any,
104
- session_id: Union[str, None],
105
- ) -> AgentInvocationResponse:
106
- """
107
- Asynchronously returns a dummy assistant response.
108
-
109
- Args:
110
- input: Ignored.
111
- session_id: Ignored.
112
-
113
- Returns:
114
- AgentInvocationResponse: Response containing agent trace, trajectory, and final response.
115
- """
116
-
117
- return AgentInvocationResponse(
63
+ input: InvokeInput,
64
+ ) -> InvokeOutput:
65
+ """Returns dummy response."""
66
+ return InvokeOutput(
118
67
  agent_trajectory=[
68
+ input.user_message,
119
69
  AssistantMessage(
120
70
  content=[MessageContentText(text="Dummy response")],
121
- )
71
+ ),
122
72
  ]
123
73
  )
@@ -7,13 +7,14 @@ import asyncio
7
7
  import json
8
8
  import os
9
9
  import uuid
10
- from typing import Any, Dict, List, Optional, Union
10
+ from typing import Any
11
11
 
12
12
  import boto3
13
13
  from botocore.exceptions import ClientError
14
14
 
15
15
  from quraite.adapters.base import BaseAdapter
16
16
  from quraite.logger import get_logger
17
+ from quraite.schema.invoke import InvokeInput, InvokeOutput
17
18
  from quraite.schema.message import (
18
19
  AgentMessage,
19
20
  AssistantMessage,
@@ -21,7 +22,6 @@ from quraite.schema.message import (
21
22
  ToolCall,
22
23
  ToolMessage,
23
24
  )
24
- from quraite.schema.response import AgentInvocationResponse
25
25
 
26
26
  logger = get_logger(__name__)
27
27
 
@@ -38,12 +38,12 @@ class BedrockAgentsAdapter(BaseAdapter):
38
38
 
39
39
  def __init__(
40
40
  self,
41
- aws_access_key_id: Optional[str] = None,
42
- aws_secret_access_key: Optional[str] = None,
43
- aws_session_token: Optional[str] = None,
44
- agent_id: Optional[str] = None,
45
- agent_alias_id: Optional[str] = None,
46
- region_name: Optional[str] = None,
41
+ aws_access_key_id: str | None = None,
42
+ aws_secret_access_key: str | None = None,
43
+ aws_session_token: str | None = None,
44
+ agent_id: str | None = None,
45
+ agent_alias_id: str | None = None,
46
+ region_name: str | None = None,
47
47
  agent_name: str = "Bedrock Agent",
48
48
  ):
49
49
  """
@@ -92,8 +92,8 @@ class BedrockAgentsAdapter(BaseAdapter):
92
92
 
93
93
  def _convert_bedrock_traces_to_messages(
94
94
  self,
95
- traces: List[Dict[str, Any]],
96
- ) -> List[AgentMessage]:
95
+ traces: list[dict[str, Any]],
96
+ ) -> list[AgentMessage]:
97
97
  logger.debug("Converting %d Bedrock trace events to messages", len(traces))
98
98
  if not traces:
99
99
  return []
@@ -121,7 +121,7 @@ class BedrockAgentsAdapter(BaseAdapter):
121
121
  try:
122
122
  parsed_content = json.loads(raw_response_content)
123
123
  contents = parsed_content.get("content", [])
124
- except (json.JSONDecodeError, KeyError, ValueError) as e:
124
+ except (json.JSONDecodeError, KeyError, ValueError):
125
125
  logger.exception("Error parsing Bedrock raw response content")
126
126
 
127
127
  if not contents:
@@ -223,27 +223,7 @@ class BedrockAgentsAdapter(BaseAdapter):
223
223
  logger.info("Converted Bedrock traces into %d messages", len(messages))
224
224
  return messages
225
225
 
226
- def _prepare_input(self, input_data: List[AgentMessage]) -> str:
227
- """Extract user message from List[AgentMessage]."""
228
- logger.debug("Preparing Bedrock input from %d messages", len(input_data))
229
- last_user_message = input_data[-1]
230
- if last_user_message.role != "user":
231
- logger.error("Last message is not from user")
232
- return ""
233
- # Check if content list is not empty and has text
234
- if not last_user_message.content:
235
- logger.error("User message has no content")
236
- raise ValueError("User message has no content")
237
- # Find the first text content item
238
- for content_item in last_user_message.content:
239
- if content_item.type == "text" and content_item.text:
240
- logger.debug(
241
- "Prepared Bedrock input (text_length=%d)", len(content_item.text)
242
- )
243
- return content_item.text
244
- raise ValueError("No text content found in user message")
245
-
246
- def _run_agent(self, session_id: str, prompt: str) -> List[Dict]:
226
+ def _run_agent(self, session_id: str, prompt: str) -> tuple[str, list[dict]]:
247
227
  """
248
228
  Run the Bedrock agent and collect response and traces.
249
229
 
@@ -283,7 +263,7 @@ class BedrockAgentsAdapter(BaseAdapter):
283
263
 
284
264
  except ClientError:
285
265
  logger.exception("Error invoking Bedrock agent via Bedrock runtime")
286
- return "", []
266
+ raise
287
267
  logger.info(
288
268
  "Bedrock agent invocation succeeded (session_id=%s, trace_events=%d)",
289
269
  session_id,
@@ -291,53 +271,20 @@ class BedrockAgentsAdapter(BaseAdapter):
291
271
  )
292
272
  return agent_answer, traces
293
273
 
294
- async def ainvoke(
295
- self,
296
- input: List[AgentMessage],
297
- session_id: Union[str, None],
298
- ) -> AgentInvocationResponse:
299
- """Asynchronous invocation method - invokes the Bedrock agent and converts to List[AgentMessage].
300
-
301
- Args:
302
- input: List of AgentMessage objects
303
- session_id: Unique session identifier
304
-
305
- Returns:
306
- AgentInvocationResponse - response containing agent trace, trajectory, and final response.
307
- """
308
- logger.info(
309
- "Bedrock ainvoke called (session_id=%s, input_messages=%d)",
310
- session_id,
311
- len(input),
312
- )
313
- agent_input = self._prepare_input(input)
314
- session_id = session_id or str(uuid.uuid4())
274
+ async def ainvoke(self, input: InvokeInput) -> InvokeOutput:
275
+ """Invoke Bedrock agent and return response."""
276
+ logger.info("Bedrock ainvoke called (session_id=%s)", input.session_id)
277
+ session_id = input.session_id or str(uuid.uuid4())
315
278
 
316
279
  try:
317
- # Run the synchronous _run_agent in a thread pool to avoid blocking
318
280
  _, traces = await asyncio.to_thread(
319
- self._run_agent, session_id, agent_input
320
- )
321
- logger.debug(
322
- "Bedrock agent run returned %d trace events for session_id=%s",
323
- len(traces),
324
- session_id,
281
+ self._run_agent, session_id, input.user_message_str()
325
282
  )
326
- except (ClientError, ValueError, KeyError, json.JSONDecodeError):
327
- logger.exception("Error invoking Bedrock agent")
328
- return AgentInvocationResponse()
329
-
330
- try:
331
283
  agent_trajectory = self._convert_bedrock_traces_to_messages(traces)
332
284
  logger.info(
333
- "Bedrock agent produced %d trajectory messages",
334
- len(agent_trajectory),
335
- )
336
-
337
- return AgentInvocationResponse(
338
- agent_trajectory=agent_trajectory,
285
+ "Bedrock agent produced %d trajectory messages", len(agent_trajectory)
339
286
  )
340
-
341
- except (ClientError, ValueError, KeyError, json.JSONDecodeError):
342
- logger.exception("Error converting Bedrock traces to messages")
343
- return AgentInvocationResponse()
287
+ return InvokeOutput(agent_trajectory=agent_trajectory)
288
+ except Exception:
289
+ logger.exception("Error invoking Bedrock agent")
290
+ return InvokeOutput()