pygeai 0.6.0b13__py3-none-any.whl → 0.6.1__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.
Files changed (217) hide show
  1. pygeai/__init__.py +1 -2
  2. pygeai/_docs/source/content/api_reference/project.rst +392 -0
  3. pygeai/_docs/source/content/authentication.rst +130 -1
  4. pygeai/_docs/source/content/debugger.rst +327 -157
  5. pygeai/_docs/source/content/migration.rst +391 -7
  6. pygeai/_docs/source/pygeai.core.common.rst +8 -0
  7. pygeai/_docs/source/pygeai.tests.auth.rst +56 -0
  8. pygeai/_docs/source/pygeai.tests.cli.rst +8 -0
  9. pygeai/admin/clients.py +1 -3
  10. pygeai/analytics/clients.py +1 -1
  11. pygeai/assistant/clients.py +2 -7
  12. pygeai/assistant/data/clients.py +0 -8
  13. pygeai/assistant/data_analyst/clients.py +0 -2
  14. pygeai/assistant/managers.py +1 -1
  15. pygeai/assistant/rag/clients.py +0 -2
  16. pygeai/assistant/rag/mappers.py +9 -11
  17. pygeai/auth/clients.py +26 -7
  18. pygeai/auth/endpoints.py +2 -1
  19. pygeai/chat/clients.py +2 -2
  20. pygeai/chat/managers.py +1 -1
  21. pygeai/cli/commands/admin.py +13 -25
  22. pygeai/cli/commands/analytics.py +56 -88
  23. pygeai/cli/commands/assistant.py +84 -138
  24. pygeai/cli/commands/auth.py +23 -46
  25. pygeai/cli/commands/base.py +0 -1
  26. pygeai/cli/commands/chat.py +218 -209
  27. pygeai/cli/commands/common.py +5 -5
  28. pygeai/cli/commands/configuration.py +79 -29
  29. pygeai/cli/commands/docs.py +3 -4
  30. pygeai/cli/commands/embeddings.py +13 -19
  31. pygeai/cli/commands/evaluation.py +133 -344
  32. pygeai/cli/commands/feedback.py +7 -15
  33. pygeai/cli/commands/files.py +26 -53
  34. pygeai/cli/commands/gam.py +28 -69
  35. pygeai/cli/commands/lab/ai_lab.py +96 -142
  36. pygeai/cli/commands/lab/common.py +1 -1
  37. pygeai/cli/commands/lab/spec.py +12 -32
  38. pygeai/cli/commands/llm.py +9 -18
  39. pygeai/cli/commands/migrate.py +43 -99
  40. pygeai/cli/commands/organization.py +223 -196
  41. pygeai/cli/commands/rag.py +35 -58
  42. pygeai/cli/commands/rerank.py +21 -25
  43. pygeai/cli/commands/secrets.py +39 -67
  44. pygeai/cli/commands/usage_limits.py +50 -136
  45. pygeai/cli/commands/validators.py +1 -1
  46. pygeai/cli/geai.py +32 -3
  47. pygeai/cli/geai_proxy.py +6 -2
  48. pygeai/cli/install_man.py +1 -1
  49. pygeai/cli/parsers.py +1 -1
  50. pygeai/core/base/clients.py +90 -21
  51. pygeai/core/base/mappers.py +39 -55
  52. pygeai/core/base/session.py +134 -22
  53. pygeai/core/common/config.py +50 -13
  54. pygeai/core/common/constants.py +8 -0
  55. pygeai/core/common/exceptions.py +6 -0
  56. pygeai/core/embeddings/clients.py +0 -1
  57. pygeai/core/embeddings/managers.py +0 -1
  58. pygeai/core/feedback/clients.py +0 -2
  59. pygeai/core/feedback/models.py +1 -1
  60. pygeai/core/files/clients.py +0 -3
  61. pygeai/core/files/managers.py +1 -1
  62. pygeai/core/files/mappers.py +4 -5
  63. pygeai/core/llm/clients.py +0 -1
  64. pygeai/core/models.py +4 -4
  65. pygeai/core/plugins/clients.py +0 -3
  66. pygeai/core/plugins/models.py +2 -2
  67. pygeai/core/rerank/clients.py +0 -2
  68. pygeai/core/secrets/clients.py +0 -2
  69. pygeai/core/services/rest.py +80 -14
  70. pygeai/core/singleton.py +24 -0
  71. pygeai/dbg/__init__.py +2 -2
  72. pygeai/dbg/debugger.py +276 -38
  73. pygeai/evaluation/clients.py +2 -4
  74. pygeai/evaluation/dataset/clients.py +0 -1
  75. pygeai/evaluation/plan/clients.py +0 -2
  76. pygeai/evaluation/result/clients.py +0 -2
  77. pygeai/gam/clients.py +1 -3
  78. pygeai/health/clients.py +1 -3
  79. pygeai/lab/clients.py +0 -1
  80. pygeai/lab/managers.py +0 -1
  81. pygeai/lab/models.py +0 -1
  82. pygeai/lab/strategies/clients.py +1 -2
  83. pygeai/lab/tools/clients.py +2 -2
  84. pygeai/lab/tools/mappers.py +1 -1
  85. pygeai/migration/strategies.py +5 -6
  86. pygeai/migration/tools.py +1 -1
  87. pygeai/organization/clients.py +118 -12
  88. pygeai/organization/endpoints.py +1 -0
  89. pygeai/organization/limits/clients.py +4 -6
  90. pygeai/organization/limits/managers.py +1 -4
  91. pygeai/organization/managers.py +2 -2
  92. pygeai/proxy/config.py +1 -0
  93. pygeai/proxy/managers.py +6 -5
  94. pygeai/tests/admin/test_clients.py +11 -11
  95. pygeai/tests/assistants/rag/test_clients.py +1 -1
  96. pygeai/tests/assistants/rag/test_models.py +1 -2
  97. pygeai/tests/assistants/test_clients.py +1 -1
  98. pygeai/tests/assistants/test_managers.py +1 -3
  99. pygeai/tests/auth/test_cli_configuration.py +252 -0
  100. pygeai/tests/auth/test_client_initialization.py +411 -0
  101. pygeai/tests/auth/test_clients.py +29 -27
  102. pygeai/tests/auth/test_config_manager.py +305 -0
  103. pygeai/tests/auth/test_header_injection.py +294 -0
  104. pygeai/tests/auth/test_oauth.py +3 -1
  105. pygeai/tests/auth/test_session_logging.py +119 -0
  106. pygeai/tests/auth/test_session_validation.py +408 -0
  107. pygeai/tests/auth/test_singleton_reset.py +201 -0
  108. pygeai/tests/chat/test_clients.py +1 -1
  109. pygeai/tests/chat/test_iris.py +1 -1
  110. pygeai/tests/chat/test_ui.py +0 -2
  111. pygeai/tests/cli/commands/lab/test_ai_lab.py +1 -3
  112. pygeai/tests/cli/commands/lab/test_common.py +0 -1
  113. pygeai/tests/cli/commands/test_chat.py +1 -1
  114. pygeai/tests/cli/commands/test_common.py +0 -1
  115. pygeai/tests/cli/commands/test_embeddings.py +2 -2
  116. pygeai/tests/cli/commands/test_evaluation.py +1 -9
  117. pygeai/tests/cli/commands/test_llm.py +1 -1
  118. pygeai/tests/cli/commands/test_migrate.py +1 -1
  119. pygeai/tests/cli/commands/test_rerank.py +0 -1
  120. pygeai/tests/cli/commands/test_secrets.py +1 -1
  121. pygeai/tests/cli/commands/test_show_help.py +0 -1
  122. pygeai/tests/cli/commands/test_validators.py +0 -1
  123. pygeai/tests/cli/test_credentials_flag.py +312 -0
  124. pygeai/tests/cli/test_error_handler.py +0 -1
  125. pygeai/tests/core/base/test_mappers.py +2 -2
  126. pygeai/tests/core/base/test_models.py +4 -4
  127. pygeai/tests/core/common/test_config.py +2 -7
  128. pygeai/tests/core/common/test_decorators.py +0 -1
  129. pygeai/tests/core/embeddings/test_managers.py +1 -1
  130. pygeai/tests/core/feedback/test_clients.py +2 -2
  131. pygeai/tests/core/files/test_clients.py +6 -6
  132. pygeai/tests/core/files/test_models.py +0 -1
  133. pygeai/tests/core/files/test_responses.py +0 -1
  134. pygeai/tests/core/llm/test_clients.py +1 -1
  135. pygeai/tests/core/plugins/test_clients.py +4 -4
  136. pygeai/tests/core/rerank/test_mappers.py +1 -3
  137. pygeai/tests/core/secrets/test_clients.py +2 -3
  138. pygeai/tests/core/services/test_rest.py +10 -10
  139. pygeai/tests/core/utils/test_console.py +0 -1
  140. pygeai/tests/dbg/test_debugger.py +95 -8
  141. pygeai/tests/evaluation/dataset/test_clients.py +24 -27
  142. pygeai/tests/evaluation/plan/test_clients.py +16 -18
  143. pygeai/tests/evaluation/result/test_clients.py +4 -5
  144. pygeai/tests/health/test_clients.py +2 -2
  145. pygeai/tests/integration/lab/agents/test_create_agent.py +1 -3
  146. pygeai/tests/integration/lab/agents/test_get_agent.py +1 -1
  147. pygeai/tests/integration/lab/processes/test_create_process.py +2 -2
  148. pygeai/tests/integration/lab/processes/test_create_task.py +2 -3
  149. pygeai/tests/integration/lab/processes/test_delete_process.py +0 -1
  150. pygeai/tests/integration/lab/processes/test_get_process.py +2 -4
  151. pygeai/tests/integration/lab/processes/test_list_process_instances.py +1 -3
  152. pygeai/tests/integration/lab/processes/test_update_process.py +3 -9
  153. pygeai/tests/integration/lab/reasoning_strategies/test_update_reasoning_strategy.py +1 -2
  154. pygeai/tests/integration/lab/tools/test_delete_tool.py +1 -1
  155. pygeai/tests/integration/lab/tools/test_list_tools.py +1 -1
  156. pygeai/tests/integration/lab/tools/test_update_tool.py +1 -1
  157. pygeai/tests/lab/agents/test_clients.py +17 -17
  158. pygeai/tests/lab/processes/test_clients.py +67 -67
  159. pygeai/tests/lab/processes/test_mappers.py +23 -23
  160. pygeai/tests/lab/spec/test_loader.py +0 -2
  161. pygeai/tests/lab/spec/test_parsers.py +1 -2
  162. pygeai/tests/lab/strategies/test_clients.py +10 -10
  163. pygeai/tests/lab/test_managers.py +3 -5
  164. pygeai/tests/lab/test_mappers.py +1 -4
  165. pygeai/tests/lab/tools/test_clients.py +21 -21
  166. pygeai/tests/lab/tools/test_mappers.py +0 -1
  167. pygeai/tests/organization/limits/test_clients.py +33 -33
  168. pygeai/tests/organization/limits/test_managers.py +7 -7
  169. pygeai/tests/organization/test_clients.py +78 -60
  170. pygeai/tests/proxy/test_clients.py +1 -1
  171. pygeai/tests/proxy/test_integration.py +1 -4
  172. pygeai/tests/proxy/test_managers.py +1 -2
  173. pygeai/tests/proxy/test_servers.py +1 -2
  174. pygeai/tests/snippets/assistants/rag/delete_rag_assistant.py +0 -1
  175. pygeai/tests/snippets/assistants/rag/get_documents.py +0 -1
  176. pygeai/tests/snippets/assistants/rag/get_rag_assistant_data.py +0 -1
  177. pygeai/tests/snippets/chat/get_request_status.py +0 -1
  178. pygeai/tests/snippets/dbg/file_debugging.py +72 -0
  179. pygeai/tests/snippets/dbg/module_debugging.py +60 -0
  180. pygeai/tests/snippets/embeddings/cohere_example.py +2 -2
  181. pygeai/tests/snippets/embeddings/openai_base64_example.py +1 -1
  182. pygeai/tests/snippets/evaluation/dataset/complete_workflow_example.py +8 -8
  183. pygeai/tests/snippets/evaluation/plan/complete_workflow_example.py +5 -5
  184. pygeai/tests/snippets/evaluation/result/complete_workflow_example.py +3 -3
  185. pygeai/tests/snippets/lab/agentic_flow_example_1.py +1 -1
  186. pygeai/tests/snippets/lab/agentic_flow_example_2.py +3 -4
  187. pygeai/tests/snippets/lab/agents/create_agent_with_permissions.py +2 -2
  188. pygeai/tests/snippets/lab/agents/delete_agent.py +1 -2
  189. pygeai/tests/snippets/lab/agents/get_agent.py +1 -1
  190. pygeai/tests/snippets/lab/agents/get_agent_with_new_fields.py +10 -10
  191. pygeai/tests/snippets/lab/agents/get_sharing_link.py +0 -1
  192. pygeai/tests/snippets/lab/agents/list_agents.py +1 -1
  193. pygeai/tests/snippets/lab/agents/publish_agent_revision.py +0 -1
  194. pygeai/tests/snippets/lab/agents/update_agent_properties.py +1 -1
  195. pygeai/tests/snippets/lab/crud_ui.py +3 -5
  196. pygeai/tests/snippets/lab/processes/kbs/get_kb.py +0 -1
  197. pygeai/tests/snippets/lab/processes/kbs/list_kbs.py +0 -1
  198. pygeai/tests/snippets/lab/processes/list_processes.py +1 -1
  199. pygeai/tests/snippets/lab/samples/summarize_files.py +0 -3
  200. pygeai/tests/snippets/lab/strategies/get_reasoning_strategy.py +0 -1
  201. pygeai/tests/snippets/lab/strategies/list_reasoning_strategies.py +1 -1
  202. pygeai/tests/snippets/lab/tools/get_tool.py +1 -1
  203. pygeai/tests/snippets/lab/tools/publish_tool_revision.py +0 -1
  204. pygeai/tests/snippets/lab/tools/set_parameters.py +1 -2
  205. pygeai/tests/snippets/lab/use_cases/c_code_fixer_agent_flow.py +2 -3
  206. pygeai/tests/snippets/lab/use_cases/file_summarizer_example_2.py +1 -1
  207. pygeai/tests/snippets/lab/use_cases/update_cli_expert.py +0 -1
  208. pygeai/tests/snippets/lab/use_cases/update_lab_expert.py +0 -1
  209. pygeai/tests/snippets/lab/use_cases/update_web_designer.py +0 -1
  210. pygeai/tests/snippets/lab/use_cases/update_web_reader.py +0 -1
  211. pygeai/tests/snippets/migrate/orchestrator_examples.py +1 -1
  212. {pygeai-0.6.0b13.dist-info → pygeai-0.6.1.dist-info}/METADATA +32 -7
  213. {pygeai-0.6.0b13.dist-info → pygeai-0.6.1.dist-info}/RECORD +217 -206
  214. {pygeai-0.6.0b13.dist-info → pygeai-0.6.1.dist-info}/WHEEL +0 -0
  215. {pygeai-0.6.0b13.dist-info → pygeai-0.6.1.dist-info}/entry_points.txt +0 -0
  216. {pygeai-0.6.0b13.dist-info → pygeai-0.6.1.dist-info}/licenses/LICENSE +0 -0
  217. {pygeai-0.6.0b13.dist-info → pygeai-0.6.1.dist-info}/top_level.txt +0 -0
