agentx-python 0.6.37__tar.gz → 0.6.39__tar.gz

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 (81) hide show
  1. {agentx_python-0.6.37 → agentx_python-0.6.39}/PKG-INFO +1 -1
  2. agentx_python-0.6.39/agentx/version.py +1 -0
  3. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx_python.egg-info/PKG-INFO +1 -1
  4. {agentx_python-0.6.37 → agentx_python-0.6.39}/tests/test_integrations.py +60 -27
  5. {agentx_python-0.6.37 → agentx_python-0.6.39}/tests/test_span_tree.py +11 -1
  6. agentx_python-0.6.37/agentx/version.py +0 -1
  7. {agentx_python-0.6.37 → agentx_python-0.6.39}/LICENSE +0 -0
  8. {agentx_python-0.6.37 → agentx_python-0.6.39}/README.md +0 -0
  9. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/__init__.py +0 -0
  10. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/agentx.py +0 -0
  11. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/cli.py +0 -0
  12. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/evaluations/__init__.py +0 -0
  13. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/evaluations/_term.py +0 -0
  14. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/evaluations/adapters/__init__.py +0 -0
  15. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/evaluations/adapters/http_endpoint.py +0 -0
  16. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/evaluations/adapters/precomputed.py +0 -0
  17. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/evaluations/adapters/raw.py +0 -0
  18. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/evaluations/client.py +0 -0
  19. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/evaluations/datasets.py +0 -0
  20. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/evaluations/evaluation_settings.py +0 -0
  21. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/evaluations/models.py +0 -0
  22. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/evaluations/prompts.py +0 -0
  23. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/evaluations/reporting.py +0 -0
  24. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/evaluations/results.py +0 -0
  25. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/evaluations/runner.py +0 -0
  26. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/evaluations/tool_schemas.py +0 -0
  27. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/evaluations/tracing.py +0 -0
  28. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/exceptions.py +0 -0
  29. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/export.py +0 -0
  30. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/feedback.py +0 -0
  31. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/integrations/__init__.py +0 -0
  32. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/integrations/_traced_call.py +0 -0
  33. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/integrations/anthropic.py +0 -0
  34. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/integrations/autogen.py +0 -0
  35. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/integrations/crewai.py +0 -0
  36. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/integrations/databricks.py +0 -0
  37. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/integrations/google_adk.py +0 -0
  38. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/integrations/google_genai.py +0 -0
  39. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/integrations/langchain.py +0 -0
  40. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/integrations/litellm.py +0 -0
  41. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/integrations/llamaindex.py +0 -0
  42. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/integrations/moveworks.py +0 -0
  43. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/integrations/openai.py +0 -0
  44. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/integrations/openai_agents.py +0 -0
  45. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/monitor/__init__.py +0 -0
  46. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/monitor/agents.py +0 -0
  47. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/monitor/client.py +0 -0
  48. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/monitor/judge_scorers.py +0 -0
  49. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/monitor/models.py +0 -0
  50. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/monitor/online_evaluators.py +0 -0
  51. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/monitor/patterns.py +0 -0
  52. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/monitor/profile.py +0 -0
  53. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/monitor/scorers.py +0 -0
  54. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/monitor/sessions.py +0 -0
  55. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/monitor/signals.py +0 -0
  56. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/outcomes.py +0 -0
  57. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/projects.py +0 -0
  58. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/py.typed +0 -0
  59. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/resources/__init__.py +0 -0
  60. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/resources/agent.py +0 -0
  61. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/resources/conversation.py +0 -0
  62. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/resources/workforce.py +0 -0
  63. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/traces.py +0 -0
  64. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/tracing/__init__.py +0 -0
  65. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/tracing/ci_types.py +0 -0
  66. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/tracing/ingest_client.py +0 -0
  67. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/tracing/tracer.py +0 -0
  68. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx/util.py +0 -0
  69. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx_python.egg-info/SOURCES.txt +0 -0
  70. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx_python.egg-info/dependency_links.txt +0 -0
  71. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx_python.egg-info/entry_points.txt +0 -0
  72. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx_python.egg-info/not-zip-safe +0 -0
  73. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx_python.egg-info/requires.txt +0 -0
  74. {agentx_python-0.6.37 → agentx_python-0.6.39}/agentx_python.egg-info/top_level.txt +0 -0
  75. {agentx_python-0.6.37 → agentx_python-0.6.39}/setup.cfg +0 -0
  76. {agentx_python-0.6.37 → agentx_python-0.6.39}/setup.py +0 -0
  77. {agentx_python-0.6.37 → agentx_python-0.6.39}/tests/test_deep_dive_fixes.py +0 -0
  78. {agentx_python-0.6.37 → agentx_python-0.6.39}/tests/test_docs_match_sdk.py +0 -0
  79. {agentx_python-0.6.37 → agentx_python-0.6.39}/tests/test_integration.py +0 -0
  80. {agentx_python-0.6.37 → agentx_python-0.6.39}/tests/test_judge_scorers.py +0 -0
  81. {agentx_python-0.6.37 → agentx_python-0.6.39}/tests/test_selfhost_analysis_fallback.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentx-python
