aixtools 0.1.10__py3-none-any.whl → 0.2.0__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.

Potentially problematic release.


This version of aixtools might be problematic. Click here for more details.

Files changed (62) hide show
  1. aixtools/_version.py +2 -2
  2. aixtools/agents/agent.py +26 -7
  3. aixtools/agents/print_nodes.py +54 -0
  4. aixtools/agents/prompt.py +2 -2
  5. aixtools/compliance/private_data.py +1 -1
  6. aixtools/evals/discovery.py +174 -0
  7. aixtools/evals/evals.py +74 -0
  8. aixtools/evals/run_evals.py +110 -0
  9. aixtools/logging/log_objects.py +24 -23
  10. aixtools/mcp/client.py +148 -2
  11. aixtools/server/__init__.py +0 -6
  12. aixtools/server/path.py +88 -31
  13. aixtools/testing/aix_test_model.py +9 -1
  14. aixtools/tools/doctor/mcp_tool_doctor.py +79 -0
  15. aixtools/tools/doctor/tool_doctor.py +4 -0
  16. aixtools/tools/doctor/tool_recommendation.py +5 -0
  17. aixtools/utils/config.py +0 -1
  18. {aixtools-0.1.10.dist-info → aixtools-0.2.0.dist-info}/METADATA +186 -30
  19. {aixtools-0.1.10.dist-info → aixtools-0.2.0.dist-info}/RECORD +23 -55
  20. aixtools-0.2.0.dist-info/entry_points.txt +4 -0
  21. aixtools-0.2.0.dist-info/top_level.txt +1 -0
  22. aixtools/server/workspace_privacy.py +0 -65
  23. aixtools-0.1.10.dist-info/entry_points.txt +0 -2
  24. aixtools-0.1.10.dist-info/top_level.txt +0 -5
  25. docker/mcp-base/Dockerfile +0 -33
  26. docker/mcp-base/zscaler.crt +0 -28
  27. notebooks/example_faulty_mcp_server.ipynb +0 -74
  28. notebooks/example_mcp_server_stdio.ipynb +0 -76
  29. notebooks/example_raw_mcp_client.ipynb +0 -84
  30. notebooks/example_tool_doctor.ipynb +0 -65
  31. scripts/config.sh +0 -28
  32. scripts/lint.sh +0 -32
  33. scripts/log_view.sh +0 -18
  34. scripts/run_example_mcp_server.sh +0 -14
  35. scripts/run_faulty_mcp_server.sh +0 -13
  36. scripts/run_server.sh +0 -29
  37. scripts/test.sh +0 -30
  38. tests/unit/__init__.py +0 -0
  39. tests/unit/a2a/__init__.py +0 -0
  40. tests/unit/a2a/google_sdk/__init__.py +0 -0
  41. tests/unit/a2a/google_sdk/pydantic_ai_adapter/__init__.py +0 -0
  42. tests/unit/a2a/google_sdk/pydantic_ai_adapter/test_agent_executor.py +0 -188
  43. tests/unit/a2a/google_sdk/pydantic_ai_adapter/test_storage.py +0 -156
  44. tests/unit/a2a/google_sdk/test_card.py +0 -114
  45. tests/unit/a2a/google_sdk/test_remote_agent_connection.py +0 -413
  46. tests/unit/a2a/google_sdk/test_utils.py +0 -208
  47. tests/unit/agents/__init__.py +0 -0
  48. tests/unit/agents/test_prompt.py +0 -363
  49. tests/unit/compliance/test_private_data.py +0 -329
  50. tests/unit/google/__init__.py +0 -1
  51. tests/unit/google/test_client.py +0 -233
  52. tests/unit/mcp/__init__.py +0 -0
  53. tests/unit/mcp/test_client.py +0 -242
  54. tests/unit/server/__init__.py +0 -0
  55. tests/unit/server/test_path.py +0 -225
  56. tests/unit/server/test_utils.py +0 -362
  57. tests/unit/utils/__init__.py +0 -0
  58. tests/unit/utils/test_files.py +0 -146
  59. tests/unit/vault/__init__.py +0 -0
  60. tests/unit/vault/test_vault.py +0 -246
  61. {tests → aixtools/evals}/__init__.py +0 -0
  62. {aixtools-0.1.10.dist-info → aixtools-0.2.0.dist-info}/WHEEL +0 -0