@@ -3,7 +3,7 @@ import platform
3
3
  import os
4
4
  import subprocess
5
5
  import sys
6
- from importlib import resources
6
+ from importlib import resources, util
7
7
  from pathlib import Path
8
8
 
9
9
  from pygeai import logger
@@ -32,12 +32,14 @@ def show_help():
32
32
 
33
33
 
34
34
  def get_chat_completion(option_list: list):
35
- model = None
35
+ opts = {opt.name: arg for opt, arg in option_list}
36
+
37
+ model = opts.get('model')
36
38
  message_list = []
37
39
  stream = False
38
40
  temperature = None
39
41
  max_tokens = None
40
- thread_id = None
42
+ thread_id = opts.get('thread_id')
41
43
  frequency_penalty = None
42
44
  presence_penalty = None
43
45
  top_p = None
@@ -51,82 +53,103 @@ def get_chat_completion(option_list: list):
51
53
  stream_options = None
52
54
  store = None
53
55
  metadata = None
54
- user = None
55
- reasoning_effort = None
56
+ user = opts.get('user')
57
+ reasoning_effort = opts.get('reasoning_effort')
56
58
 
57
- for option_flag, option_arg in option_list:
58
- if option_flag.name == "model":
59
- model = option_arg
60
- if option_flag.name == "messages":
61
- try:
62
- message_json = json.loads(option_arg)
63
- if isinstance(message_json, list):
64
- message_list = message_json
65
- elif isinstance(message_json, dict):
66
- message_list.append(message_json)
67
- except Exception as e:
68
- raise WrongArgumentError(
69
- "Each message must be in json format: '{\"role\": \"user\", \"content\": \"message content\"}' "
70
- "It can be a dictionary or a list of dictionaries. Each dictionary must contain role and content")
71
- if option_flag.name == "stream":
72
- if option_arg:
73
- stream = get_boolean_value(option_arg)
74
- if option_flag.name == "temperature":
75
- temperature = float(option_arg) if option_arg is not None else None
76
- if option_flag.name == "max_tokens":
77
- max_tokens = int(option_arg) if option_arg is not None else None
78
- if option_flag.name == "thread_id":
79
- thread_id = option_arg
80
- if option_flag.name == "frequency_penalty":
81
- if option_arg:
82
- frequency_penalty = get_penalty_float_value(option_arg)
83
- if option_flag.name == "presence_penalty":
84
- if option_arg:
85
- presence_penalty = get_penalty_float_value(option_arg)
86
- if option_flag.name == "top_p":
87
- top_p = float(option_arg) if option_arg else None
88
- if option_flag.name == "stop":
89
- try:
90
- stop = json.loads(option_arg) if option_arg else None
91
- except json.JSONDecodeError:
92
- stop = option_arg
93
- if option_flag.name == "response_format":
94
- try:
95
- response_format = json.loads(option_arg) if option_arg else None
96
- except json.JSONDecodeError:
97
- raise WrongArgumentError("response_format must be a valid JSON object")
98
- if option_flag.name == "tools":
99
- try:
100
- tools = json.loads(option_arg) if option_arg else None
101
- except json.JSONDecodeError:
102
- raise WrongArgumentError("tools must be a valid JSON array")
103
- if option_flag.name == "tool_choice":
104
- try:
105
- tool_choice = json.loads(option_arg) if option_arg else None
106
- except json.JSONDecodeError:
107
- tool_choice = option_arg
108
- if option_flag.name == "logprobs":
109
- logprobs = get_boolean_value(option_arg) if option_arg else None
110
- if option_flag.name == "top_logprobs":
111
- top_logprobs = int(option_arg) if option_arg else None
112
- if option_flag.name == "seed":
113
- seed = int(option_arg) if option_arg else None
114
- if option_flag.name == "stream_options":
115
- try:
116
- stream_options = json.loads(option_arg) if option_arg else None
117
- except json.JSONDecodeError:
118
- raise WrongArgumentError("stream_options must be a valid JSON object")
119
- if option_flag.name == "store":
120
- store = get_boolean_value(option_arg) if option_arg else None
121
- if option_flag.name == "metadata":
122
- try:
123
- metadata = json.loads(option_arg) if option_arg else None
124
- except json.JSONDecodeError:
125
- raise WrongArgumentError("metadata must be a valid JSON object")
126
- if option_flag.name == "user":
127
- user = option_arg
128
- if option_flag.name == "reasoning_effort":
129
- reasoning_effort = option_arg
59
+ messages_arg = opts.get('messages')
60
+ if messages_arg:
61
+ try:
62
+ message_json = json.loads(messages_arg)
63
+ if isinstance(message_json, list):
64
+ message_list = message_json
65
+ elif isinstance(message_json, dict):
66
+ message_list.append(message_json)
67
+ except Exception:
68
+ raise WrongArgumentError(
69
+ "Each message must be in json format: '{\"role\": \"user\", \"content\": \"message content\"}' "
70
+ "It can be a dictionary or a list of dictionaries. Each dictionary must contain role and content")
71
+
72
+ stream_arg = opts.get('stream')
73
+ if stream_arg:
74
+ stream = get_boolean_value(stream_arg)
75
+
76
+ temperature_arg = opts.get('temperature')
77
+ if temperature_arg is not None:
78
+ temperature = float(temperature_arg)
79
+
80
+ max_tokens_arg = opts.get('max_tokens')
81
+ if max_tokens_arg is not None:
82
+ max_tokens = int(max_tokens_arg)
83
+
84
+ frequency_penalty_arg = opts.get('frequency_penalty')
85
+ if frequency_penalty_arg:
86
+ frequency_penalty = get_penalty_float_value(frequency_penalty_arg)
87
+
88
+ presence_penalty_arg = opts.get('presence_penalty')
89
+ if presence_penalty_arg:
90
+ presence_penalty = get_penalty_float_value(presence_penalty_arg)
91
+
92
+ top_p_arg = opts.get('top_p')
93
+ if top_p_arg:
94
+ top_p = float(top_p_arg)
95
+
96
+ stop_arg = opts.get('stop')
97
+ if stop_arg:
98
+ try:
99
+ stop = json.loads(stop_arg)
100
+ except json.JSONDecodeError:
101
+ stop = stop_arg
102
+
103
+ response_format_arg = opts.get('response_format')
104
+ if response_format_arg:
105
+ try:
106
+ response_format = json.loads(response_format_arg)
107
+ except json.JSONDecodeError:
108
+ raise WrongArgumentError("response_format must be a valid JSON object")
109
+
110
+ tools_arg = opts.get('tools')
111
+ if tools_arg:
112
+ try:
113
+ tools = json.loads(tools_arg)
114
+ except json.JSONDecodeError:
115
+ raise WrongArgumentError("tools must be a valid JSON array")
116
+
117
+ tool_choice_arg = opts.get('tool_choice')
118
+ if tool_choice_arg:
119
+ try:
120
+ tool_choice = json.loads(tool_choice_arg)
121
+ except json.JSONDecodeError:
122
+ tool_choice = tool_choice_arg
123
+
124
+ logprobs_arg = opts.get('logprobs')
125
+ if logprobs_arg:
126
+ logprobs = get_boolean_value(logprobs_arg)
127
+
128
+ top_logprobs_arg = opts.get('top_logprobs')
129
+ if top_logprobs_arg:
130
+ top_logprobs = int(top_logprobs_arg)
131
+
132
+ seed_arg = opts.get('seed')
133
+ if seed_arg:
134
+ seed = int(seed_arg)
135
+
136
+ stream_options_arg = opts.get('stream_options')
137
+ if stream_options_arg:
138
+ try:
139
+ stream_options = json.loads(stream_options_arg)
140
+ except json.JSONDecodeError:
141
+ raise WrongArgumentError("stream_options must be a valid JSON object")
142
+
143
+ store_arg = opts.get('store')
144
+ if store_arg:
145
+ store = get_boolean_value(store_arg)
146
+
147
+ metadata_arg = opts.get('metadata')
148
+ if metadata_arg:
149
+ try:
150
+ metadata = json.loads(metadata_arg)
151
+ except json.JSONDecodeError:
152
+ raise WrongArgumentError("metadata must be a valid JSON object")
130
153
 
