reasoning-deployment-service 0.3.5__tar.gz → 0.3.6__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.

Potentially problematic release.


This version of reasoning-deployment-service might be problematic. Click here for more details.

Files changed (37) hide show
  1. reasoning_deployment_service-0.3.6/PKG-INFO +211 -0
  2. reasoning_deployment_service-0.3.6/README.md +183 -0
  3. {reasoning_deployment_service-0.3.5 → reasoning_deployment_service-0.3.6}/pyproject.toml +1 -1
  4. {reasoning_deployment_service-0.3.5 → reasoning_deployment_service-0.3.6}/reasoning_deployment_service/cli_editor/api_client.py +135 -1
  5. {reasoning_deployment_service-0.3.5 → reasoning_deployment_service-0.3.6}/reasoning_deployment_service/cli_editor/cli_runner.py +46 -0
  6. reasoning_deployment_service-0.3.6/reasoning_deployment_service/gui_editor/agent_checkbox_list.py +48 -0
  7. {reasoning_deployment_service-0.3.5 → reasoning_deployment_service-0.3.6}/reasoning_deployment_service/gui_editor/src/core/api_client.py +88 -0
  8. {reasoning_deployment_service-0.3.5 → reasoning_deployment_service-0.3.6}/reasoning_deployment_service/gui_editor/src/ui/agent_space_view.py +99 -7
  9. {reasoning_deployment_service-0.3.5 → reasoning_deployment_service-0.3.6}/reasoning_deployment_service/gui_editor/src/ui/authorization_view.py +127 -13
  10. reasoning_deployment_service-0.3.6/reasoning_deployment_service.egg-info/PKG-INFO +211 -0
  11. {reasoning_deployment_service-0.3.5 → reasoning_deployment_service-0.3.6}/reasoning_deployment_service.egg-info/SOURCES.txt +1 -0
  12. reasoning_deployment_service-0.3.5/PKG-INFO +0 -183
  13. reasoning_deployment_service-0.3.5/README.md +0 -155
  14. reasoning_deployment_service-0.3.5/reasoning_deployment_service.egg-info/PKG-INFO +0 -183
  15. {reasoning_deployment_service-0.3.5 → reasoning_deployment_service-0.3.6}/reasoning_deployment_service/__init__.py +0 -0
  16. {reasoning_deployment_service-0.3.5 → reasoning_deployment_service-0.3.6}/reasoning_deployment_service/cli_editor/__init__.py +0 -0
  17. {reasoning_deployment_service-0.3.5 → reasoning_deployment_service-0.3.6}/reasoning_deployment_service/cli_editor/config.py +0 -0
  18. {reasoning_deployment_service-0.3.5 → reasoning_deployment_service-0.3.6}/reasoning_deployment_service/cli_editor/google_deps.py +0 -0
  19. {reasoning_deployment_service-0.3.5 → reasoning_deployment_service-0.3.6}/reasoning_deployment_service/cli_editor/reasoning_engine_creator.py +0 -0
  20. {reasoning_deployment_service-0.3.5 → reasoning_deployment_service-0.3.6}/reasoning_deployment_service/gui_editor/__init__.py +0 -0
  21. {reasoning_deployment_service-0.3.5 → reasoning_deployment_service-0.3.6}/reasoning_deployment_service/gui_editor/main.py +0 -0
  22. {reasoning_deployment_service-0.3.5 → reasoning_deployment_service-0.3.6}/reasoning_deployment_service/gui_editor/src/__init__.py +0 -0
  23. {reasoning_deployment_service-0.3.5 → reasoning_deployment_service-0.3.6}/reasoning_deployment_service/gui_editor/src/core/__init__.py +0 -0
  24. {reasoning_deployment_service-0.3.5 → reasoning_deployment_service-0.3.6}/reasoning_deployment_service/gui_editor/src/core/config.py +0 -0
  25. {reasoning_deployment_service-0.3.5 → reasoning_deployment_service-0.3.6}/reasoning_deployment_service/gui_editor/src/core/google_deps.py +0 -0
  26. {reasoning_deployment_service-0.3.5 → reasoning_deployment_service-0.3.6}/reasoning_deployment_service/gui_editor/src/core/reasoning_engine_creator.py +0 -0
  27. {reasoning_deployment_service-0.3.5 → reasoning_deployment_service-0.3.6}/reasoning_deployment_service/gui_editor/src/ui/__init__.py +0 -0
  28. {reasoning_deployment_service-0.3.5 → reasoning_deployment_service-0.3.6}/reasoning_deployment_service/gui_editor/src/ui/reasoning_engine_view.py +0 -0
  29. {reasoning_deployment_service-0.3.5 → reasoning_deployment_service-0.3.6}/reasoning_deployment_service/gui_editor/src/ui/reasoning_engines_view.py +0 -0
  30. {reasoning_deployment_service-0.3.5 → reasoning_deployment_service-0.3.6}/reasoning_deployment_service/gui_editor/src/ui/ui_components.py +0 -0
  31. {reasoning_deployment_service-0.3.5 → reasoning_deployment_service-0.3.6}/reasoning_deployment_service/reasoning_deployment_service.py +0 -0
  32. {reasoning_deployment_service-0.3.5 → reasoning_deployment_service-0.3.6}/reasoning_deployment_service/runner.py +0 -0
  33. {reasoning_deployment_service-0.3.5 → reasoning_deployment_service-0.3.6}/reasoning_deployment_service.egg-info/dependency_links.txt +0 -0
  34. {reasoning_deployment_service-0.3.5 → reasoning_deployment_service-0.3.6}/reasoning_deployment_service.egg-info/entry_points.txt +0 -0
  35. {reasoning_deployment_service-0.3.5 → reasoning_deployment_service-0.3.6}/reasoning_deployment_service.egg-info/requires.txt +0 -0
  36. {reasoning_deployment_service-0.3.5 → reasoning_deployment_service-0.3.6}/reasoning_deployment_service.egg-info/top_level.txt +0 -0
  37. {reasoning_deployment_service-0.3.5 → reasoning_deployment_service-0.3.6}/setup.cfg +0 -0
