pygeai 0.6.0b11__py3-none-any.whl → 0.6.0b13__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.
- pygeai/_docs/source/content/ai_lab/cli.rst +4 -4
- pygeai/_docs/source/content/ai_lab/models.rst +169 -35
- pygeai/_docs/source/content/ai_lab/runner.rst +2 -2
- pygeai/_docs/source/content/ai_lab/spec.rst +9 -9
- pygeai/_docs/source/content/ai_lab/usage.rst +34 -34
- pygeai/_docs/source/content/ai_lab.rst +1 -1
- pygeai/_docs/source/content/analytics.rst +598 -0
- pygeai/_docs/source/content/api_reference/chat.rst +428 -2
- pygeai/_docs/source/content/api_reference/embeddings.rst +1 -1
- pygeai/_docs/source/content/api_reference/project.rst +184 -0
- pygeai/_docs/source/content/api_reference/rag.rst +2 -2
- pygeai/_docs/source/content/authentication.rst +295 -0
- pygeai/_docs/source/content/cli.rst +79 -2
- pygeai/_docs/source/content/debugger.rst +1 -1
- pygeai/_docs/source/content/migration.rst +19 -2
- pygeai/_docs/source/index.rst +2 -0
- pygeai/_docs/source/pygeai.analytics.rst +53 -0
- pygeai/_docs/source/pygeai.cli.commands.rst +8 -0
- pygeai/_docs/source/pygeai.rst +1 -0
- pygeai/_docs/source/pygeai.tests.analytics.rst +45 -0
- pygeai/_docs/source/pygeai.tests.auth.rst +8 -0
- pygeai/_docs/source/pygeai.tests.rst +1 -1
- pygeai/analytics/__init__.py +0 -0
- pygeai/analytics/clients.py +505 -0
- pygeai/analytics/endpoints.py +35 -0
- pygeai/analytics/managers.py +606 -0
- pygeai/analytics/mappers.py +207 -0
- pygeai/analytics/responses.py +240 -0
- pygeai/assistant/managers.py +1 -1
- pygeai/chat/managers.py +1 -1
- pygeai/cli/commands/analytics.py +525 -0
- pygeai/cli/commands/base.py +16 -0
- pygeai/cli/commands/common.py +28 -24
- pygeai/cli/commands/migrate.py +75 -6
- pygeai/cli/commands/organization.py +265 -0
- pygeai/cli/commands/validators.py +144 -1
- pygeai/cli/error_handler.py +41 -6
- pygeai/cli/geai.py +106 -18
- pygeai/cli/parsers.py +75 -31
- pygeai/cli/texts/help.py +75 -6
- pygeai/core/base/clients.py +18 -4
- pygeai/core/base/session.py +59 -7
- pygeai/core/common/config.py +25 -2
- pygeai/core/common/exceptions.py +64 -1
- pygeai/core/embeddings/managers.py +1 -1
- pygeai/core/files/managers.py +1 -1
- pygeai/core/rerank/managers.py +1 -1
- pygeai/core/services/rest.py +20 -2
- pygeai/evaluation/clients.py +5 -3
- pygeai/lab/agents/clients.py +3 -3
- pygeai/lab/agents/endpoints.py +2 -2
- pygeai/lab/agents/mappers.py +50 -2
- pygeai/lab/clients.py +5 -2
- pygeai/lab/managers.py +8 -10
- pygeai/lab/models.py +70 -2
- pygeai/lab/tools/clients.py +1 -59
- pygeai/migration/__init__.py +3 -1
- pygeai/migration/strategies.py +72 -3
- pygeai/organization/clients.py +110 -1
- pygeai/organization/endpoints.py +11 -7
- pygeai/organization/limits/managers.py +1 -1
- pygeai/organization/managers.py +135 -3
- pygeai/organization/mappers.py +28 -2
- pygeai/organization/responses.py +11 -1
- pygeai/tests/analytics/__init__.py +0 -0
- pygeai/tests/analytics/test_clients.py +86 -0
- pygeai/tests/analytics/test_managers.py +94 -0
- pygeai/tests/analytics/test_mappers.py +84 -0
- pygeai/tests/analytics/test_responses.py +73 -0
- pygeai/tests/auth/test_oauth.py +172 -0
- pygeai/tests/cli/commands/test_migrate.py +14 -1
- pygeai/tests/cli/commands/test_organization.py +69 -1
- pygeai/tests/cli/test_error_handler.py +4 -4
- pygeai/tests/cli/test_geai_driver.py +1 -1
- pygeai/tests/lab/agents/test_mappers.py +128 -1
- pygeai/tests/lab/test_models.py +2 -0
- pygeai/tests/lab/tools/test_clients.py +2 -31
- pygeai/tests/organization/test_clients.py +180 -1
- pygeai/tests/organization/test_managers.py +40 -0
- pygeai/tests/snippets/analytics/__init__.py +0 -0
- pygeai/tests/snippets/analytics/get_agent_usage_per_user.py +16 -0
- pygeai/tests/snippets/analytics/get_agents_created_and_modified.py +11 -0
- pygeai/tests/snippets/analytics/get_average_cost_per_request.py +10 -0
- pygeai/tests/snippets/analytics/get_overall_error_rate.py +10 -0
- pygeai/tests/snippets/analytics/get_top_10_agents_by_requests.py +12 -0
- pygeai/tests/snippets/analytics/get_total_active_users.py +10 -0
- pygeai/tests/snippets/analytics/get_total_cost.py +10 -0
- pygeai/tests/snippets/analytics/get_total_requests_per_day.py +12 -0
- pygeai/tests/snippets/analytics/get_total_tokens.py +12 -0
- pygeai/tests/snippets/chat/get_response_complete_example.py +67 -0
- pygeai/tests/snippets/chat/get_response_with_instructions.py +19 -0
- pygeai/tests/snippets/chat/get_response_with_metadata.py +24 -0
- pygeai/tests/snippets/chat/get_response_with_parallel_tools.py +58 -0
- pygeai/tests/snippets/chat/get_response_with_reasoning.py +21 -0
- pygeai/tests/snippets/chat/get_response_with_store.py +38 -0
- pygeai/tests/snippets/chat/get_response_with_truncation.py +24 -0
- pygeai/tests/snippets/lab/agents/create_agent_with_permissions.py +39 -0
- pygeai/tests/snippets/lab/agents/create_agent_with_properties.py +46 -0
- pygeai/tests/snippets/lab/agents/get_agent_with_new_fields.py +62 -0
- pygeai/tests/snippets/lab/agents/update_agent_properties.py +50 -0
- pygeai/tests/snippets/organization/add_project_member.py +10 -0
- pygeai/tests/snippets/organization/add_project_member_batch.py +44 -0
- {pygeai-0.6.0b11.dist-info → pygeai-0.6.0b13.dist-info}/METADATA +1 -1
- {pygeai-0.6.0b11.dist-info → pygeai-0.6.0b13.dist-info}/RECORD +108 -98
- pygeai/_docs/source/pygeai.tests.snippets.assistants.data_analyst.rst +0 -37
- pygeai/_docs/source/pygeai.tests.snippets.assistants.rag.rst +0 -85
- pygeai/_docs/source/pygeai.tests.snippets.assistants.rst +0 -78
- pygeai/_docs/source/pygeai.tests.snippets.auth.rst +0 -10
- pygeai/_docs/source/pygeai.tests.snippets.chat.rst +0 -125
- pygeai/_docs/source/pygeai.tests.snippets.dbg.rst +0 -45
- pygeai/_docs/source/pygeai.tests.snippets.embeddings.rst +0 -61
- pygeai/_docs/source/pygeai.tests.snippets.evaluation.dataset.rst +0 -197
- pygeai/_docs/source/pygeai.tests.snippets.evaluation.plan.rst +0 -133
- pygeai/_docs/source/pygeai.tests.snippets.evaluation.result.rst +0 -37
- pygeai/_docs/source/pygeai.tests.snippets.evaluation.rst +0 -20
- pygeai/_docs/source/pygeai.tests.snippets.extras.rst +0 -37
- pygeai/_docs/source/pygeai.tests.snippets.files.rst +0 -53
- pygeai/_docs/source/pygeai.tests.snippets.gam.rst +0 -21
- pygeai/_docs/source/pygeai.tests.snippets.lab.agents.rst +0 -93
- pygeai/_docs/source/pygeai.tests.snippets.lab.processes.jobs.rst +0 -21
- pygeai/_docs/source/pygeai.tests.snippets.lab.processes.kbs.rst +0 -45
- pygeai/_docs/source/pygeai.tests.snippets.lab.processes.rst +0 -46
- pygeai/_docs/source/pygeai.tests.snippets.lab.rst +0 -82
- pygeai/_docs/source/pygeai.tests.snippets.lab.samples.rst +0 -21
- pygeai/_docs/source/pygeai.tests.snippets.lab.strategies.rst +0 -45
- pygeai/_docs/source/pygeai.tests.snippets.lab.tools.rst +0 -85
- pygeai/_docs/source/pygeai.tests.snippets.lab.use_cases.rst +0 -117
- pygeai/_docs/source/pygeai.tests.snippets.migrate.rst +0 -10
- pygeai/_docs/source/pygeai.tests.snippets.organization.rst +0 -109
- pygeai/_docs/source/pygeai.tests.snippets.rag.rst +0 -85
- pygeai/_docs/source/pygeai.tests.snippets.rerank.rst +0 -21
- pygeai/_docs/source/pygeai.tests.snippets.rst +0 -32
- pygeai/_docs/source/pygeai.tests.snippets.secrets.rst +0 -10
- pygeai/_docs/source/pygeai.tests.snippets.usage_limit.rst +0 -77
- {pygeai-0.6.0b11.dist-info → pygeai-0.6.0b13.dist-info}/WHEEL +0 -0
- {pygeai-0.6.0b11.dist-info → pygeai-0.6.0b13.dist-info}/entry_points.txt +0 -0
- {pygeai-0.6.0b11.dist-info → pygeai-0.6.0b13.dist-info}/licenses/LICENSE +0 -0
- {pygeai-0.6.0b11.dist-info → pygeai-0.6.0b13.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,525 @@
|
|
|
1
|
+
from pygeai.cli.commands import Command, Option, ArgumentsEnum
|
|
2
|
+
from pygeai.cli.commands.builders import build_help_text
|
|
3
|
+
from pygeai.cli.texts.help import ANALYTICS_HELP_TEXT
|
|
4
|
+
from pygeai.core.common.exceptions import MissingRequirementException
|
|
5
|
+
from pygeai.core.utils.console import Console
|
|
6
|
+
from pygeai.analytics.managers import AnalyticsManager
|
|
7
|
+
import csv
|
|
8
|
+
from datetime import datetime, timedelta
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def show_help():
|
|
12
|
+
help_text = build_help_text(analytics_commands, ANALYTICS_HELP_TEXT)
|
|
13
|
+
Console.write_stdout(help_text)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def get_default_date_range():
|
|
17
|
+
today = datetime.now()
|
|
18
|
+
first_day_current_month = today.replace(day=1)
|
|
19
|
+
last_day_last_month = first_day_current_month - timedelta(days=1)
|
|
20
|
+
first_day_last_month = last_day_last_month.replace(day=1)
|
|
21
|
+
|
|
22
|
+
start_date = first_day_last_month.strftime('%Y-%m-%d')
|
|
23
|
+
end_date = last_day_last_month.strftime('%Y-%m-%d')
|
|
24
|
+
|
|
25
|
+
return start_date, end_date
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
START_DATE_OPTION = Option(
|
|
29
|
+
"start_date",
|
|
30
|
+
["--start-date", "-s"],
|
|
31
|
+
"Start date in YYYY-MM-DD format (defaults to first day of last month)",
|
|
32
|
+
True
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
END_DATE_OPTION = Option(
|
|
36
|
+
"end_date",
|
|
37
|
+
["--end-date", "-e"],
|
|
38
|
+
"End date in YYYY-MM-DD format (defaults to last day of last month)",
|
|
39
|
+
True
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
AGENT_NAME_OPTION = Option(
|
|
43
|
+
"agent_name",
|
|
44
|
+
["--agent-name", "-a"],
|
|
45
|
+
"Name of the agent to filter results",
|
|
46
|
+
True
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
CSV_EXPORT_OPTION = Option(
|
|
50
|
+
"csv_file",
|
|
51
|
+
["--csv", "-c"],
|
|
52
|
+
"Export results to CSV file",
|
|
53
|
+
True
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def get_agents_created_and_modified(option_list: list):
|
|
58
|
+
start_date = None
|
|
59
|
+
end_date = None
|
|
60
|
+
for option_flag, option_arg in option_list:
|
|
61
|
+
if option_flag.name == "start_date":
|
|
62
|
+
start_date = option_arg
|
|
63
|
+
if option_flag.name == "end_date":
|
|
64
|
+
end_date = option_arg
|
|
65
|
+
|
|
66
|
+
if not (start_date and end_date):
|
|
67
|
+
raise MissingRequirementException("Cannot retrieve agents created and modified without start-date and end-date")
|
|
68
|
+
|
|
69
|
+
manager = AnalyticsManager()
|
|
70
|
+
result = manager.get_agents_created_and_modified(start_date, end_date)
|
|
71
|
+
Console.write_stdout(f"Agents created and modified:\n Created: {result.createdAgents}\n Modified: {result.modifiedAgents}")
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
agents_created_options = [START_DATE_OPTION, END_DATE_OPTION]
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def get_total_requests_per_day(option_list: list):
|
|
78
|
+
start_date = None
|
|
79
|
+
end_date = None
|
|
80
|
+
agent_name = None
|
|
81
|
+
for option_flag, option_arg in option_list:
|
|
82
|
+
if option_flag.name == "start_date":
|
|
83
|
+
start_date = option_arg
|
|
84
|
+
if option_flag.name == "end_date":
|
|
85
|
+
end_date = option_arg
|
|
86
|
+
if option_flag.name == "agent_name":
|
|
87
|
+
agent_name = option_arg
|
|
88
|
+
|
|
89
|
+
if not (start_date and end_date):
|
|
90
|
+
raise MissingRequirementException("Cannot retrieve total requests per day without start-date and end-date")
|
|
91
|
+
|
|
92
|
+
manager = AnalyticsManager()
|
|
93
|
+
result = manager.get_total_requests_per_day(start_date, end_date, agent_name)
|
|
94
|
+
Console.write_stdout(f"Total requests per day:")
|
|
95
|
+
for item in result.requestsPerDay:
|
|
96
|
+
Console.write_stdout(f" {item.date}: {item.totalRequests} requests ({item.totalRequestsWithError} errors)")
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
total_requests_per_day_options = [START_DATE_OPTION, END_DATE_OPTION, AGENT_NAME_OPTION]
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def get_total_cost(option_list: list):
|
|
103
|
+
start_date = None
|
|
104
|
+
end_date = None
|
|
105
|
+
for option_flag, option_arg in option_list:
|
|
106
|
+
if option_flag.name == "start_date":
|
|
107
|
+
start_date = option_arg
|
|
108
|
+
if option_flag.name == "end_date":
|
|
109
|
+
end_date = option_arg
|
|
110
|
+
|
|
111
|
+
if not (start_date and end_date):
|
|
112
|
+
raise MissingRequirementException("Cannot retrieve total cost without start-date and end-date")
|
|
113
|
+
|
|
114
|
+
manager = AnalyticsManager()
|
|
115
|
+
result = manager.get_total_cost(start_date, end_date)
|
|
116
|
+
Console.write_stdout(f"Total cost: ${result.totalCost:.2f}")
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
total_cost_options = [START_DATE_OPTION, END_DATE_OPTION]
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def get_average_cost_per_request(option_list: list):
|
|
123
|
+
start_date = None
|
|
124
|
+
end_date = None
|
|
125
|
+
for option_flag, option_arg in option_list:
|
|
126
|
+
if option_flag.name == "start_date":
|
|
127
|
+
start_date = option_arg
|
|
128
|
+
if option_flag.name == "end_date":
|
|
129
|
+
end_date = option_arg
|
|
130
|
+
|
|
131
|
+
if not (start_date and end_date):
|
|
132
|
+
raise MissingRequirementException("Cannot retrieve average cost per request without start-date and end-date")
|
|
133
|
+
|
|
134
|
+
manager = AnalyticsManager()
|
|
135
|
+
result = manager.get_average_cost_per_request(start_date, end_date)
|
|
136
|
+
Console.write_stdout(f"Average cost per request: ${result.averageCost:.4f}")
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
average_cost_per_request_options = [START_DATE_OPTION, END_DATE_OPTION]
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def get_total_tokens(option_list: list):
|
|
143
|
+
start_date = None
|
|
144
|
+
end_date = None
|
|
145
|
+
for option_flag, option_arg in option_list:
|
|
146
|
+
if option_flag.name == "start_date":
|
|
147
|
+
start_date = option_arg
|
|
148
|
+
if option_flag.name == "end_date":
|
|
149
|
+
end_date = option_arg
|
|
150
|
+
|
|
151
|
+
if not (start_date and end_date):
|
|
152
|
+
raise MissingRequirementException("Cannot retrieve total tokens without start-date and end-date")
|
|
153
|
+
|
|
154
|
+
manager = AnalyticsManager()
|
|
155
|
+
result = manager.get_total_tokens(start_date, end_date)
|
|
156
|
+
Console.write_stdout(f"Total tokens:\n Input: {result.totalInputTokens}\n Output: {result.totalOutputTokens}\n Total: {result.totalTokens}")
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
total_tokens_options = [START_DATE_OPTION, END_DATE_OPTION]
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def get_overall_error_rate(option_list: list):
|
|
163
|
+
start_date = None
|
|
164
|
+
end_date = None
|
|
165
|
+
for option_flag, option_arg in option_list:
|
|
166
|
+
if option_flag.name == "start_date":
|
|
167
|
+
start_date = option_arg
|
|
168
|
+
if option_flag.name == "end_date":
|
|
169
|
+
end_date = option_arg
|
|
170
|
+
|
|
171
|
+
if not (start_date and end_date):
|
|
172
|
+
raise MissingRequirementException("Cannot retrieve overall error rate without start-date and end-date")
|
|
173
|
+
|
|
174
|
+
manager = AnalyticsManager()
|
|
175
|
+
result = manager.get_overall_error_rate(start_date, end_date)
|
|
176
|
+
Console.write_stdout(f"Overall error rate: {result.errorRate:.2%}")
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
error_rate_options = [START_DATE_OPTION, END_DATE_OPTION]
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
def get_top_agents_by_requests(option_list: list):
|
|
183
|
+
start_date = None
|
|
184
|
+
end_date = None
|
|
185
|
+
for option_flag, option_arg in option_list:
|
|
186
|
+
if option_flag.name == "start_date":
|
|
187
|
+
start_date = option_arg
|
|
188
|
+
if option_flag.name == "end_date":
|
|
189
|
+
end_date = option_arg
|
|
190
|
+
|
|
191
|
+
if not (start_date and end_date):
|
|
192
|
+
raise MissingRequirementException("Cannot retrieve top agents by requests without start-date and end-date")
|
|
193
|
+
|
|
194
|
+
manager = AnalyticsManager()
|
|
195
|
+
result = manager.get_top_10_agents_by_requests(start_date, end_date)
|
|
196
|
+
Console.write_stdout("Top 10 agents by requests:")
|
|
197
|
+
for idx, agent in enumerate(result.topAgents, 1):
|
|
198
|
+
Console.write_stdout(f" {idx}. {agent.agentName}: {agent.totalRequests} requests")
|
|
199
|
+
|
|
200
|
+
|
|
201
|
+
top_agents_options = [START_DATE_OPTION, END_DATE_OPTION]
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def get_total_active_users(option_list: list):
|
|
205
|
+
start_date = None
|
|
206
|
+
end_date = None
|
|
207
|
+
for option_flag, option_arg in option_list:
|
|
208
|
+
if option_flag.name == "start_date":
|
|
209
|
+
start_date = option_arg
|
|
210
|
+
if option_flag.name == "end_date":
|
|
211
|
+
end_date = option_arg
|
|
212
|
+
|
|
213
|
+
if not (start_date and end_date):
|
|
214
|
+
raise MissingRequirementException("Cannot retrieve total active users without start-date and end-date")
|
|
215
|
+
|
|
216
|
+
manager = AnalyticsManager()
|
|
217
|
+
result = manager.get_total_active_users(start_date, end_date)
|
|
218
|
+
Console.write_stdout(f"Total active users: {result.totalActiveUsers}")
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
active_users_options = [START_DATE_OPTION, END_DATE_OPTION]
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
def get_full_report(option_list: list):
|
|
225
|
+
start_date = None
|
|
226
|
+
end_date = None
|
|
227
|
+
csv_file = None
|
|
228
|
+
for option_flag, option_arg in option_list:
|
|
229
|
+
if option_flag.name == "start_date":
|
|
230
|
+
start_date = option_arg
|
|
231
|
+
if option_flag.name == "end_date":
|
|
232
|
+
end_date = option_arg
|
|
233
|
+
if option_flag.name == "csv_file":
|
|
234
|
+
csv_file = option_arg
|
|
235
|
+
|
|
236
|
+
if not start_date or not end_date:
|
|
237
|
+
start_date, end_date = get_default_date_range()
|
|
238
|
+
Console.write_stdout(f"Using default date range: {start_date} to {end_date}")
|
|
239
|
+
|
|
240
|
+
manager = AnalyticsManager()
|
|
241
|
+
|
|
242
|
+
Console.write_stdout(f"\n{'='*80}")
|
|
243
|
+
Console.write_stdout(f"ANALYTICS FULL REPORT - Period: {start_date} to {end_date}")
|
|
244
|
+
Console.write_stdout(f"{'='*80}\n")
|
|
245
|
+
|
|
246
|
+
report_data = {}
|
|
247
|
+
|
|
248
|
+
try:
|
|
249
|
+
Console.write_stdout("LAB METRICS")
|
|
250
|
+
Console.write_stdout("-" * 80)
|
|
251
|
+
agents_created = manager.get_agents_created_and_modified(start_date, end_date)
|
|
252
|
+
Console.write_stdout(f"Agents Created: {agents_created.createdAgents}")
|
|
253
|
+
Console.write_stdout(f"Agents Modified: {agents_created.modifiedAgents}")
|
|
254
|
+
report_data["Agents Created"] = agents_created.createdAgents
|
|
255
|
+
report_data["Agents Modified"] = agents_created.modifiedAgents
|
|
256
|
+
except Exception as e:
|
|
257
|
+
Console.write_stdout(f"Error retrieving agents data: {e}")
|
|
258
|
+
|
|
259
|
+
try:
|
|
260
|
+
flows_created = manager.get_flows_created_and_modified(start_date, end_date)
|
|
261
|
+
Console.write_stdout(f"Flows Created: {flows_created.createdFlows}")
|
|
262
|
+
Console.write_stdout(f"Flows Modified: {flows_created.modifiedFlows}")
|
|
263
|
+
report_data["Flows Created"] = flows_created.createdFlows
|
|
264
|
+
report_data["Flows Modified"] = flows_created.modifiedFlows
|
|
265
|
+
except Exception as e:
|
|
266
|
+
Console.write_stdout(f"Error retrieving flows data: {e}")
|
|
267
|
+
|
|
268
|
+
try:
|
|
269
|
+
processes_created = manager.get_processes_created_and_modified(start_date, end_date)
|
|
270
|
+
Console.write_stdout(f"Processes Created: {processes_created.createdProcesses}")
|
|
271
|
+
Console.write_stdout(f"Processes Modified: {processes_created.modifiedProcesses}")
|
|
272
|
+
report_data["Processes Created"] = processes_created.createdProcesses
|
|
273
|
+
report_data["Processes Modified"] = processes_created.modifiedProcesses
|
|
274
|
+
except Exception as e:
|
|
275
|
+
Console.write_stdout(f"Error retrieving processes data: {e}")
|
|
276
|
+
|
|
277
|
+
Console.write_stdout("\nREQUEST METRICS")
|
|
278
|
+
Console.write_stdout("-" * 80)
|
|
279
|
+
|
|
280
|
+
try:
|
|
281
|
+
total_requests = manager.get_total_requests(start_date, end_date)
|
|
282
|
+
Console.write_stdout(f"Total Requests: {total_requests.totalRequests}")
|
|
283
|
+
report_data["Total Requests"] = total_requests.totalRequests
|
|
284
|
+
except Exception as e:
|
|
285
|
+
Console.write_stdout(f"Error retrieving total requests: {e}")
|
|
286
|
+
|
|
287
|
+
try:
|
|
288
|
+
total_errors = manager.get_total_requests_with_error(start_date, end_date)
|
|
289
|
+
Console.write_stdout(f"Total Requests with Error: {total_errors.totalRequestsWithError}")
|
|
290
|
+
report_data["Total Requests with Error"] = total_errors.totalRequestsWithError
|
|
291
|
+
except Exception as e:
|
|
292
|
+
Console.write_stdout(f"Error retrieving error requests: {e}")
|
|
293
|
+
|
|
294
|
+
try:
|
|
295
|
+
error_rate = manager.get_overall_error_rate(start_date, end_date)
|
|
296
|
+
Console.write_stdout(f"Overall Error Rate: {error_rate.errorRate:.2%}")
|
|
297
|
+
report_data["Overall Error Rate (%)"] = f"{error_rate.errorRate:.2%}"
|
|
298
|
+
except Exception as e:
|
|
299
|
+
Console.write_stdout(f"Error retrieving error rate: {e}")
|
|
300
|
+
|
|
301
|
+
try:
|
|
302
|
+
avg_request_time = manager.get_average_request_time(start_date, end_date)
|
|
303
|
+
Console.write_stdout(f"Average Request Time: {avg_request_time.averageTime:.2f} ms")
|
|
304
|
+
report_data["Average Request Time (ms)"] = f"{avg_request_time.averageTime:.2f}"
|
|
305
|
+
except Exception as e:
|
|
306
|
+
Console.write_stdout(f"Error retrieving average request time: {e}")
|
|
307
|
+
|
|
308
|
+
Console.write_stdout("\nCOST METRICS")
|
|
309
|
+
Console.write_stdout("-" * 80)
|
|
310
|
+
|
|
311
|
+
try:
|
|
312
|
+
total_cost = manager.get_total_cost(start_date, end_date)
|
|
313
|
+
Console.write_stdout(f"Total Cost: ${total_cost.totalCost:.2f}")
|
|
314
|
+
report_data["Total Cost (USD)"] = f"{total_cost.totalCost:.2f}"
|
|
315
|
+
except Exception as e:
|
|
316
|
+
Console.write_stdout(f"Error retrieving total cost: {e}")
|
|
317
|
+
|
|
318
|
+
try:
|
|
319
|
+
avg_cost = manager.get_average_cost_per_request(start_date, end_date)
|
|
320
|
+
Console.write_stdout(f"Average Cost per Request: ${avg_cost.averageCost:.4f}")
|
|
321
|
+
report_data["Average Cost per Request (USD)"] = f"{avg_cost.averageCost:.4f}"
|
|
322
|
+
except Exception as e:
|
|
323
|
+
Console.write_stdout(f"Error retrieving average cost: {e}")
|
|
324
|
+
|
|
325
|
+
Console.write_stdout("\nTOKEN METRICS")
|
|
326
|
+
Console.write_stdout("-" * 80)
|
|
327
|
+
|
|
328
|
+
try:
|
|
329
|
+
total_tokens = manager.get_total_tokens(start_date, end_date)
|
|
330
|
+
Console.write_stdout(f"Total Input Tokens: {total_tokens.totalInputTokens}")
|
|
331
|
+
Console.write_stdout(f"Total Output Tokens: {total_tokens.totalOutputTokens}")
|
|
332
|
+
Console.write_stdout(f"Total Tokens: {total_tokens.totalTokens}")
|
|
333
|
+
report_data["Total Input Tokens"] = total_tokens.totalInputTokens
|
|
334
|
+
report_data["Total Output Tokens"] = total_tokens.totalOutputTokens
|
|
335
|
+
report_data["Total Tokens"] = total_tokens.totalTokens
|
|
336
|
+
except Exception as e:
|
|
337
|
+
Console.write_stdout(f"Error retrieving token data: {e}")
|
|
338
|
+
|
|
339
|
+
try:
|
|
340
|
+
avg_tokens = manager.get_average_tokens_per_request(start_date, end_date)
|
|
341
|
+
Console.write_stdout(f"Average Input Tokens per Request: {avg_tokens.averageInputTokens:.2f}")
|
|
342
|
+
Console.write_stdout(f"Average Output Tokens per Request: {avg_tokens.averageOutputTokens:.2f}")
|
|
343
|
+
Console.write_stdout(f"Average Total Tokens per Request: {avg_tokens.averageTotalTokens:.2f}")
|
|
344
|
+
report_data["Average Input Tokens per Request"] = f"{avg_tokens.averageInputTokens:.2f}"
|
|
345
|
+
report_data["Average Output Tokens per Request"] = f"{avg_tokens.averageOutputTokens:.2f}"
|
|
346
|
+
report_data["Average Total Tokens per Request"] = f"{avg_tokens.averageTotalTokens:.2f}"
|
|
347
|
+
except Exception as e:
|
|
348
|
+
Console.write_stdout(f"Error retrieving average tokens: {e}")
|
|
349
|
+
|
|
350
|
+
Console.write_stdout("\nUSER & AGENT METRICS")
|
|
351
|
+
Console.write_stdout("-" * 80)
|
|
352
|
+
|
|
353
|
+
try:
|
|
354
|
+
active_users = manager.get_total_active_users(start_date, end_date)
|
|
355
|
+
Console.write_stdout(f"Total Active Users: {active_users.totalActiveUsers}")
|
|
356
|
+
report_data["Total Active Users"] = active_users.totalActiveUsers
|
|
357
|
+
except Exception as e:
|
|
358
|
+
Console.write_stdout(f"Error retrieving active users: {e}")
|
|
359
|
+
|
|
360
|
+
try:
|
|
361
|
+
active_agents = manager.get_total_active_agents(start_date, end_date)
|
|
362
|
+
Console.write_stdout(f"Total Active Agents: {active_agents.totalActiveAgents}")
|
|
363
|
+
report_data["Total Active Agents"] = active_agents.totalActiveAgents
|
|
364
|
+
except Exception as e:
|
|
365
|
+
Console.write_stdout(f"Error retrieving active agents: {e}")
|
|
366
|
+
|
|
367
|
+
try:
|
|
368
|
+
active_projects = manager.get_total_active_projects(start_date, end_date)
|
|
369
|
+
Console.write_stdout(f"Total Active Projects: {active_projects.totalActiveProjects}")
|
|
370
|
+
report_data["Total Active Projects"] = active_projects.totalActiveProjects
|
|
371
|
+
except Exception as e:
|
|
372
|
+
Console.write_stdout(f"Error retrieving active projects: {e}")
|
|
373
|
+
|
|
374
|
+
Console.write_stdout("\nTOP 10 AGENTS BY REQUESTS")
|
|
375
|
+
Console.write_stdout("-" * 80)
|
|
376
|
+
|
|
377
|
+
try:
|
|
378
|
+
top_agents_requests = manager.get_top_10_agents_by_requests(start_date, end_date)
|
|
379
|
+
for idx, agent in enumerate(top_agents_requests.topAgents, 1):
|
|
380
|
+
Console.write_stdout(f"{idx}. {agent.agentName}: {agent.totalRequests} requests")
|
|
381
|
+
except Exception as e:
|
|
382
|
+
Console.write_stdout(f"Error retrieving top agents by requests: {e}")
|
|
383
|
+
|
|
384
|
+
Console.write_stdout("\nTOP 10 AGENTS BY TOKENS")
|
|
385
|
+
Console.write_stdout("-" * 80)
|
|
386
|
+
|
|
387
|
+
try:
|
|
388
|
+
top_agents_tokens = manager.get_top_10_agents_by_tokens(start_date, end_date)
|
|
389
|
+
for idx, agent in enumerate(top_agents_tokens.topAgents, 1):
|
|
390
|
+
Console.write_stdout(f"{idx}. {agent.agentName}: {agent.totalTokens} tokens")
|
|
391
|
+
except Exception as e:
|
|
392
|
+
Console.write_stdout(f"Error retrieving top agents by tokens: {e}")
|
|
393
|
+
|
|
394
|
+
Console.write_stdout("\nTOP 10 USERS BY REQUESTS")
|
|
395
|
+
Console.write_stdout("-" * 80)
|
|
396
|
+
|
|
397
|
+
try:
|
|
398
|
+
top_users_requests = manager.get_top_10_users_by_requests(start_date, end_date)
|
|
399
|
+
for idx, user in enumerate(top_users_requests.topUsers, 1):
|
|
400
|
+
Console.write_stdout(f"{idx}. {user.userEmail}: {user.totalRequests} requests")
|
|
401
|
+
except Exception as e:
|
|
402
|
+
Console.write_stdout(f"Error retrieving top users by requests: {e}")
|
|
403
|
+
|
|
404
|
+
Console.write_stdout("\nTOP 10 USERS BY COST")
|
|
405
|
+
Console.write_stdout("-" * 80)
|
|
406
|
+
|
|
407
|
+
try:
|
|
408
|
+
top_users_cost = manager.get_top_10_users_by_cost(start_date, end_date)
|
|
409
|
+
for idx, user in enumerate(top_users_cost.topUsers, 1):
|
|
410
|
+
Console.write_stdout(f"{idx}. {user.userEmail}: ${user.totalCost:.2f}")
|
|
411
|
+
except Exception as e:
|
|
412
|
+
Console.write_stdout(f"Error retrieving top users by cost: {e}")
|
|
413
|
+
|
|
414
|
+
Console.write_stdout(f"\n{'='*80}\n")
|
|
415
|
+
|
|
416
|
+
if csv_file:
|
|
417
|
+
try:
|
|
418
|
+
with open(csv_file, 'w', newline='') as f:
|
|
419
|
+
writer = csv.writer(f)
|
|
420
|
+
writer.writerow(['Metric', 'Value'])
|
|
421
|
+
writer.writerow(['Report Period', f"{start_date} to {end_date}"])
|
|
422
|
+
writer.writerow(['Generated At', datetime.now().strftime('%Y-%m-%d %H:%M:%S')])
|
|
423
|
+
writer.writerow([])
|
|
424
|
+
for key, value in report_data.items():
|
|
425
|
+
writer.writerow([key, value])
|
|
426
|
+
Console.write_stdout(f"Report exported to: {csv_file}")
|
|
427
|
+
except Exception as e:
|
|
428
|
+
Console.write_stdout(f"Error exporting to CSV: {e}")
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
full_report_options = [START_DATE_OPTION, END_DATE_OPTION, CSV_EXPORT_OPTION]
|
|
432
|
+
|
|
433
|
+
|
|
434
|
+
analytics_commands = [
|
|
435
|
+
Command(
|
|
436
|
+
"help",
|
|
437
|
+
["help", "h"],
|
|
438
|
+
"Display analytics help text",
|
|
439
|
+
show_help,
|
|
440
|
+
ArgumentsEnum.NOT_AVAILABLE,
|
|
441
|
+
[],
|
|
442
|
+
[]
|
|
443
|
+
),
|
|
444
|
+
Command(
|
|
445
|
+
"agents_created",
|
|
446
|
+
["agents-created", "ac"],
|
|
447
|
+
"Get total agents created and modified",
|
|
448
|
+
get_agents_created_and_modified,
|
|
449
|
+
ArgumentsEnum.OPTIONAL,
|
|
450
|
+
[],
|
|
451
|
+
agents_created_options
|
|
452
|
+
),
|
|
453
|
+
Command(
|
|
454
|
+
"requests_per_day",
|
|
455
|
+
["requests-per-day", "rpd"],
|
|
456
|
+
"Get total requests per day",
|
|
457
|
+
get_total_requests_per_day,
|
|
458
|
+
ArgumentsEnum.OPTIONAL,
|
|
459
|
+
[],
|
|
460
|
+
total_requests_per_day_options
|
|
461
|
+
),
|
|
462
|
+
Command(
|
|
463
|
+
"total_cost",
|
|
464
|
+
["total-cost", "tc"],
|
|
465
|
+
"Get total cost for the period",
|
|
466
|
+
get_total_cost,
|
|
467
|
+
ArgumentsEnum.OPTIONAL,
|
|
468
|
+
[],
|
|
469
|
+
total_cost_options
|
|
470
|
+
),
|
|
471
|
+
Command(
|
|
472
|
+
"average_cost",
|
|
473
|
+
["average-cost", "ac"],
|
|
474
|
+
"Get average cost per request",
|
|
475
|
+
get_average_cost_per_request,
|
|
476
|
+
ArgumentsEnum.OPTIONAL,
|
|
477
|
+
[],
|
|
478
|
+
average_cost_per_request_options
|
|
479
|
+
),
|
|
480
|
+
Command(
|
|
481
|
+
"total_tokens",
|
|
482
|
+
["total-tokens", "tt"],
|
|
483
|
+
"Get total tokens consumed",
|
|
484
|
+
get_total_tokens,
|
|
485
|
+
ArgumentsEnum.OPTIONAL,
|
|
486
|
+
[],
|
|
487
|
+
total_tokens_options
|
|
488
|
+
),
|
|
489
|
+
Command(
|
|
490
|
+
"error_rate",
|
|
491
|
+
["error-rate", "er"],
|
|
492
|
+
"Get overall error rate",
|
|
493
|
+
get_overall_error_rate,
|
|
494
|
+
ArgumentsEnum.OPTIONAL,
|
|
495
|
+
[],
|
|
496
|
+
error_rate_options
|
|
497
|
+
),
|
|
498
|
+
Command(
|
|
499
|
+
"top_agents",
|
|
500
|
+
["top-agents", "ta"],
|
|
501
|
+
"Get top 10 agents by requests",
|
|
502
|
+
get_top_agents_by_requests,
|
|
503
|
+
ArgumentsEnum.OPTIONAL,
|
|
504
|
+
[],
|
|
505
|
+
top_agents_options
|
|
506
|
+
),
|
|
507
|
+
Command(
|
|
508
|
+
"active_users",
|
|
509
|
+
["active-users", "au"],
|
|
510
|
+
"Get total active users",
|
|
511
|
+
get_total_active_users,
|
|
512
|
+
ArgumentsEnum.OPTIONAL,
|
|
513
|
+
[],
|
|
514
|
+
active_users_options
|
|
515
|
+
),
|
|
516
|
+
Command(
|
|
517
|
+
"full_report",
|
|
518
|
+
["full-report", "fr"],
|
|
519
|
+
"Get comprehensive analytics report",
|
|
520
|
+
get_full_report,
|
|
521
|
+
ArgumentsEnum.OPTIONAL,
|
|
522
|
+
[],
|
|
523
|
+
full_report_options
|
|
524
|
+
),
|
|
525
|
+
]
|
pygeai/cli/commands/base.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from pygeai.cli.commands import ArgumentsEnum, Command, Option
|
|
2
2
|
from pygeai.cli.commands.admin import admin_commands
|
|
3
|
+
from pygeai.cli.commands.analytics import analytics_commands
|
|
3
4
|
from pygeai.cli.commands.assistant import assistant_commands
|
|
4
5
|
from pygeai.cli.commands.auth import auth_commands
|
|
5
6
|
from pygeai.cli.commands.builders import build_help_text
|
|
@@ -121,6 +122,15 @@ base_commands = [
|
|
|
121
122
|
organization_commands,
|
|
122
123
|
[],
|
|
123
124
|
),
|
|
125
|
+
Command(
|
|
126
|
+
"analytics",
|
|
127
|
+
["analytics", "anl"],
|
|
128
|
+
"Invoke analytics endpoints to retrieve metrics and insights",
|
|
129
|
+
None,
|
|
130
|
+
ArgumentsEnum.REQUIRED,
|
|
131
|
+
analytics_commands,
|
|
132
|
+
[],
|
|
133
|
+
),
|
|
124
134
|
Command(
|
|
125
135
|
"assistant",
|
|
126
136
|
["assistant", "ast"],
|
|
@@ -295,4 +305,10 @@ base_options = (
|
|
|
295
305
|
"Set output file to save the command result",
|
|
296
306
|
True
|
|
297
307
|
),
|
|
308
|
+
Option(
|
|
309
|
+
"verbose",
|
|
310
|
+
["--verbose", "-v"],
|
|
311
|
+
"Enable verbose mode with detailed logging output",
|
|
312
|
+
False
|
|
313
|
+
),
|
|
298
314
|
)
|
pygeai/cli/commands/common.py
CHANGED
|
@@ -109,39 +109,43 @@ def get_messages(message_list: list):
|
|
|
109
109
|
return messages
|
|
110
110
|
|
|
111
111
|
|
|
112
|
-
def get_boolean_value(option_arg: str):
|
|
112
|
+
def get_boolean_value(option_arg: str) -> bool:
|
|
113
113
|
"""
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
114
|
+
Converts a string argument into a boolean value with flexible input formats.
|
|
115
|
+
|
|
116
|
+
:param option_arg: str - A string representation of a boolean.
|
|
117
|
+
Accepts: "0"/"1", "true"/"false", "yes"/"no", "on"/"off".
|
|
118
|
+
:return: bool - The boolean value corresponding to the input.
|
|
119
|
+
:raises WrongArgumentError: If the input is not a valid boolean representation.
|
|
120
|
+
"""
|
|
121
|
+
normalized = option_arg.lower().strip()
|
|
122
|
+
|
|
123
|
+
if normalized in ("0", "false", "no", "off"):
|
|
124
|
+
return False
|
|
125
|
+
elif normalized in ("1", "true", "yes", "on"):
|
|
126
|
+
return True
|
|
127
|
+
else:
|
|
125
128
|
raise WrongArgumentError("Possible values are 0 or 1, for off and on, respectively.")
|
|
126
129
|
|
|
127
130
|
|
|
128
|
-
def get_penalty_float_value(option_arg: str):
|
|
131
|
+
def get_penalty_float_value(option_arg: str) -> float:
|
|
129
132
|
"""
|
|
130
|
-
|
|
133
|
+
Converts a string argument into a float value representing a penalty and validates its range.
|
|
131
134
|
|
|
132
|
-
|
|
135
|
+
:param option_arg: str - A string representation of a float to be converted to a penalty value.
|
|
133
136
|
The value must be between -2.0 and 2.0 (inclusive).
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
"""
|
|
137
|
+
:return: float - The float value corresponding to the input, if valid.
|
|
138
|
+
:raises WrongArgumentError: If the input is not a valid float or if the value is outside the range [-2.0, 2.0].
|
|
139
|
+
"""
|
|
138
140
|
try:
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
141
|
+
penalty_value = float(option_arg)
|
|
142
|
+
except ValueError:
|
|
143
|
+
raise WrongArgumentError("If defined, penalty must be a number between -2.0 and 2.0")
|
|
144
|
+
|
|
145
|
+
if not (-2.0 <= penalty_value <= 2.0):
|
|
144
146
|
raise WrongArgumentError("If defined, penalty must be a number between -2.0 and 2.0")
|
|
147
|
+
|
|
148
|
+
return penalty_value
|
|
145
149
|
|
|
146
150
|
|
|
147
151
|
def _build_llm_options(
|