131
154
  messages = get_messages(message_list)
132
155
 
@@ -312,15 +335,15 @@ chat_completion_options = [
312
335
 
313
336
  def chat_with_iris():
314
337
  iris = Iris()
315
- messages = list()
338
+ messages = []
316
339
 
317
340
  history = InMemoryHistory()
318
341
  session = PromptSession(">> Ask Iris: ", history=history)
319
342
 
320
- Console.write_stdout(f"#=================================================#")
321
- Console.write_stdout(f"#--------------------- IRIS ----------------------#")
322
- Console.write_stdout(f"#=================================================#")
323
- Console.write_stdout(f"# This is the start of your conversation with Iris. Type 'exit' or press Ctrl+C to close the chat.\n")
343
+ Console.write_stdout("#=================================================#")
344
+ Console.write_stdout("#--------------------- IRIS ----------------------#")
345
+ Console.write_stdout("#=================================================#")
346
+ Console.write_stdout("# This is the start of your conversation with Iris. Type 'exit' or press Ctrl+C to close the chat.\n")
324
347
  Console.write_stdout("""- Iris: Hello! I'm Iris. I'll guide you step by step to create your agent.
325
348
  First, we need to define some key details for your agent. You can specify its role and purpose or give it a name, and I'll help you set up the rest. Once we have that, we'll refine its knowledge and behavior.""")
326
349
  try:
@@ -356,22 +379,15 @@ First, we need to define some key details for your agent. You can specify its ro
356
379
 
357
380
 
358
381
  def chat_with_agent(option_list: list):
359
- agent_name = None
360
- use_gui = False
361
- save_session_file = None
362
- restore_session_file = None
363
- for option_flag, option_arg in option_list:
364
- if option_flag.name == "agent_name":
365
- agent_name = option_arg
366
- if option_flag.name == "gui":
367
- use_gui = True
368
- if option_flag.name == "save_session":
369
- save_session_file = option_arg
370
- if option_flag.name == "restore_session":
371
- restore_session_file = option_arg
382
+ opts = {opt.name: arg for opt, arg in option_list}
383
+
384
+ agent_name = opts.get('agent_name')
385
+ use_gui = 'gui' in opts
386
+ save_session_file = opts.get('save_session')
387
+ restore_session_file = opts.get('restore_session')
372
388
 
373
389
  if not agent_name:
374
- raise MissingRequirementException(f"Agent name must be specified.")
390
+ raise MissingRequirementException("Agent name must be specified.")
375
391
 
376
392
  project_id = get_project_id()
377
393
  agent_data = AgentClient(project_id=project_id).get_agent(agent_id=agent_name)
@@ -379,9 +395,7 @@ def chat_with_agent(option_list: list):
379
395
  raise InvalidAgentException(f"There is no agent with that name: {agent_data.get('errors')}")
380
396
 
381
397
  if use_gui:
382
- try:
383
- import streamlit
384
- except ImportError:
398
+ if not util.find_spec("streamlit"):
385
399
  logger.error("Streamlit not installed")
386
400
  Console.write_stderr("Streamlit is required for GUI mode. Install it with 'pip install streamlit'.")
387
401
  sys.exit(1)
@@ -436,7 +450,7 @@ def chat_with_agent(option_list: list):
436
450
  sys.exit(1)
437
451
  else:
438
452
  chat_session = AgentChatSession(agent_name)
439
- messages = list()
453
+ messages = []
440
454
 
441
455
  # Restore session if specified
442
456
  if restore_session_file:
@@ -447,9 +461,9 @@ def chat_with_agent(option_list: list):
447
461
  messages = restored_data
448
462
  Console.write_stdout(f"Restored conversation from {restore_session_file}")
449
463
  # Display restored conversation history
450
- Console.write_stdout(f"#=================================================#")
464
+ Console.write_stdout("#=================================================#")
451
465
  Console.write_stdout(f"# CHAT SESSION WITH {agent_name} ")
452
- Console.write_stdout(f"#=================================================#")
466
+ Console.write_stdout("#=================================================#")
453
467
  for msg in messages:
454
468
  role = msg.get("role", "unknown")
455
469
  content = msg.get("content", "")
@@ -480,9 +494,9 @@ def chat_with_agent(option_list: list):
480
494
  raise WrongArgumentError(
481
495
  "The specified agent doesn't seem to exist. Please review the name and try again.")
482
496
 
483
- Console.write_stdout(f"#=================================================#")
497
+ Console.write_stdout("#=================================================#")
484
498
  Console.write_stdout(f"# CHAT SESSION WITH {agent_name} ")
485
- Console.write_stdout(f"#=================================================#")
499
+ Console.write_stdout("#=================================================#")
486
500
  Console.write_stdout(introduction_message)
487
501
  messages.append({"role": "assistant", "content": introduction_message})
488
502
 
@@ -576,31 +590,23 @@ chat_with_agent_options = [
576
590
 
577
591
 
578
592
  def get_generate_image(option_list: list):
579
- model = None
580
- prompt = None
593
+ opts = {opt.name: arg for opt, arg in option_list}
594
+
595
+ model = opts.get('model')
596
+ prompt = opts.get('prompt')
581
597
  n = None
582
- quality = None
583
- size = None
584
- aspect_ratio = None
585
-
586
- for option_flag, option_arg in option_list:
587
- if option_flag.name == "model":
588
- model = option_arg
589
- if option_flag.name == "prompt":
590
- prompt = option_arg
591
- if option_flag.name == "n":
592
- try:
593
- n = int(option_arg)
594
- if n < 1 or n > 10:
595
- raise WrongArgumentError("n must be an integer between 1 and 10.")
596
- except ValueError:
597
- raise WrongArgumentError("n must be a valid integer.")
598
- if option_flag.name == "quality":
599
- quality = option_arg
600
- if option_flag.name == "size":
601
- size = option_arg
602
- if option_flag.name == "aspect_ratio":
603
- aspect_ratio = option_arg
598
+ quality = opts.get('quality')
599
+ size = opts.get('size')
600
+ aspect_ratio = opts.get('aspect_ratio')
601
+
602
+ n_arg = opts.get('n')
603
+ if n_arg:
604
+ try:
605
+ n = int(n_arg)
606
+ if n < 1 or n > 10:
607
+ raise WrongArgumentError("n must be an integer between 1 and 10.")
608
+ except ValueError:
609
+ raise WrongArgumentError("n must be a valid integer.")
604
610
 
605
611
  if not (model and prompt and n is not None and quality and size):
606
612
  raise MissingRequirementException("Cannot generate image without specifying model, prompt, n, quality, and size.")
@@ -662,31 +668,23 @@ generate_image_options = [
662
668
 
663
669
 
664
670
  def get_edit_image(option_list: list):
665
- model = None
666
- prompt = None
667
- image = None
668
- size = None
671
+ opts = {opt.name: arg for opt, arg in option_list}
672
+
673
+ model = opts.get('model')
674
+ prompt = opts.get('prompt')
675
+ image = opts.get('image')
676
+ size = opts.get('size')
669
677
  n = 1
670
- quality = None
671
-
672
- for option_flag, option_arg in option_list:
673
- if option_flag.name == "model":
674
- model = option_arg
675
- if option_flag.name == "prompt":
676
- prompt = option_arg
677
- if option_flag.name == "image":
678
- image = option_arg
679
- if option_flag.name == "size":
680
- size = option_arg
681
- if option_flag.name == "n":
682
- try:
683
- n = int(option_arg)
684
- if n < 1 or n > 10:
685
- raise WrongArgumentError("n must be an integer between 1 and 10.")
686
- except ValueError:
687
- raise WrongArgumentError("n must be a valid integer.")
688
- if option_flag.name == "quality":
689
- quality = option_arg
678
+ quality = opts.get('quality')
679
+
680
+ n_arg = opts.get('n')
681
+ if n_arg:
682
+ try:
683
+ n = int(n_arg)
684
+ if n < 1 or n > 10:
685
+ raise WrongArgumentError("n must be an integer between 1 and 10.")
686
+ except ValueError:
687
+ raise WrongArgumentError("n must be a valid integer.")
690
688
 
691
689
  if not (model and prompt and image and size):
692
690
  raise MissingRequirementException("Cannot edit image without specifying model, prompt, image, and size.")
@@ -748,8 +746,10 @@ edit_image_options = [
748
746
 
749
747
 
750
748
  def get_response(option_list: list):
751
- model = None
752
- input_text = None
749
+ opts = {opt.name: arg for opt, arg in option_list}
750
+
751
+ model = opts.get('model')
752
+ input_text = opts.get('input')
753
753
  files = None
754
754
  tools = None
755
755
  tool_choice = None
@@ -757,65 +757,74 @@ def get_response(option_list: list):
757
757
  max_output_tokens = None
758
758
  top_p = None
759
759
  metadata = None
760
- user = None
761
- instructions = None
760
+ user = opts.get('user')
761
+ instructions = opts.get('instructions')
762
762
  reasoning = None
763
- truncation = None
763
+ truncation = opts.get('truncation')
764
764
  parallel_tool_calls = None
765
765
  store = None
766
766
  stream = False
767
767
 
768
- for option_flag, option_arg in option_list:
769
- if option_flag.name == "model":
770
- model = option_arg
771
- if option_flag.name == "input":
772
- input_text = option_arg
773
- if option_flag.name == "files":
774
- try:
775
- files = json.loads(option_arg) if option_arg else None
776
- if files and not isinstance(files, list):
777
- raise WrongArgumentError("files must be a JSON array of file paths")
778
- except json.JSONDecodeError:
779
- raise WrongArgumentError("files must be a valid JSON array")
780
- if option_flag.name == "tools":
781
- try:
782
- tools = json.loads(option_arg) if option_arg else None
783
- except json.JSONDecodeError:
784
- raise WrongArgumentError("tools must be a valid JSON array")
785
- if option_flag.name == "tool_choice":
786
- try:
787
- tool_choice = json.loads(option_arg) if option_arg else None
788
- except json.JSONDecodeError:
789
- tool_choice = option_arg
790
- if option_flag.name == "temperature":
791
- temperature = float(option_arg) if option_arg is not None else None
792
- if option_flag.name == "max_output_tokens":
793
- max_output_tokens = int(option_arg) if option_arg is not None else None
794
- if option_flag.name == "top_p":
795
- top_p = float(option_arg) if option_arg else None
796
- if option_flag.name == "metadata":
797
- try:
798
- metadata = json.loads(option_arg) if option_arg else None
799
- except json.JSONDecodeError:
800
- raise WrongArgumentError("metadata must be a valid JSON object")
801
- if option_flag.name == "user":
802
- user = option_arg
803
- if option_flag.name == "instructions":
804
- instructions = option_arg
805
- if option_flag.name == "reasoning":
806
- try:
807
- reasoning = json.loads(option_arg) if option_arg else None
808
- except json.JSONDecodeError:
809
- raise WrongArgumentError("reasoning must be a valid JSON object")
810
- if option_flag.name == "truncation":
811
- truncation = option_arg
812
- if option_flag.name == "parallel_tool_calls":
813
- parallel_tool_calls = get_boolean_value(option_arg) if option_arg else None
814
- if option_flag.name == "store":
815
- store = get_boolean_value(option_arg) if option_arg else None
816
- if option_flag.name == "stream":
817
- if option_arg:
818
- stream = get_boolean_value(option_arg)
768
+ files_arg = opts.get('files')
769
+ if files_arg:
770
+ try:
771
+ files = json.loads(files_arg)
772
+ if files and not isinstance(files, list):
773
+ raise WrongArgumentError("files must be a JSON array of file paths")
774
+ except json.JSONDecodeError:
775
+ raise WrongArgumentError("files must be a valid JSON array")
776
+
777
+ tools_arg = opts.get('tools')
778
+ if tools_arg:
779
+ try:
780
+ tools = json.loads(tools_arg)
781
+ except json.JSONDecodeError:
782
+ raise WrongArgumentError("tools must be a valid JSON array")
783
+
784
+ tool_choice_arg = opts.get('tool_choice')
785
+ if tool_choice_arg:
786
+ try:
787
+ tool_choice = json.loads(tool_choice_arg)
788
+ except json.JSONDecodeError:
789
+ tool_choice = tool_choice_arg
790
+
791
+ temperature_arg = opts.get('temperature')
792
+ if temperature_arg is not None:
793
+ temperature = float(temperature_arg)
794
+
795
+ max_output_tokens_arg = opts.get('max_output_tokens')
796
+ if max_output_tokens_arg is not None:
797
+ max_output_tokens = int(max_output_tokens_arg)
798
+
799
+ top_p_arg = opts.get('top_p')
800
+ if top_p_arg:
801
+ top_p = float(top_p_arg)
802
+
803
+ metadata_arg = opts.get('metadata')
804
+ if metadata_arg:
805
+ try:
806
+ metadata = json.loads(metadata_arg)
807
+ except json.JSONDecodeError:
808
+ raise WrongArgumentError("metadata must be a valid JSON object")
809
+
810
+ reasoning_arg = opts.get('reasoning')
811
+ if reasoning_arg:
812
+ try:
813
+ reasoning = json.loads(reasoning_arg)
814
+ except json.JSONDecodeError:
815
+ raise WrongArgumentError("reasoning must be a valid JSON object")
816
+
817
+ parallel_tool_calls_arg = opts.get('parallel_tool_calls')
818
+ if parallel_tool_calls_arg:
819
+ parallel_tool_calls = get_boolean_value(parallel_tool_calls_arg)
820
+
821
+ store_arg = opts.get('store')
822
+ if store_arg:
823
+ store = get_boolean_value(store_arg)
824
+
825
+ stream_arg = opts.get('stream')
826
+ if stream_arg:
827
+ stream = get_boolean_value(stream_arg)
819
828
 
820
829
  if not (model and input_text):
821
830
  raise MissingRequirementException("Cannot get response without specifying model and input")
@@ -59,7 +59,7 @@ def get_welcome_data(
59
59
  "title": feature_dict['title'],
60
60
  "description": feature_dict['description']
61
61
  })
62
- except ValueError as e:
62
+ except ValueError:
63
63
  raise WrongArgumentError(
64
64
  "Each feature must have exactly two keys: \"title\" and \"description\"")
65
65
 
@@ -71,7 +71,7 @@ def get_welcome_data(
71
71
  "description": example['description'],
72
72
  "promptText": example['prompt_text']
73
73
  })
74
- except ValueError as e:
74
+ except ValueError:
75
75
  raise WrongArgumentError(
76
76
  "Each example prompt must have exactly three keys: \"title\", \"description\", and \"prompt_text\"")
77
77
 
@@ -101,7 +101,7 @@ def get_messages(message_list: list):
101
101
  "role": message_dict['role'],
102
102
  "content": message_dict['content']
103
103
  })