@@ -0,0 +1,211 @@
1
+ Metadata-Version: 2.4
2
+ Name: reasoning-deployment-service
3
+ Version: 0.3.6
4
+ Summary: Deployment helper for Vertex AI Reasoning Engines & Agent Spaces
5
+ Author-email: Sergio Estrada <sergio.estrada@accenture.com>
6
+ License: Apache-2.0
7
+ Project-URL: Homepage, https://github.com/AxG-AI-Exchange-GenAI-Initiative/AIXAgentDeploymentService
8
+ Project-URL: Repository, https://github.com/AxG-AI-Exchange-GenAI-Initiative/AIXAgentDeploymentService
9
+ Project-URL: Issues, https://github.com/AxG-AI-Exchange-GenAI-Initiative/AIXAgentDeploymentService/issues
10
+ Requires-Python: >=3.9
11
+ Description-Content-Type: text/markdown
12
+ Requires-Dist: requests>=2.28
13
+ Requires-Dist: python-dotenv>=1.0
14
+ Requires-Dist: google-auth>=2.20
15
+ Requires-Dist: google-cloud-storage>=2.16
16
+ Requires-Dist: google-cloud-aiplatform[adk,agent-engines]>=1.88.0
17
+ Requires-Dist: protobuf<7.0.0,>=4.21
18
+ Requires-Dist: keyring>=24.0
19
+ Requires-Dist: keyrings.google-artifactregistry-auth>=1.1
20
+ Requires-Dist: PyYAML>=6.0
21
+ Requires-Dist: click>=8.0
22
+ Provides-Extra: dev
23
+ Requires-Dist: pytest; extra == "dev"
24
+ Requires-Dist: build; extra == "dev"
25
+ Requires-Dist: twine; extra == "dev"
26
+ Requires-Dist: black; extra == "dev"
27
+ Requires-Dist: ruff; extra == "dev"
28
+
29
+ # Reasoning Deployment Service
30
+
31
+ Helper package for deploying Vertex AI Reasoning Engines and Agent Spaces
32
+
33
+ ---
34
+
35
+ ## 📦 Installation
36
+
37
+ Install the package directly from PyPI (version 0.3.5):
38
+
39
+ ```bash
40
+ pip install reasoning-deployment-service==0.3.5
41
+ ```
42
+
43
+ ---
44
+
45
+ ## 🚀 First Run
46
+
47
+ Run the CLI tool with no arguments:
48
+
49
+ ```bash
50
+ reasoning-deploy
51
+ ```
52
+
53
+ ### What happens
54
+
55
+ - You will see a list of available modes:
56
+
57
+ ```
58
+ Choose an operation:
59
+ 1) Create/Update
60
+ 2) Auth only
61
+ 3) CLI
62
+ 4) GUI
63
+ q) Quit
64
+ ```
65
+
66
+ - If required files are missing, usage will be limited until you bootstrap the project
67
+ - The tool will guide you to create the starter files:
68
+ - `your_agent_import.py` (shim pointing to your agent folder)
69
+ - `.env.agent` (environment and project settings)
70
+ - `aix_agent.yaml` (agent engine and space definition)
71
+
72
+ Once these are in place, all modes will be fully available
73
+
74
+ ⚠️ Important: You must be running inside the same virtual environment where you installed reasoning-deployment-service
75
+
76
+ ---
77
+
78
+ ## ⚙️ Required Project Structure
79
+
80
+ Your project must have the following at minimum:
81
+
82
+ ```
83
+ my_project/
84
+ ├── requirements.txt # pinned dependencies
85
+ ├── .env.agent # environment and project config
86
+ ├── aix_agent.yaml # engine and agent space definition
87
+ ├── my_agent/ # your agent folder
88
+ │ └── agent.py # defines root_agent
89
+ ```
90
+
91
+ ---
92
+
93
+ ### ✅ requirements.txt
94
+
95
+ This file must be in your project root and contain all dependencies
96
+
97
+ Example:
98
+
99
+ ```text
100
+ google-adk==1.0.0
101
+ google-cloud-aiplatform[adk,agent_engines]>=1.88.0
102
+ google-generativeai>=0.7.0
103
+ pydantic>=2.0.0
104
+ python-dotenv>=1.0.0
105
+ python-docx>=1.1.0
106
+ google-api-python-client>=2.100.0
107
+ google-auth>=2.25.0
108
+ google-auth-httplib2>=0.2.0
109
+ google-auth-oauthlib>=1.2.0
110
+ absl-py>=2.0.0
111
+ PyPDF2>=3.0.0
112
+ deprecated>=1.2.14
113
+ reasoning-deployment-service==0.3.5
114
+ ```
115
+
116
+ Install with:
117
+
118
+ ```bash
119
+ pip install -r requirements.txt
120
+ ```
121
+
122
+ ---
123
+
124
+ ### ✅ my_agent/agent.py
125
+
126
+ Inside your agent folder (for example `my_agent`) you must define a variable called `root_agent`
127
+
128
+ Example:
129
+
130
+ ```python
131
+ from google.adk.agents import LlmAgent
132
+
133
+ root_agent = LlmAgent(
134
+ name="my_agent",
135
+ model="gemini-2.5-flash",
136
+ description="My reasoning agent",
137
+ instruction="You do not do a whole lot yet"
138
+ )
139
+ ```
140
+
141
+ This `root_agent` instance is what gets deployed
142
+ It can be an `LlmAgent`, `Agent`, or any derived class
143
+
144
+ ---
145
+
146
+ ### ✅ .env.agent
147
+
148
+ Environment specific config for DEV and PROD
149
+
150
+ Example:
151
+
152
+ ```env
153
+ DEV_PROJECT_ID=your-dev-project-id
154
+ DEV_PROJECT_NUMBER=123456789012
155
+ DEV_PROJECT_LOCATION=us-central1
156
+ DEV_STAGING_BUCKET=gs://your-dev-staging-bucket
157
+ DEV_AGENT_SPACE_ENGINE=your-dev-agentspace-engine
158
+ DEV_OAUTH_CLIENT_ID=your-dev-oauth-client-id.apps.googleusercontent.com
159
+ DEV_OAUTH_CLIENT_SECRET=your-dev-oauth-client-secret
160
+
161
+ PROD_PROJECT_ID=
162
+ PROD_PROJECT_NUMBER=
163
+ PROD_PROJECT_LOCATION=
164
+ PROD_STAGING_BUCKET=
165
+ PROD_AGENT_SPACE_ENGINE=
166
+ PROD_OAUTH_CLIENT_ID=
167
+ PROD_OAUTH_CLIENT_SECRET=
168
+
169
+ REASONING_DEPLOYMENT_VERSION=0.3.5
170
+
171
+ DEVELOPER=your.name
172
+ ```
173
+
174
+ ---
175
+
176
+ ### ✅ aix_agent.yaml
177
+
178
+ Example starter file:
179
+
180
+ ```yaml
181
+ defaults:
182
+ scopes:
183
+ - https://www.googleapis.com/auth/cloud-platform
184
+ - https://www.googleapis.com/auth/userinfo.email
185
+ metadata:
186
+ reasoning_engine_name: reasoning-engine-dev
187
+ reasoning_engine_description: My Engine
188
+ agent_space_name: My Agent Space
189
+ agent_space_description: Example Agent Space
190
+ agent_space_tool_description: Example Tool
191
+ agent_folder: my_agent
192
+ auth:
193
+ oauth_authorization_id: test_auth
194
+ environment_variables:
195
+ - DEVELOPER
196
+ ```
197
+
198
+ ---
199
+
200
+ ## 🛠 Potential Issues
201
+
202
+ - If you cannot run `reasoning-deploy`, try deleting your venv and making a new one
203
+ - If you see a message saying you can only install on user site-packages, you will most likely need a fresh venv and new requirements install
204
+ - Always ensure you are running `reasoning-deploy` inside the venv where it was installed
205
+
206
+ ---
207
+
208
+ ## ⚠️ Experimental Notice
209
+
210
+ This tool is still experimental
211
+ If it takes longer than 20 to 30 minutes to set up, please go back to what already works for you and send logs and feedback to the development team
@@ -0,0 +1,183 @@
1
+ # Reasoning Deployment Service
2
+
3
+ Helper package for deploying Vertex AI Reasoning Engines and Agent Spaces
4
+
5
+ ---
6
+
7
+ ## 📦 Installation
8
+
9
+ Install the package directly from PyPI (version 0.3.5):
10
+
11
+ ```bash
12
+ pip install reasoning-deployment-service==0.3.5
13
+ ```
14
+
15
+ ---
16
+
17
+ ## 🚀 First Run
18
+
19
+ Run the CLI tool with no arguments:
20
+
21
+ ```bash
22
+ reasoning-deploy
23
+ ```
24
+
25
+ ### What happens
26
+
27
+ - You will see a list of available modes:
28
+
29
+ ```
30
+ Choose an operation:
31
+ 1) Create/Update
32
+ 2) Auth only
33
+ 3) CLI
34
+ 4) GUI
35
+ q) Quit
36
+ ```
37
+
38
+ - If required files are missing, usage will be limited until you bootstrap the project
39
+ - The tool will guide you to create the starter files:
40
+ - `your_agent_import.py` (shim pointing to your agent folder)
41
+ - `.env.agent` (environment and project settings)
42
+ - `aix_agent.yaml` (agent engine and space definition)
43
+
44
+ Once these are in place, all modes will be fully available
45
+
46
+ ⚠️ Important: You must be running inside the same virtual environment where you installed reasoning-deployment-service
47
+
48
+ ---
49
+
50
+ ## ⚙️ Required Project Structure
51
+
52
+ Your project must have the following at minimum:
53
+
54
+ ```
55
+ my_project/
56
+ ├── requirements.txt # pinned dependencies
57
+ ├── .env.agent # environment and project config
58
+ ├── aix_agent.yaml # engine and agent space definition
59
+ ├── my_agent/ # your agent folder
60
+ │ └── agent.py # defines root_agent
61
+ ```
62
+
63
+ ---
64
+
65
+ ### ✅ requirements.txt
66
+
67
+ This file must be in your project root and contain all dependencies
68
+
69
+ Example:
70
+
71
+ ```text
72
+ google-adk==1.0.0
73
+ google-cloud-aiplatform[adk,agent_engines]>=1.88.0
74
+ google-generativeai>=0.7.0
75
+ pydantic>=2.0.0
76
+ python-dotenv>=1.0.0
77
+ python-docx>=1.1.0
78
+ google-api-python-client>=2.100.0
79
+ google-auth>=2.25.0
80
+ google-auth-httplib2>=0.2.0
81
+ google-auth-oauthlib>=1.2.0
82
+ absl-py>=2.0.0
83
+ PyPDF2>=3.0.0
84
+ deprecated>=1.2.14
85
+ reasoning-deployment-service==0.3.5
86
+ ```
87
+
88
+ Install with:
89
+
90
+ ```bash
91
+ pip install -r requirements.txt
92
+ ```
93
+
94
+ ---
95
+
96
+ ### ✅ my_agent/agent.py
97
+
98
+ Inside your agent folder (for example `my_agent`) you must define a variable called `root_agent`
99
+
100
+ Example:
101
+
102
+ ```python
103
+ from google.adk.agents import LlmAgent
104
+
105
+ root_agent = LlmAgent(
106
+ name="my_agent",
107
+ model="gemini-2.5-flash",
108
+ description="My reasoning agent",
109
+ instruction="You do not do a whole lot yet"
110
+ )
111
+ ```
112
+
113
+ This `root_agent` instance is what gets deployed
114
+ It can be an `LlmAgent`, `Agent`, or any derived class
115
+
116
+ ---
117
+
118
+ ### ✅ .env.agent
119
+
120
+ Environment specific config for DEV and PROD
121
+
122
+ Example:
123
+
124
+ ```env
125
+ DEV_PROJECT_ID=your-dev-project-id
126
+ DEV_PROJECT_NUMBER=123456789012
127
+ DEV_PROJECT_LOCATION=us-central1
128
+ DEV_STAGING_BUCKET=gs://your-dev-staging-bucket
129
+ DEV_AGENT_SPACE_ENGINE=your-dev-agentspace-engine
130
+ DEV_OAUTH_CLIENT_ID=your-dev-oauth-client-id.apps.googleusercontent.com
131
+ DEV_OAUTH_CLIENT_SECRET=your-dev-oauth-client-secret
132
+
133
+ PROD_PROJECT_ID=
134
+ PROD_PROJECT_NUMBER=
135
+ PROD_PROJECT_LOCATION=
136
+ PROD_STAGING_BUCKET=
137
+ PROD_AGENT_SPACE_ENGINE=
138
+ PROD_OAUTH_CLIENT_ID=
139
+ PROD_OAUTH_CLIENT_SECRET=
140
+
141
+ REASONING_DEPLOYMENT_VERSION=0.3.5
142
+
143
+ DEVELOPER=your.name
144
+ ```
145
+
146
+ ---
147
+
148
+ ### ✅ aix_agent.yaml
149
+
150
+ Example starter file:
151
+
152
+ ```yaml
153
+ defaults:
154
+ scopes:
155
+ - https://www.googleapis.com/auth/cloud-platform
156
+ - https://www.googleapis.com/auth/userinfo.email
157
+ metadata:
158
+ reasoning_engine_name: reasoning-engine-dev
159
+ reasoning_engine_description: My Engine
160
+ agent_space_name: My Agent Space
161
+ agent_space_description: Example Agent Space
162
+ agent_space_tool_description: Example Tool
163
+ agent_folder: my_agent
164
+ auth:
165
+ oauth_authorization_id: test_auth
166
+ environment_variables:
167
+ - DEVELOPER
168
+ ```
169
+
170
+ ---
171
+
172
+ ## 🛠 Potential Issues
173
+
174
+ - If you cannot run `reasoning-deploy`, try deleting your venv and making a new one
175
+ - If you see a message saying you can only install on user site-packages, you will most likely need a fresh venv and new requirements install
176
+ - Always ensure you are running `reasoning-deploy` inside the venv where it was installed
177
+
178
+ ---
179
+
180
+ ## ⚠️ Experimental Notice
181
+
182
+ This tool is still experimental
183
+ If it takes longer than 20 to 30 minutes to set up, please go back to what already works for you and send logs and feedback to the development team
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "reasoning-deployment-service"
7
- version = "0.3.5"
7
+ version = "0.3.6"
8
8
  description = "Deployment helper for Vertex AI Reasoning Engines & Agent Spaces"
