agent-starter-pack 0.2.3__py3-none-any.whl → 0.3.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 agent-starter-pack might be problematic. Click here for more details.

Files changed (64) hide show
  1. {agent_starter_pack-0.2.3.dist-info → agent_starter_pack-0.3.0.dist-info}/METADATA +8 -4
  2. {agent_starter_pack-0.2.3.dist-info → agent_starter_pack-0.3.0.dist-info}/RECORD +61 -46
  3. agents/adk_base/README.md +14 -0
  4. agents/adk_base/app/agent.py +66 -0
  5. agents/adk_base/notebooks/adk_app_testing.ipynb +305 -0
  6. agents/adk_base/template/.templateconfig.yaml +21 -0
  7. agents/adk_base/tests/integration/test_agent.py +58 -0
  8. agents/agentic_rag/README.md +1 -0
  9. agents/agentic_rag/app/agent.py +44 -89
  10. agents/agentic_rag/app/templates.py +0 -25
  11. agents/agentic_rag/notebooks/adk_app_testing.ipynb +305 -0
  12. agents/agentic_rag/template/.templateconfig.yaml +3 -1
  13. agents/agentic_rag/tests/integration/test_agent.py +34 -27
  14. agents/langgraph_base_react/README.md +1 -1
  15. agents/langgraph_base_react/template/.templateconfig.yaml +1 -1
  16. src/base_template/Makefile +9 -0
  17. src/base_template/README.md +1 -1
  18. src/base_template/app/__init__.py +3 -0
  19. src/base_template/app/utils/tracing.py +11 -1
  20. src/base_template/app/utils/typing.py +54 -4
  21. src/base_template/deployment/terraform/dev/variables.tf +4 -0
  22. src/base_template/deployment/terraform/dev/vars/env.tfvars +0 -3
  23. src/base_template/deployment/terraform/variables.tf +4 -0
  24. src/base_template/deployment/terraform/vars/env.tfvars +0 -4
  25. src/base_template/pyproject.toml +5 -3
  26. src/{deployment_targets/agent_engine → base_template}/tests/unit/test_dummy.py +2 -1
  27. src/cli/commands/create.py +10 -2
  28. src/cli/commands/setup_cicd.py +3 -0
  29. src/cli/utils/gcp.py +1 -1
  30. src/cli/utils/template.py +27 -25
  31. src/data_ingestion/data_ingestion_pipeline/components/ingest_data.py +2 -1
  32. src/deployment_targets/agent_engine/app/agent_engine_app.py +62 -11
  33. src/deployment_targets/agent_engine/app/utils/gcs.py +1 -1
  34. src/deployment_targets/agent_engine/tests/integration/test_agent_engine_app.py +63 -0
  35. src/deployment_targets/agent_engine/tests/load_test/load_test.py +9 -2
  36. src/deployment_targets/cloud_run/app/server.py +41 -15
  37. src/deployment_targets/cloud_run/tests/integration/test_server_e2e.py +60 -3
  38. src/deployment_targets/cloud_run/tests/load_test/README.md +1 -1
  39. src/deployment_targets/cloud_run/tests/load_test/load_test.py +57 -24
  40. src/frontends/live_api_react/frontend/package-lock.json +3 -3
  41. src/frontends/streamlit_adk/frontend/side_bar.py +214 -0
  42. src/frontends/streamlit_adk/frontend/streamlit_app.py +314 -0
  43. src/frontends/streamlit_adk/frontend/style/app_markdown.py +37 -0
  44. src/frontends/streamlit_adk/frontend/utils/chat_utils.py +84 -0
  45. src/frontends/streamlit_adk/frontend/utils/local_chat_history.py +110 -0
  46. src/frontends/streamlit_adk/frontend/utils/message_editing.py +61 -0
  47. src/frontends/streamlit_adk/frontend/utils/multimodal_utils.py +223 -0
  48. src/frontends/streamlit_adk/frontend/utils/stream_handler.py +311 -0
  49. src/frontends/streamlit_adk/frontend/utils/title_summary.py +129 -0
  50. src/resources/locks/uv-adk_base-agent_engine.lock +5335 -0
  51. src/resources/locks/uv-adk_base-cloud_run.lock +5927 -0
  52. src/resources/locks/uv-agentic_rag-agent_engine.lock +882 -676
  53. src/resources/locks/uv-agentic_rag-cloud_run.lock +1014 -835
  54. src/resources/locks/uv-crewai_coding_crew-agent_engine.lock +712 -606
  55. src/resources/locks/uv-crewai_coding_crew-cloud_run.lock +770 -672
  56. src/resources/locks/uv-langgraph_base_react-agent_engine.lock +602 -529
  57. src/resources/locks/uv-langgraph_base_react-cloud_run.lock +763 -665
  58. src/resources/locks/uv-live_api-cloud_run.lock +760 -662
  59. agents/agentic_rag/notebooks/evaluating_langgraph_agent.ipynb +0 -1561
  60. src/base_template/tests/unit/test_utils/test_tracing_exporter.py +0 -140
  61. src/deployment_targets/cloud_run/tests/unit/test_server.py +0 -124
  62. {agent_starter_pack-0.2.3.dist-info → agent_starter_pack-0.3.0.dist-info}/WHEEL +0 -0
  63. {agent_starter_pack-0.2.3.dist-info → agent_starter_pack-0.3.0.dist-info}/entry_points.txt +0 -0
  64. {agent_starter_pack-0.2.3.dist-info → agent_starter_pack-0.3.0.dist-info}/licenses/LICENSE +0 -0