104
- except ValueError as e:
104
+ except ValueError:
105
105
  raise WrongArgumentError(
106
106
  "Each message must be in JSON format: '{\"role\": \"user\", \"content\": \"message content\"}' "
107
107
  "Each dictionary must contain role and content")
@@ -384,7 +384,7 @@ def get_welcome_data_feature_list(feature_list: list, option_arg: str):
384
384
  feature_list = feature_json
385
385
  elif isinstance(feature_json, dict):
386
386
  feature_list.append(feature_json)
387
- except Exception as e:
387
+ except Exception:
388
388
  raise WrongArgumentError(
389
389
  "Features must be a JSON string. It can be either a dictionary or a list or dictionaries. "
390
390
  "Each feature must be a dictionary with exactly two keys: 'title' and 'description'")
@@ -399,7 +399,7 @@ def get_welcome_data_example_prompt(examples_prompt_list: list, option_arg: str)
399
399
  examples_prompt_list = examples_prompt_json
400
400
  elif isinstance(examples_prompt_json, dict):
401
401
  examples_prompt_list.append(examples_prompt_json)
402
- except Exception as e:
402
+ except Exception:
403
403
  raise WrongArgumentError(
404
404
  "Example prompt text must be a JSON string. It can be either a dictionary or a list or dictionaries. "
405
405
  "Each example_prompt must be a dictionary with exactly three keys: 'title', 'description' and 'prompt_text'")