9
9
  readme = "README.md"
10
10
  license = { text = "Apache-2.0" }
@@ -30,6 +30,27 @@ EXCLUDES = [
30
30
 
31
31
 
32
32
  class ApiClient:
33
+ def get_authorization_info(self, auth_id: str) -> dict:
34
+ """Get details for a specific authorization by ID."""
35
+ if not self.is_live:
36
+ # Return mock info for testing
37
+ return {
38
+ "id": auth_id,
39
+ "scopes": [
40
+ "https://www.googleapis.com/auth/cloud-platform",
41
+ "https://www.googleapis.com/auth/userinfo.email"
42
+ ],
43
+ "status": "mock"
44
+ }
45
+ headers = {
46
+ "Authorization": f"Bearer {self._access_token()}",
47
+ "Content-Type": "application/json",
48
+ "X-Goog-User-Project": self.project_id,
49
+ }
50
+ url = f"https://discoveryengine.googleapis.com/v1alpha/projects/{self.project_id}/locations/global/authorizations/{auth_id}"
51
+ r = self._http.get(url, headers=headers, timeout=60)
52
+ r.raise_for_status()
53
+ return r.json()
33
54
  """
34
55
  Single responsibility: hold configuration & credentials and expose API calls.
35
56
  This class has both 'live' and 'mock' modes; the public surface is identical.
@@ -559,6 +580,63 @@ class ApiClient:
559
580
  else:
560
581
  return ("failed", f"{r.status_code} {r.text}")
561
582
 
583
+ def get_authorization_info(self, auth_id: str) -> Dict[str, Any]:
584
+ """Get details for a specific authorization by ID."""
585
+ if not self.is_live:
586
+ # Return mock info for testing
587
+ return {
588
+ "id": auth_id,
589
+ "scopes": [
590
+ "https://www.googleapis.com/auth/cloud-platform",
591
+ "https://www.googleapis.com/auth/userinfo.email"
592
+ ],
593
+ "status": "mock"
594
+ }
595
+ headers = {
596
+ "Authorization": f"Bearer {self._access_token()}",
597
+ "Content-Type": "application/json",
598
+ "X-Goog-User-Project": self.project_id,
599
+ }
600
+ url = f"{BASE_URL}/projects/{self.project_id}/locations/global/authorizations/{auth_id}"
601
+ r = self._http.get(url, headers=headers, timeout=60)
602
+ r.raise_for_status()
603
+ return r.json()
604
+
605
+ def update_authorization_scopes(self, auth_id: str, scopes: list) -> Dict[str, Any]:
606
+ """Patch the scopes for a specific authorization by ID, updating the authorizationUri as well."""
607
+ if not self.is_live:
608
+ return {
609
+ "id": auth_id,
610
+ "scopes": scopes,
611
+ "status": "mock-patched"
612
+ }
613
+ headers = {
614
+ "Authorization": f"Bearer {self._access_token()}",
615
+ "Content-Type": "application/json",
616
+ "X-Goog-User-Project": self.project_number,
617
+ }
618
+ url = f"{BASE_URL}/projects/{self.project_number}/locations/global/authorizations/{auth_id}?update_mask=server_side_oauth2.authorization_uri"
619
+ scopes_str = "%20".join(scopes)
620
+ authorization_uri = (
621
+ "https://accounts.google.com/o/oauth2/auth"
622
+ "?response_type=code"
623
+ f"&client_id={self.oauth_client_id or 'your-client-id'}"
624
+ f"&scope={scopes_str}"
625
+ "&access_type=offline&prompt=consent"
626
+ )
627
+
628
+ payload = {
629
+ "serverSideOauth2": {
630
+ "authorizationUri": authorization_uri
631
+ }
632
+ }
633
+ r = self._http.patch(url, headers=headers, json=payload, timeout=60)
634
+ print(r.status_code)
635
+ print(r.text)
636
+ print(r.json())
637
+ r.raise_for_status()
638
+ return r.json()
639
+
562
640
  def _ensure_authorization(self, auth_name: str) -> Tuple[bool, str]:
563
641
  if not self.is_live:
564
642
  time.sleep(0.02)
@@ -663,4 +741,60 @@ class ApiClient:
663
741
  }
664
742
  self._profile["agent_space_agent_id"] = full
665
743
  self._save_profile()
666
- return ("created", "Deployed", item)
744
+ return ("created", "Deployed", item)
745
+
746
+ def remove_authorization_from_agent(self, agent_id: str) -> Dict[str, Any]:
747
+ """Remove all authorizations from an agent by PATCHing with an empty authorizations list."""
748
+ if not self.is_live:
749
+ return {
750
+ "id": agent_id,
751
+ "authorizations": [],
752
+ "status": "mock-removed"
753
+ }
754
+ headers = {
755
+ "Authorization": f"Bearer {self._access_token()}",
756
+ "Content-Type": "application/json",
757
+ "X-Goog-User-Project": self.project_id,
758
+ }
759
+ url = f"{BASE_URL}/projects/{self.project_id}/locations/global/assistants/default_assistant/agents/{agent_id}"
760
+ payload = {"authorizations": []}
761
+ r = self._http.patch(url, headers=headers, json=payload, timeout=60)
762
+ r.raise_for_status()
763
+ return r.json()
764
+
765
+ def drop_agent_authorizations(self, agent_id: str) -> Dict[str, Any]:
766
+ """Drop all authorizations for an agent space agent by PATCHing with all attributes except authorizations (fully omitted)."""
767
+ if not self.is_live:
768
+ return {
769
+ "id": agent_id,
770
+ "authorizations": [],
771
+ "status": "mock-dropped"
772
+ }
773
+ headers = {
774
+ "Authorization": f"Bearer {self._access_token()}",
775
+ "Content-Type": "application/json",
776
+ "X-Goog-User-Project": self.project_id,
777
+ }
778
+ url = (f"{BASE_URL}/projects/{self.project_id}/locations/global/collections/default_collection/"
779
+ f"engines/{self.engine_name}/assistants/default_assistant/agents/{agent_id}")
780
+ # GET the current agent definition
781
+ get_resp = self._http.get(url, headers=headers, timeout=60)
782
+ get_resp.raise_for_status()
783
+ agent_data = get_resp.json()
784
+ # Build PATCH payload: copy all attributes except authorizations
785
+ patch_payload = {}
786
+ for key in ["displayName", "description"]:
787
+ if key in agent_data:
788
+ patch_payload[key] = agent_data[key]
789
+ adk_def = agent_data.get("adkAgentDefinition", {})
790
+ patch_adk_def = {}
791
+ # Copy all adkAgentDefinition fields except 'authorizations'
792
+ for k, v in adk_def.items():
793
+ if k != "authorizations":
794
+ patch_adk_def[k] = v
795
+ if patch_adk_def:
796
+ patch_payload["adk_agent_definition"] = patch_adk_def
797
+ # PATCH with the new payload
798
+ patch_resp = self._http.patch(url, headers=headers, json=patch_payload, timeout=60)
799
+ patch_resp.raise_for_status()
800
+ return patch_resp.json()
@@ -43,6 +43,14 @@ class CLIRunner:
43
43
  subparsers.add_parser("list-authorizations", help="List all authorizations in the project")
44
44
  delete_auth_parser = subparsers.add_parser("delete-authorization", help="Delete an authorization by list position")
45
45
  delete_auth_parser.add_argument("position", help="Position number from the list (e.g., 1, 2, 3...)")
46
+ # New commands
47
+ get_auth_info_parser = subparsers.add_parser("get-authorization-info", help="Get details for a specific authorization")
48
+ get_auth_info_parser.add_argument("auth_id", help="Authorization ID")
49
+ update_auth_scopes_parser = subparsers.add_parser("update-authorization-scopes", help="Update scopes for a specific authorization")
50
+ update_auth_scopes_parser.add_argument("auth_id", help="Authorization ID")
51
+ update_auth_scopes_parser.add_argument("scopes", help="Comma-separated list of scopes")
52
+ drop_agent_auth_parser = subparsers.add_parser("drop-agent-authorizations", help="Drop all authorizations for an agent space agent")
53
+ drop_agent_auth_parser.add_argument("agent_id", help="Agent ID")
46
54
 
47
55
  def run(self):
48
56
  # Load environment variables from .env.agent file (same as GUI editor)
@@ -113,12 +121,20 @@ class CLIRunner:
113
121
  self._list_authorizations()
114
122
  elif args.command == "delete-authorization":
115
123
  self._delete_authorization(args.position)
124
+ elif args.command == "get-authorization-info":
125
+ self._get_authorization_info(args.auth_id)
126
+ elif args.command == "update-authorization-scopes":
127
+ scopes = [s.strip() for s in args.scopes.split(",") if s.strip()]
128
+ self._update_authorization_scopes(args.auth_id, scopes)
129
+ elif args.command == "drop-agent-authorizations":
130
+ self._drop_agent_authorizations(args.agent_id)
116
131
  else:
117
132
  self.parser.print_help()
118
133
  except SystemExit:
119
134
  # Catch argparse's SystemExit to prevent CLI from closing
120
135
  print("Invalid command. Please try again.")
121
136
  except Exception as e:
137
+ raise
122
138
  print(f"An error occurred: {e}")
123
139
  print("\nAvailable commands:")
124
140
  print(" list-engines List all reasoning engines in the project")
@@ -339,5 +355,35 @@ class CLIRunner:
339
355
  except Exception as e:
340
356
  print(f"❌ Error deleting authorization: {e}")
341
357
 
358
+ def _get_authorization_info(self, auth_id):
359
+ """Get details for a specific authorization."""
360
+ print(f"🔍 Getting info for authorization: {auth_id}")
361
+ try:
362
+ info = self.api_client.get_authorization_info(auth_id)
363
+ from pprint import pprint
364
+ pprint(info)
365
+ except Exception as e:
366
+ print(f"❌ Error getting authorization info: {e}")
367
+
368
+ def _update_authorization_scopes(self, auth_id, scopes):
369
+ """Update scopes for a specific authorization."""
370
+ print(f"🔧 Updating scopes for authorization: {auth_id}")
371
+ print(f"New scopcdscsdes: {scopes}")
372
+
373
+ result = self.api_client.update_authorization_scopes(auth_id, scopes)
374
+ from pprint import pprint
375
+ pprint(result)
376
+
377
+ def _drop_agent_authorizations(self, agent_id):
378
+ """Drop all authorizations for an agent space agent."""
379
+ print(f"🗑️ Dropping all authorizations for agent: {agent_id}")
380
+ try:
381
+ result = self.api_client.drop_agent_authorizations(agent_id)
382
+ from pprint import pprint
383
+ pprint(result)
384
+ except Exception as e:
385
+ raise
386
+ print(f"❌ Error dropping agent authorizations: {e}")
387
+
342
388
  if __name__ == "__main__":
343
389
  CLIRunner().run()
@@ -0,0 +1,48 @@
1
+ """
2
+ Scrollable agent list with checkboxes for mass selection and actions.
3
+ """
4
+ import tkinter as tk
5
+ from tkinter import ttk, messagebox
6
+
7
+ class AgentCheckboxList(tk.Frame):
8
+ def __init__(self, master, agents, on_mass_action):
9
+ super().__init__(master)
10
+ self.agents = agents
11
+ self.on_mass_action = on_mass_action
12
+ self.vars = {}
13
+ self._setup_ui()
14
+
15
+ def _setup_ui(self):
16
+ canvas = tk.Canvas(self)
17
+ scrollbar = ttk.Scrollbar(self, orient="vertical", command=canvas.yview)
18
+ self.scrollable_frame = tk.Frame(canvas)
19
+
20
+ self.scrollable_frame.bind(
21
+ "<Configure>",
22
+ lambda e: canvas.configure(scrollregion=canvas.bbox("all"))
23
+ )
24
+
25
+ canvas.create_window((0, 0), window=self.scrollable_frame, anchor="nw")
26
+ canvas.configure(yscrollcommand=scrollbar.set, height=300)
27
+
28
+ canvas.pack(side="left", fill="both", expand=True)
29
+ scrollbar.pack(side="right", fill="y")
30
+
31
+ for agent in self.agents:
32
+ var = tk.BooleanVar()
33
+ self.vars[agent["id"]] = var
34
+ cb = tk.Checkbutton(self.scrollable_frame, text=f"{agent.get('display_name', agent['id'])}", variable=var)
35
+ cb.pack(anchor="w", padx=4, pady=2)
36
+
37
+ self.action_btn = ttk.Button(self, text="Drop Authorizations for Checked Agents", command=self._do_mass_action)
38
+ self.action_btn.pack(fill="x", pady=8)
39
+
40
+ def get_checked_agent_ids(self):
41
+ return [aid for aid, var in self.vars.items() if var.get()]
42
+
43
+ def _do_mass_action(self):
44
+ checked = self.get_checked_agent_ids()
45
+ if not checked:
46
+ messagebox.showinfo("No agents selected", "Please check agents to drop authorizations.")
47
+ return
48
+ self.on_mass_action(checked)