@@ -1,140 +0,0 @@
1
- # Copyright 2025 Google LLC
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
- from collections.abc import Generator
16
- from typing import Any
17
- from unittest.mock import Mock, patch
18
-
19
- import pytest
20
- from google.cloud import logging as google_cloud_logging
21
- from google.cloud import storage
22
- from opentelemetry.sdk.trace import ReadableSpan
23
-
24
- from app.utils.tracing import CloudTraceLoggingSpanExporter
25
-
26
-
27
- @pytest.fixture
28
- def mock_logging_client() -> Mock:
29
- """Create a mock logging client."""
30
- return Mock(spec=google_cloud_logging.Client)
31
-
32
-
33
- @pytest.fixture
34
- def mock_storage_client() -> Mock:
35
- """Create a mock storage client."""
36
- return Mock(spec=storage.Client)
37
-
38
-
39
- @pytest.fixture
40
- def mock_credentials() -> Any:
41
- """Create mock credentials."""
42
- return Mock()
43
-
44
-
45
- @pytest.fixture
46
- def patch_auth(mock_credentials: Any) -> Generator[Mock, None, None]:
47
- """Patch the google.auth.default function."""
48
- with patch(
49
- "google.auth.default", return_value=(mock_credentials, "project")
50
- ) as mock_auth:
51
- yield mock_auth
52
-
53
-
54
- @pytest.fixture
55
- def patch_clients(
56
- mock_logging_client: Mock, mock_storage_client: Mock
57
- ) -> Generator[None, None, None]:
58
- """Patch the logging and storage clients."""
59
- with patch("google.cloud.logging.Client", return_value=mock_logging_client):
60
- with patch("google.cloud.storage.Client", return_value=mock_storage_client):
61
- yield
62
-
63
-
64
- @pytest.fixture
65
- def exporter(
66
- mock_logging_client: Mock,
67
- mock_storage_client: Mock,
68
- patch_auth: Any,
69
- mock_credentials: Any,
70
- patch_clients: Any,
71
- ) -> CloudTraceLoggingSpanExporter:
72
- """Create a CloudTraceLoggingSpanExporter instance for testing."""
73
- exporter = CloudTraceLoggingSpanExporter(
74
- project_id="test-project",
75
- logging_client=mock_logging_client,
76
- storage_client=mock_storage_client,
77
- bucket_name="test-bucket",
78
- )
79
- return exporter
80
-
81
-
82
- def test_init(exporter: CloudTraceLoggingSpanExporter) -> None:
83
- """Test the initialization of CloudTraceLoggingSpanExporter."""
84
- assert exporter.project_id == "test-project"
85
- assert exporter.bucket_name == "test-bucket"
86
- assert exporter.debug is False
87
-
88
-
89
- def test_store_in_gcs(exporter: CloudTraceLoggingSpanExporter) -> None:
90
- """Test the store_in_gcs method of CloudTraceLoggingSpanExporter."""
91
- span_id = "test-span-id"
92
- content = "test-content"
93
- uri = exporter.store_in_gcs(content, span_id)
94
- assert uri == f"gs://test-bucket/spans/{span_id}.json"
95
- exporter.bucket.blob.assert_called_once_with(f"spans/{span_id}.json")
96
-
97
-
98
- @patch("json.dumps")
99
- def test_process_large_attributes_small_payload(
100
- mock_json_dumps: Mock, exporter: CloudTraceLoggingSpanExporter
101
- ) -> None:
102
- """Test processing of small payload attributes."""
103
- mock_json_dumps.return_value = "a" * 100 # Small payload
104
- span_dict = {"attributes": {"key": "value"}}
105
- result = exporter._process_large_attributes(span_dict, "span-id")
106
- assert result == span_dict
107
-
108
-
109
- @patch("json.dumps")
110
- def test_process_large_attributes_large_payload(
111
- mock_json_dumps: Mock, exporter: CloudTraceLoggingSpanExporter
112
- ) -> None:
113
- """Test processing of large payload attributes."""
114
- mock_json_dumps.return_value = "a" * (400 * 1024 + 1) # Large payload
115
- span_dict = {
116
- "attributes": {
117
- "key1": "value1",
118
- }
119
- }
120
- result = exporter._process_large_attributes(span_dict, "span-id")
121
- assert "uri_payload" in result["attributes"]
122
- assert "url_payload" in result["attributes"]
123
-
124
-
125
- @patch.object(CloudTraceLoggingSpanExporter, "_process_large_attributes")
126
- def test_export(
127
- mock_process_large_attributes: Mock, exporter: CloudTraceLoggingSpanExporter
128
- ) -> None:
129
- """Test the export method of CloudTraceLoggingSpanExporter."""
130
- mock_span = Mock(spec=ReadableSpan)
131
- mock_span.get_span_context.return_value.trace_id = 123
132
- mock_span.get_span_context.return_value.span_id = 456
133
- mock_span.to_json.return_value = '{"key": "value"}'
134
-
135
- mock_process_large_attributes.return_value = {"processed": "data"}
136
-
137
- exporter.export([mock_span])
138
-
139
- mock_process_large_attributes.assert_called_once()
140
- exporter.logger.log_struct.assert_called_once()
@@ -1,124 +0,0 @@
1
- # Copyright 2025 Google LLC
2
- #
3
- # Licensed under the Apache License, Version 2.0 (the "License");
4
- # you may not use this file except in compliance with the License.
5
- # You may obtain a copy of the License at
6
- #
7
- # http://www.apache.org/licenses/LICENSE-2.0
8
- #
9
- # Unless required by applicable law or agreed to in writing, software
10
- # distributed under the License is distributed on an "AS IS" BASIS,
11
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
- # See the License for the specific language governing permissions and
13
- # limitations under the License.
14
-
15
- import json
16
- import logging
17
- import os
18
- import sys
19
- from collections.abc import Generator
20
- from unittest.mock import MagicMock, patch
21
-
22
- import pytest
23
- from fastapi.testclient import TestClient
24
- from google.auth.credentials import Credentials
25
- from langchain_core.messages import HumanMessage
26
-
27
- from app.utils.typing import InputChat
28
-
29
- # Set up logging
30
- logging.basicConfig(level=logging.INFO)
31
- logger = logging.getLogger(__name__)
32
-
33
-
34
- @pytest.fixture(autouse=True)
35
- def mock_google_cloud_credentials() -> Generator[None, None, None]:
36
- """Mock Google Cloud credentials for testing."""
37
- with patch.dict(
38
- os.environ,
39
- {
40
- "GOOGLE_APPLICATION_CREDENTIALS": "/path/to/mock/credentials.json",
41
- "GOOGLE_CLOUD_PROJECT_ID": "mock-project-id",
42
- },
43
- ):
44
- yield
45
-
46
-
47
- @pytest.fixture(autouse=True)
48
- def mock_google_auth_default() -> Generator[None, None, None]:
49
- """Mock the google.auth.default function for testing."""
50
- mock_credentials = MagicMock(spec=Credentials)
51
- mock_project = "mock-project-id"
52
-
53
- with patch("google.auth.default", return_value=(mock_credentials, mock_project)):
54
- yield
55
-
56
-
57
- @pytest.fixture
58
- def sample_input_chat() -> InputChat:
59
- """
60
- Fixture to create a sample input chat for testing.
61
- """
62
- return InputChat(
63
- messages=[HumanMessage(content="What is the meaning of life?")],
64
- )
65
-
66
-
67
- def test_redirect_root_to_docs() -> None:
68
- """
69
- Test that the root endpoint (/) redirects to the Swagger UI documentation.
70
- """
71
- # Mock the agent module before importing server
72
- mock_agent = MagicMock()
73
- with patch.dict(sys.modules, {"app.agent": mock_agent}):
74
- # Now import server after the mock is in place
75
- from app.server import app
76
-
77
- client = TestClient(app)
78
- response = client.get("/")
79
- assert response.status_code == 200
80
- assert "Swagger UI" in response.text
81
-
82
-
83
- @pytest.mark.asyncio
84
- async def test_stream_chat_events() -> None:
85
- """
86
- Test the stream endpoint to ensure it correctly handles
87
- streaming responses and generates the expected events.
88
- """
89
- input_data = {
90
- "input": {
91
- "messages": [
92
- {"type": "human", "content": "Hello, AI!"},
93
- {"type": "ai", "content": "Hello!"},
94
- {"type": "human", "content": "What cooking recipes do you suggest?"},
95
- ],
96
- },
97
- "config": {"metadata": {"user_id": "test-user", "session_id": "test-session"}},
98
- }
99
-
100
- mock_events = [{"content": "Mocked response"}, {"content": "Additional response"}]
101
-
102
- # Create a mock agent module
103
- mock_agent_module = MagicMock()
104
- mock_agent_module.agent = MagicMock()
105
- mock_agent_module.agent.stream.return_value = mock_events
106
-
107
- # Patch the module import
108
- with patch.dict(sys.modules, {"app.agent": mock_agent_module}):
109
- # Import server after the mock is in place
110
- from app.server import app
111
-
112
- client = TestClient(app)
113
- response = client.post("/stream_messages", json=input_data)
114
-
115
- assert response.status_code == 200
116
-
117
- events = []
118
- for line in response.iter_lines():
119
- if line:
120
- events.append(json.loads(line))
121
-
122
- assert len(events) == 2
123
- assert events[0]["content"] == "Mocked response"
124
- assert events[1]["content"] == "Additional response"