@@ -1,76 +0,0 @@
1
- {
2
- "cells": [
3
- {
4
- "cell_type": "markdown",
5
- "id": "57d36f62",
6
- "metadata": {},
7
- "source": [
8
- "# Example MCP Server STDIO"
9
- ]
10
- },
11
- {
12
- "cell_type": "code",
13
- "execution_count": null,
14
- "id": "ebf6d915",
15
- "metadata": {},
16
- "outputs": [],
17
- "source": [
18
- "from aixtools.agents.agent import get_agent, run_agent\n",
19
- "from aixtools.utils.config import PROJECT_DIR\n",
20
- "from pydantic_ai.mcp import MCPServerStdio"
21
- ]
22
- },
23
- {
24
- "cell_type": "code",
25
- "execution_count": null,
26
- "id": "97d1e607",
27
- "metadata": {},
28
- "outputs": [],
29
- "source": [
30
- "mcp_path = PROJECT_DIR /'aixtools' / 'mcp' / 'example_server.py'\n",
31
- "server = MCPServerStdio(command='fastmcp', args=['run', str(mcp_path)])\n",
32
- "agent = get_agent(mcp_servers=[server])"
33
- ]
34
- },
35
- {
36
- "cell_type": "code",
37
- "execution_count": null,
38
- "id": "fc560d25",
39
- "metadata": {},
40
- "outputs": [],
41
- "source": [
42
- "async with agent:\n",
43
- " ret = await run_agent(agent, \"What is the add of 40123456789 and 2123456789?\", verbose=True, debug=True)"
44
- ]
45
- },
46
- {
47
- "cell_type": "code",
48
- "execution_count": null,
49
- "id": "cad32e85",
50
- "metadata": {},
51
- "outputs": [],
52
- "source": []
53
- }
54
- ],
55
- "metadata": {
56
- "kernelspec": {
57
- "display_name": ".venv",
58
- "language": "python",
59
- "name": "python3"
60
- },
61
- "language_info": {
62
- "codemirror_mode": {
63
- "name": "ipython",
64
- "version": 3
65
- },
66
- "file_extension": ".py",
67
- "mimetype": "text/x-python",
68
- "name": "python",
69
- "nbconvert_exporter": "python",
70
- "pygments_lexer": "ipython3",
71
- "version": "3.12.2"
72
- }
73
- },
74
- "nbformat": 4,
75
- "nbformat_minor": 5
76
- }
@@ -1,84 +0,0 @@
1
- {
2
- "cells": [
3
- {
4
- "cell_type": "markdown",
5
- "id": "57d36f62",
6
- "metadata": {},
7
- "source": [
8
- "# Example \"Raw MCP Client\"\n",
9
- "\n",
10
- "Run the server using the script:\n",
11
- "\n",
12
- "```bash\n",
13
- "./scripts/run_faulty_mcp_server.sh\n",
14
- "``` "
15
- ]
16
- },
17
- {
18
- "cell_type": "code",
19
- "execution_count": null,
20
- "id": "cad32e85",
21
- "metadata": {},
22
- "outputs": [],
23
- "source": [
24
- "from fastmcp import Client\n",
25
- "import rich\n",
26
- "\n",
27
- "client = Client(\"http://localhost:9999/mcp/\")"
28
- ]
29
- },
30
- {
31
- "cell_type": "code",
32
- "execution_count": null,
33
- "id": "e372fc6a",
34
- "metadata": {},
35
- "outputs": [],
36
- "source": [
37
- "async with client:\n",
38
- " # Basic server interaction\n",
39
- " await client.ping()\n",
40
- " \n",
41
- " # # List available operations\n",
42
- " # tools = await client.list_tools()\n",
43
- " # rich.print(tools)\n",
44
- " # \n",
45
- " # # Execute 'add' tool\n",
46
- " # result = await client.call_tool(\"add\", {\"a\": 7, \"b\": 3})\n",
47
- " # rich.print(result)\n",
48
- "\n",
49
- " # Execute 'add' tool\n",
50
- " result = await client.call_tool(\"throw_404_exception\", {})\n",
51
- " rich.print(result)\n"
52
- ]
53
- },
54
- {
55
- "cell_type": "code",
56
- "execution_count": null,
57
- "id": "a8a743e2",
58
- "metadata": {},
59
- "outputs": [],
60
- "source": []
61
- }
62
- ],
63
- "metadata": {
64
- "kernelspec": {
65
- "display_name": ".venv",
66
- "language": "python",
67
- "name": "python3"
68
- },
69
- "language_info": {
70
- "codemirror_mode": {
71
- "name": "ipython",
72
- "version": 3
73
- },
74
- "file_extension": ".py",
75
- "mimetype": "text/x-python",
76
- "name": "python",
77
- "nbconvert_exporter": "python",
78
- "pygments_lexer": "ipython3",
79
- "version": "3.12.2"
80
- }
81
- },
82
- "nbformat": 4,
83
- "nbformat_minor": 5
84
- }
@@ -1,65 +0,0 @@
1
- {
2
- "cells": [
3
- {
4
- "cell_type": "markdown",
5
- "id": "dab47237",
6
- "metadata": {},
7
- "source": [
8
- "# Tool doctor example"
9
- ]
10
- },
11
- {
12
- "cell_type": "code",
13
- "execution_count": null,
14
- "id": "9735e38c",
15
- "metadata": {},
16
- "outputs": [],
17
- "source": [
18
- "# Example 1: A reasonably well-defined tool\n",
19
- "from aixtools.tools.doctor import tool_doctor\n",
20
- "\n",
21
- "\n",
22
- "def add(a: int, b: int) -> int:\n",
23
- " \"\"\" Add two numbers \"\"\"\n",
24
- " return a + b\n",
25
- "\n",
26
- "# Example 2: A poorly defined tool\n",
27
- "def z(a: int, b: int) -> int:\n",
28
- " \"\"\" performs some arithmentic with two parameters \"\"\"\n",
29
- " return a + b\n"
30
- ]
31
- },
32
- {
33
- "cell_type": "code",
34
- "execution_count": null,
35
- "id": "e50d48d6",
36
- "metadata": {},
37
- "outputs": [],
38
- "source": [
39
- "# Call tool doctor\n",
40
- "ret = await tool_doctor([add, z])"
41
- ]
42
- }
43
- ],
44
- "metadata": {
45
- "kernelspec": {
46
- "display_name": ".venv",
47
- "language": "python",
48
- "name": "python3"
49
- },
50
- "language_info": {
51
- "codemirror_mode": {
52
- "name": "ipython",
53
- "version": 3
54
- },
55
- "file_extension": ".py",
56
- "mimetype": "text/x-python",
57
- "name": "python",
58
- "nbconvert_exporter": "python",
59
- "pygments_lexer": "ipython3",
60
- "version": "3.12.2"
61
- }
62
- },
63
- "nbformat": 4,
64
- "nbformat_minor": 5
65
- }
scripts/config.sh DELETED
@@ -1,28 +0,0 @@
1
- #-----------------------------------------------------------------------------
2
- #
3
- # This template script sets up the environment for the project by defining the
4
- # project directory and activating the virtual environment.
5
- #
6
- #-----------------------------------------------------------------------------
7
-
8
- export SCRIPTS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
9
-
10
- # Project directory
11
- export PROJECT_DIR="$( cd $SCRIPTS_DIR/.. && pwd -P )"
12
- export PROJECT_NAME="$(basename $PROJECT_DIR)"
13
-
14
- # Data directories
15
- export DATA_DIR="$PROJECT_DIR/data"
16
- export LOGS_DIR="$PROJECT_DIR/logs"
17
- export PG_DATA_DIR="$DATA_DIR/data/db/postgres"
18
-
19
- # Server configuration
20
- export PORT=8081
21
-
22
- # Activate virtual environment
23
- if [ "${OS-}" == "Windows_NT" ]; then
24
- source .venv/Scripts/activate
25
- else
26
- source .venv/bin/activate
27
- fi
28
-
scripts/lint.sh DELETED
@@ -1,32 +0,0 @@
1
- #!/bin/bash -eu
2
- set -o pipefail
3
-
4
- #-----------------------------------------------------------------------------
5
- #
6
- # Template script for running the linter
7
- #
8
- #-----------------------------------------------------------------------------
9
-
10
-
11
- # Get script directory
12
- SCRIPTS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
13
- source "$SCRIPTS_DIR/config.sh"
14
-
15
- # Check if the fix parameter is provided
16
- FIX_MODE=false
17
- if [[ $# -gt 0 && "$1" == "--fix" ]]; then
18
- FIX_MODE=true
19
- fi
20
-
21
- # Run linter
22
- if [ "$FIX_MODE" = true ]; then
23
- echo "Running linters in fix mode..."
24
- ruff format .
25
- ruff check --fix .
26
- else
27
- echo "Running linters in check mode..."
28
- ruff format --check .
29
- ruff check .
30
- fi
31
- echo "Running pylint..."
32
- pylint aixtools/
scripts/log_view.sh DELETED
@@ -1,18 +0,0 @@
1
- #!/bin/bash -eu
2
- set -o pipefail
3
-
4
- #-----------------------------------------------------------------------------
5
- #
6
- # Template script for running the Chainlit server
7
- #
8
- #-----------------------------------------------------------------------------
9
-
10
- # Get script directory
11
- SCRIPTS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
12
- source "$SCRIPTS_DIR/config.sh"
13
-
14
- # Activate virtual environment (with special handling for Windows)
15
- cd "$PROJECT_DIR"
16
-
17
- # Run the server
18
- streamlit run aixtools/log_view/app.py $*
@@ -1,14 +0,0 @@
1
- #!/bin/bash -eu
2
- set -o pipefail
3
-
4
- # Get script directory
5
- SCRIPTS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
6
- source "$SCRIPTS_DIR/config.sh"
7
-
8
- # Activate virtual environment (with special handling for Windows)
9
- cd "$PROJECT_DIR"
10
-
11
- # Run the example MCP server
12
- fastmcp run \
13
- --transport http \
14
- "$PROJECT_DIR/aixtools/mcp/example_server.py"
@@ -1,13 +0,0 @@
1
- #!/bin/bash -eu
2
- set -o pipefail
3
-
4
- # Get script directory
5
- SCRIPTS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
6
- source "$SCRIPTS_DIR/config.sh"
7
-
8
- cd "$PROJECT_DIR"
9
-
10
- while true; do
11
- uv run aixtools/mcp/faulty_mcp.py "$@" || true
12
- echo "MCP server terminated. Restarting..."
13
- done
scripts/run_server.sh DELETED
@@ -1,29 +0,0 @@
1
- #!/bin/bash -eu
2
- set -o pipefail
3
-
4
- #-----------------------------------------------------------------------------
5
- #
6
- # Template script for running the Chainlit server
7
- #
8
- #-----------------------------------------------------------------------------
9
-
10
- # Get script directory
11
- SCRIPTS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
12
- source "$SCRIPTS_DIR/config.sh"
13
-
14
- # Activate virtual environment (with special handling for Windows)
15
- cd "$PROJECT_DIR"
16
-
17
- # Run linter before starting the server
18
- "$SCRIPTS_DIR/lint.sh"
19
-
20
- # Go into the sub-dir (most projects don't need this)
21
- cd "$PROJECT_NAME"
22
-
23
- # Run the server
24
- chainlit run \
25
- --host 0.0.0.0 \
26
- --port $PORT \
27
- --root-path /$PROJECT_NAME \
28
- --watch \
29
- app.py
scripts/test.sh DELETED
@@ -1,30 +0,0 @@
1
- #!/bin/bash -eu
2
- set -o pipefail
3
-
4
- # Get the directory of this script
5
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6
- source "${SCRIPT_DIR}/config.sh"
7
-
8
- # Install required dependencies
9
- echo "Installing test dependencies..."
10
- uv pip install pytest pytest-asyncio pytest-mock pytest-cov
11
-
12
- # Ensure .env exists
13
- touch .env
14
-
15
- # Add the project root to PYTHONPATH so imports work correctly
16
- export PYTHONPATH="${PROJECT_DIR}:${PYTHONPATH:-}"
17
-
18
- # Check if a specific test is provided as parameter
19
- if [ $# -eq 1 ]; then
20
- # Run specific test without coverage
21
- echo "Running specific test: $1"
22
- pytest "$1" -v
23
- else
24
- # Run all tests using pytest with coverage
25
- echo "Running tests with coverage..."
26
- pytest tests/ -v --cov=aixtools --cov-report=term-missing
27
-
28
- # Generate HTML coverage report
29
- # pytest tests/ --cov=aixtools --cov-report=html
30
- fi
tests/unit/__init__.py DELETED
File without changes
File without changes
File without changes
File without changes
@@ -1,188 +0,0 @@
1
- """Tests for the Pydantic AI adapter agent executor module."""
2
-
3
- import unittest
4
- from unittest.mock import AsyncMock, MagicMock, patch
5
-
6
- from a2a.server.agent_execution import RequestContext
7
- from a2a.server.events import EventQueue
8
- from a2a.types import Message, TaskState, TaskStatusUpdateEvent
9
- from pydantic_ai import Agent
10
-
11
- from aixtools.a2a.google_sdk.pydantic_ai_adapter.agent_executor import (
12
- AgentParameters,
13
- RunOutput,
14
- PydanticAgentExecutor,
15
- _task_failed_event,
16
- )
17
-
18
-
19
- class TestAgentParameters(unittest.TestCase):
20
- """Tests for the AgentParameters model."""
21
-
22
- def test_agent_parameters_creation(self):
23
- """Test creating AgentParameters with valid data."""
24
- params = AgentParameters(
25
- system_prompt="Test prompt",
26
- mcp_servers=["server1", "server2"]
27
- )
28
-
29
- self.assertEqual(params.system_prompt, "Test prompt")
30
- self.assertEqual(params.mcp_servers, ["server1", "server2"])
31
-
32
-
33
- class TestRunOutput(unittest.TestCase):
34
- """Tests for the RunOutput model."""
35
-
36
- def test_run_output_creation(self):
37
- """Test creating RunOutput with valid data."""
38
- output = RunOutput(
39
- is_task_failed=False,
40
- is_task_in_progress=True,
41
- is_input_required=False,
42
- output="Test output",
43
- created_artifacts_paths=["path1", "path2"]
44
- )
45
-
46
- self.assertFalse(output.is_task_failed)
47
- self.assertTrue(output.is_task_in_progress)
48
- self.assertFalse(output.is_input_required)
49
- self.assertEqual(output.output, "Test output")
50
- self.assertEqual(output.created_artifacts_paths, ["path1", "path2"])
51
-
52
-
53
- class TestTaskFailedEvent(unittest.TestCase):
54
- """Tests for the _task_failed_event function."""
55
-
56
- def test_task_failed_event_creation(self):
57
- """Test creating a task failed event."""
58
- text = "Test error message"
59
- context_id = "ctx123"
60
- task_id = "task456"
61
-
62
- event = _task_failed_event(text, context_id, task_id)
63
-
64
- self.assertIsInstance(event, TaskStatusUpdateEvent)
65
- self.assertEqual(event.status.state, TaskState.failed)
66
- self.assertEqual(event.context_id, context_id)
67
- self.assertEqual(event.task_id, task_id)
68
- self.assertTrue(event.final)
69
-
70
- def test_task_failed_event_with_none_ids(self):
71
- """Test creating a task failed event with None IDs."""
72
- text = "Test error message"
73
-
74
- event = _task_failed_event(text, "default_ctx", "default_task")
75
-
76
- self.assertIsInstance(event, TaskStatusUpdateEvent)
77
- self.assertEqual(event.status.state, TaskState.failed)
78
- self.assertEqual(event.context_id, "default_ctx")
79
- self.assertEqual(event.task_id, "default_task")
80
- self.assertTrue(event.final)
81
-
82
-
83
- class TestPydanticAgentExecutor(unittest.IsolatedAsyncioTestCase):
84
- """Tests for the PydanticAgentExecutor class."""
85
-
86
- def setUp(self):
87
- self.agent_params = AgentParameters(
88
- system_prompt="Test system prompt",
89
- mcp_servers=["test_server"]
90
- )
91
- self.executor = PydanticAgentExecutor(self.agent_params)
92
-
93
- def test_init(self):
94
- """Test PydanticAgentExecutor initialization."""
95
- self.assertEqual(self.executor._agent_parameters, self.agent_params)
96
- self.assertIsNotNone(self.executor.history_storage)
97
-
98
- @patch("aixtools.a2a.google_sdk.pydantic_ai_adapter.agent_executor.get_message_text")
99
- @patch("aixtools.a2a.google_sdk.pydantic_ai_adapter.agent_executor.get_file_parts")
100
- def test_convert_message_to_pydantic_parts_text_only(self, mock_get_file_parts, mock_get_message_text):
101
- """Test converting message with text only."""
102
- mock_get_message_text.return_value = "Test message"
103
- mock_get_file_parts.return_value = []
104
-
105
- mock_message = MagicMock(spec=Message)
106
- mock_message.parts = []
107
- session_tuple = ("user1", "session1")
108
-
109
- result = self.executor._convert_message_to_pydantic_parts(session_tuple, mock_message)
110
-
111
- self.assertEqual(result, "Test message")
112
- mock_get_message_text.assert_called_once_with(mock_message)
113
- mock_get_file_parts.assert_called_once_with([])
114
-
115
- @patch("aixtools.a2a.google_sdk.pydantic_ai_adapter.agent_executor.build_user_input")
116
- @patch("aixtools.a2a.google_sdk.pydantic_ai_adapter.agent_executor.get_message_text")
117
- @patch("aixtools.a2a.google_sdk.pydantic_ai_adapter.agent_executor.get_file_parts")
118
- def test_convert_message_to_pydantic_parts_with_files(self, mock_get_file_parts, mock_get_message_text, mock_build_user_input):
119
- """Test converting message with files."""
120
- mock_get_message_text.return_value = "Test message"
121
- mock_file_part = MagicMock()
122
- mock_file_part.uri = "/test/path.txt"
123
- mock_get_file_parts.return_value = [mock_file_part]
124
- mock_build_user_input.return_value = ["processed", "input"]
125
-
126
- mock_message = MagicMock(spec=Message)
127
- mock_message.parts = [mock_file_part]
128
- session_tuple = ("user1", "session1")
129
-
130
- result = self.executor._convert_message_to_pydantic_parts(session_tuple, mock_message)
131
-
132
- self.assertEqual(result, ["processed", "input"])
133
- # Verify that build_user_input was called (exact args may vary due to filtering)
134
- mock_build_user_input.assert_called_once()
135
-
136
- def test_execute_no_message_validation(self):
137
- """Test that execute validates message presence."""
138
- # This is a simple validation test without complex integration
139
- mock_context = MagicMock(spec=RequestContext)
140
- mock_context.message = None
141
-
142
- # The actual validation happens in the execute method
143
- # We test the validation logic separately
144
- self.assertIsNone(mock_context.message)
145
-
146
- async def test_cancel_not_supported(self):
147
- """Test that cancel raises an exception."""
148
- mock_context = MagicMock(spec=RequestContext)
149
- mock_event_queue = AsyncMock(spec=EventQueue)
150
-
151
- with self.assertRaises(Exception) as context:
152
- await self.executor.cancel(mock_context, mock_event_queue)
153
-
154
- self.assertIn("cancel not supported", str(context.exception))
155
-
156
- @patch("aixtools.a2a.google_sdk.pydantic_ai_adapter.agent_executor.get_agent")
157
- @patch("aixtools.a2a.google_sdk.pydantic_ai_adapter.agent_executor.get_configured_mcp_servers")
158
- def test_build_agent(self, mock_get_mcp_servers, mock_get_agent):
159
- """Test building an agent."""
160
- mock_agent = MagicMock(spec=Agent)
161
- mock_get_agent.return_value = mock_agent
162
- mock_get_mcp_servers.return_value = ["mcp1", "mcp2"]
163
-
164
- session_tuple = ("user1", "session1")
165
- result = self.executor._build_agent(session_tuple)
166
-
167
- self.assertEqual(result, mock_agent)
168
- mock_get_mcp_servers.assert_called_once_with(session_tuple, ["test_server"])
169
- mock_get_agent.assert_called_once_with(
170
- system_prompt="Test system prompt",
171
- toolsets=["mcp1", "mcp2"],
172
- output_type=RunOutput
173
- )
174
-
175
- def test_task_creation_logic(self):
176
- """Test task creation logic validation."""
177
- # Test the basic logic without complex integration
178
- mock_context = MagicMock(spec=RequestContext)
179
- mock_context.current_task = None
180
- mock_context.message = MagicMock(spec=Message)
181
-
182
- # Verify that when current_task is None, we have a message to work with
183
- self.assertIsNone(mock_context.current_task)
184
- self.assertIsNotNone(mock_context.message)
185
-
186
-
187
- if __name__ == '__main__':
188
- unittest.main()