3
- Version: 0.6.37
3
+ Version: 0.6.39
4
4
  Summary: Official Python SDK for AgentX (https://www.agentx.so/)
5
5
  Home-page: https://github.com/AgentX-ai/AgentX-python
6
6
  Author: Robin Wang and AgentX Team
@@ -0,0 +1 @@
1
+ VERSION = "0.6.39"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: agentx-python
3
- Version: 0.6.37
3
+ Version: 0.6.39
4
4
  Summary: Official Python SDK for AgentX (https://www.agentx.so/)
5
5
  Home-page: https://github.com/AgentX-ai/AgentX-python
6
6
  Author: Robin Wang and AgentX Team
@@ -46,6 +46,9 @@ def make_tracer() -> Tracer:
46
46
  # ---------------------------------------------------------------------------
47
47
 
48
48
  def test_adk_model_error_is_captured():
49
+ # google-adk is an optional extra; skip like the crewai/litellm/llamaindex/autogen tests
50
+ # below rather than failing on ImportError (importing the module raises when it is absent).
51
+ pytest.importorskip("google.adk")
49
52
  from agentx.integrations.google_adk import AgentXADKPlugin
50
53
 
51
54
  tracer = make_tracer()
@@ -637,22 +640,32 @@ def test_crewai_captures_real_per_task_timing_via_event_bus():
637
640
 
638
641
  return FakeCrewOutput(raw="final output", tasks_output=[output1, output2])
639
642
 
640
- tracer = make_tracer()
643
+ # Boundary-mocked rather than make_tracer(): each task is a real child span now (9d45dd1
644
+ # replaced the synthetic performance_summary step list), and mocking tracer._send would
645
+ # bypass the very _send/_dispatch/child_span chain that builds them. Same idiom as
646
+ # tests/test_span_tree.py.
647
+ tracer = Tracer(ingest_client=MagicMock())
641
648
  observer = AgentXCrewObserver(tracer, name="my-crew")
642
649
 
643
650
  result = observer.kickoff(FakeCrew(), inputs={"topic": "AI"})
644
651
 
645
652
  assert result.raw == "final output"
646
- tracer._send.assert_called_once()
647
- _, kwargs = tracer._send.call_args
648
- steps = kwargs["performance_summary"]["execution_steps"]
649
- assert len(steps) == 2
650
- assert steps[0]["name"] == "Research topic"
651
- assert steps[1]["name"] == "Write summary"
652
- # Real timing, not an even split task 1 slept ~3x longer than task 2.
653
- assert steps[0]["duration_ms"] > steps[1]["duration_ms"] * 1.5
654
- assert steps[0]["output"] == "research done"
655
- assert steps[1]["output"] == "summary done"
653
+ wires = [call.args[0] for call in tracer._client.enqueue.call_args_list]
654
+ assert len(wires) == 3
655
+ research, summary, root = wires
656
+ assert root["name"] == "my-crew"
657
+ assert root["output"] == "final output"
658
+
659
+ # Each task is its own child span under the crew's root, carrying its own real duration.
660
+ assert research["name"] == "Research topic"
661
+ assert summary["name"] == "Write summary"
662
+ assert research["parent_span_id"] == root["span_id"]
663
+ assert summary["parent_span_id"] == root["span_id"]
664
+ assert research["output"] == "research done"
665
+ assert summary["output"] == "summary done"
666
+ # The point of the test: real timing, not an even split — task 1 slept ~3x longer than
667
+ # task 2, and the old "divide latency evenly" approximation reported them identical.
668
+ assert research["latency_ms"] > summary["latency_ms"] * 1.5
656
669
 
657
670
 
658
671
  def test_crewai_falls_back_to_even_split_without_event_bus():
@@ -927,6 +940,10 @@ def test_llamaindex_llm_error_is_captured():
927
940
  def test_autogen_agent_run_traces_text_reply():
928
941
  """Drives a real AssistantAgent.run() via AutoGen's own ReplayChatCompletionClient (no network/API keys)."""
929
942
  pytest.importorskip("autogen_agentchat")
943
+ # autogen-ext is a separate distribution and is NOT part of the "autogen" extra -
944
+ # ReplayChatCompletionClient below is a test double that lives there, so guard it too
945
+ # or this fails with ModuleNotFoundError instead of skipping.
946
+ pytest.importorskip("autogen_ext")
930
947
  from autogen_agentchat.agents import AssistantAgent
931
948
  from autogen_ext.models.replay import ReplayChatCompletionClient
932
949
 
@@ -935,25 +952,33 @@ def test_autogen_agent_run_traces_text_reply():
935
952
  model_client = ReplayChatCompletionClient(["Hello from AutoGen!"])
936
953
  agent = AssistantAgent("assistant", model_client=model_client)
937
954
 
938
- tracer = make_tracer()
955
+ # Boundary-mocked, not make_tracer(): the agent's turn is a real child span since
956
+ # 9d45dd1, and mocking tracer._send would bypass the chain that builds it.
957
+ tracer = Tracer(ingest_client=MagicMock())
939
958
  observer = AgentXAutoGenObserver(tracer, name="my-agent")
940
959
 
941
960
  result = asyncio.run(observer.run(agent, task="Say hello"))
942
961
 
943
962
  assert result.messages[-1].content == "Hello from AutoGen!"
944
- tracer._send.assert_called_once()
945
- _, kwargs = tracer._send.call_args
946
- assert kwargs["input"] == "Say hello"
947
- assert kwargs["output"] == "Hello from AutoGen!"
948
- assert kwargs["input_tokens"] == 22
949
- assert kwargs["output_tokens"] == 3
950
- steps = kwargs["performance_summary"]["execution_steps"]
951
- assert len(steps) == 1
952
- assert steps[0]["output"] == "Hello from AutoGen!"
963
+ wires = [call.args[0] for call in tracer._client.enqueue.call_args_list]
964
+ assert len(wires) == 2
965
+ step, root = wires
966
+ assert root["input"] == "Say hello"
967
+ assert root["output"] == "Hello from AutoGen!"
968
+ assert root["input_tokens"] == 22
969
+ assert root["output_tokens"] == 3
970
+ # The turn itself, as its own child span rather than a performance_summary step.
971
+ assert step["name"] == "assistant"
972
+ assert step["output"] == "Hello from AutoGen!"
973
+ assert step["parent_span_id"] == root["span_id"]
953
974
 
954
975
 
955
976
  def test_autogen_agent_run_traces_tool_call():
956
977
  pytest.importorskip("autogen_agentchat")
978
+ # autogen-ext is a separate distribution and is NOT part of the "autogen" extra -
979
+ # ReplayChatCompletionClient below is a test double that lives there, so guard it too
980
+ # or this fails with ModuleNotFoundError instead of skipping.
981
+ pytest.importorskip("autogen_ext")
957
982
  import json
958
983
 
959
984
  from autogen_agentchat.agents import AssistantAgent
@@ -983,16 +1008,24 @@ def test_autogen_agent_run_traces_tool_call():
983
1008
  )
984
1009
  agent = AssistantAgent("assistant", model_client=model_client, tools=[tool])
985
1010
 
986
- tracer = make_tracer()
1011
+ tracer = Tracer(ingest_client=MagicMock())
987
1012
  observer = AgentXAutoGenObserver(tracer, name="my-agent")
988
1013
 
989
1014
  asyncio.run(observer.run(agent, task="What is the weather in NYC?"))
990
1015
 
991
- tracer._send.assert_called_once()
992
- _, kwargs = tracer._send.call_args
993
- perf = kwargs["performance_summary"]
994
- assert len(perf["tool_calls"]) == 1
995
- tool_call = perf["tool_calls"][0]
1016
+ wires = [call.args[0] for call in tracer._client.enqueue.call_args_list]
1017
+ assert len(wires) == 2
1018
+ child, root = wires
1019
+ # The tool call is a real child span...
1020
+ assert child["name"] == "get_weather"
1021
+ assert "NYC" in child["input"]
1022
+ assert child["output"] == "sunny in NYC"
1023
+ assert child["parent_span_id"] == root["span_id"]
1024
+ # ...and is mirrored onto the ROOT's flat tool_calls, which is what the engine's built-in
1025
+ # "Tool failure" check and the dashboard's Tool quality column read. Same deliberate
1026
+ # dual-write as trace_tool_call() - see test_span_tree.py.
1027
+ assert len(root["tool_calls"]) == 1
1028
+ tool_call = root["tool_calls"][0]
996
1029
  assert tool_call["name"] == "get_weather"
997
1030
  assert "NYC" in tool_call["input"]
998
1031
  assert tool_call["output"] == "sunny in NYC"
@@ -486,6 +486,9 @@ def test_google_adk_emits_real_child_spans():
486
486
  import asyncio
487
487
  import types
488
488
 
489
+ # google-adk is an optional extra; skip like every other integration test here rather
490
+ # than failing on ImportError (importing the module raises when it is absent).
491
+ pytest.importorskip("google.adk")
489
492
  from agentx.integrations.google_adk import AgentXADKPlugin
490
493
 
491
494
  tracer = make_tracer()
@@ -529,6 +532,7 @@ def test_google_adk_model_error_is_captured():
529
532
  import asyncio
530
533
  import types
531
534
 
535
+ pytest.importorskip("google.adk")
532
536
  from agentx.integrations.google_adk import AgentXADKPlugin
533
537
 
534
538
  tracer = make_tracer()
@@ -581,7 +585,13 @@ def test_trace_tool_call_emits_real_child_span():
581
585
  assert child["name"] == "policy_lookup"
582
586
  assert child["parent_span_id"] == root["span_id"]
583
587
  assert child["output"] == "digital purchases are final"
584
- assert "tool_calls" not in root or root.get("tool_calls") in (None, [])
588
+ # ...and a summary of it also lands on the ROOT's flat tool_calls list. That dual-write is
589
+ # deliberate (40c6f6e): the child span feeds the trace detail's span tree, while the
590
+ # engine's built-in "Tool failure" check and the dashboard's Tool quality column read the
591
+ # root's flat list - before it, a failed trace_tool_call() was invisible to both surfaces.
592
+ # Asserted positively, and as exactly one entry, so a third write shows up here too.
593
+ assert [tc["name"] for tc in root["tool_calls"]] == ["policy_lookup"]
594
+ assert root["tool_calls"][0]["output"] == "digital purchases are final"
585
595
 
586
596
 
587
597
  def test_trace_retrieval_emits_real_child_span():
@@ -1 +0,0 @@
1
- VERSION = "0.6.37"
File without changes
File without changes
File without changes
File without changes