solace-agent-mesh 1.1.0__py3-none-any.whl → 1.3.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.

Potentially problematic release.


This version of solace-agent-mesh might be problematic. Click here for more details.

Files changed (168) hide show
  1. solace_agent_mesh/agent/adk/runner.py +18 -12
  2. solace_agent_mesh/agent/adk/services.py +3 -3
  3. solace_agent_mesh/agent/adk/setup.py +141 -34
  4. solace_agent_mesh/agent/protocol/event_handlers.py +27 -21
  5. solace_agent_mesh/agent/sac/app.py +0 -1
  6. solace_agent_mesh/agent/sac/component.py +0 -1
  7. solace_agent_mesh/agent/tools/__init__.py +1 -0
  8. solace_agent_mesh/agent/tools/dynamic_tool.py +362 -0
  9. solace_agent_mesh/assets/docs/404.html +3 -3
  10. solace_agent_mesh/assets/docs/assets/js/42b3f8d8.d97b8e94.js +1 -0
  11. solace_agent_mesh/assets/docs/assets/js/483cef9a.4e972867.js +1 -0
  12. solace_agent_mesh/assets/docs/assets/js/55f47984.cf3781c4.js +1 -0
  13. solace_agent_mesh/assets/docs/assets/js/664b740a.1b744a32.js +1 -0
  14. solace_agent_mesh/assets/docs/assets/js/75384d09.c193a8f0.js +1 -0
  15. solace_agent_mesh/assets/docs/assets/js/9a09e75d.d6607c56.js +1 -0
  16. solace_agent_mesh/assets/docs/assets/js/aba87c2f.071e2d94.js +1 -0
  17. solace_agent_mesh/assets/docs/assets/js/ae0e903d.4d8dda10.js +1 -0
  18. solace_agent_mesh/assets/docs/assets/js/c835a94d.146e3186.js +1 -0
  19. solace_agent_mesh/assets/docs/assets/js/f284c35a.7334119c.js +1 -0
  20. solace_agent_mesh/assets/docs/assets/js/main.1c79039d.js +2 -0
  21. solace_agent_mesh/assets/docs/assets/js/runtime~main.858117b7.js +1 -0
  22. solace_agent_mesh/assets/docs/docs/documentation/Enterprise/installation/index.html +29 -0
  23. solace_agent_mesh/assets/docs/docs/documentation/Enterprise/single-sign-on/index.html +25 -0
  24. solace_agent_mesh/assets/docs/docs/documentation/{migration-guides/a2a-upgrade-to-0.3.0/a2a-gateway-upgrade-to-0.3.0/index.html → Migrations/A2A Upgrade To 0.3.0/a2a-gateway-upgrade-to-0.3.0/index.html } +6 -6
  25. solace_agent_mesh/assets/docs/docs/documentation/{migration-guides/a2a-upgrade-to-0.3.0/a2a-technical-migration-map/index.html → Migrations/A2A Upgrade To 0.3.0/a2a-technical-migration-map/index.html } +6 -6
  26. solace_agent_mesh/assets/docs/docs/documentation/concepts/agents/index.html +19 -27
  27. solace_agent_mesh/assets/docs/docs/documentation/concepts/architecture/index.html +4 -4
  28. solace_agent_mesh/assets/docs/docs/documentation/concepts/cli/index.html +4 -4
  29. solace_agent_mesh/assets/docs/docs/documentation/concepts/gateways/index.html +4 -4
  30. solace_agent_mesh/assets/docs/docs/documentation/concepts/orchestrator/index.html +4 -4
  31. solace_agent_mesh/assets/docs/docs/documentation/concepts/plugins/index.html +4 -4
  32. solace_agent_mesh/assets/docs/docs/documentation/deployment/debugging/index.html +4 -4
  33. solace_agent_mesh/assets/docs/docs/documentation/deployment/deploy/index.html +4 -4
  34. solace_agent_mesh/assets/docs/docs/documentation/deployment/observability/index.html +4 -4
  35. solace_agent_mesh/assets/docs/docs/documentation/getting-started/component-overview/index.html +4 -4
  36. solace_agent_mesh/assets/docs/docs/documentation/getting-started/configurations/index.html +4 -4
  37. solace_agent_mesh/assets/docs/docs/documentation/getting-started/installation/index.html +4 -4
  38. solace_agent_mesh/assets/docs/docs/documentation/getting-started/introduction/index.html +4 -4
  39. solace_agent_mesh/assets/docs/docs/documentation/getting-started/quick-start/index.html +4 -4
  40. solace_agent_mesh/assets/docs/docs/documentation/tutorials/bedrock-agents/index.html +4 -4
  41. solace_agent_mesh/assets/docs/docs/documentation/tutorials/custom-agent/index.html +4 -4
  42. solace_agent_mesh/assets/docs/docs/documentation/tutorials/event-mesh-gateway/index.html +4 -4
  43. solace_agent_mesh/assets/docs/docs/documentation/tutorials/mcp-integration/index.html +4 -4
  44. solace_agent_mesh/assets/docs/docs/documentation/tutorials/mongodb-integration/index.html +4 -4
  45. solace_agent_mesh/assets/docs/docs/documentation/tutorials/rag-integration/index.html +4 -4
  46. solace_agent_mesh/assets/docs/docs/documentation/tutorials/rest-gateway/index.html +4 -4
  47. solace_agent_mesh/assets/docs/docs/documentation/tutorials/slack-integration/index.html +4 -4
  48. solace_agent_mesh/assets/docs/docs/documentation/tutorials/sql-database/index.html +4 -4
  49. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/artifact-management/index.html +4 -4
  50. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/audio-tools/index.html +4 -4
  51. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/data-analysis-tools/index.html +4 -4
  52. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/embeds/index.html +4 -4
  53. solace_agent_mesh/assets/docs/docs/documentation/user-guide/builtin-tools/index.html +4 -4
  54. solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-agents/index.html +5 -4
  55. solace_agent_mesh/assets/docs/docs/documentation/user-guide/create-gateways/index.html +4 -4
  56. solace_agent_mesh/assets/docs/docs/documentation/user-guide/creating-python-tools/index.html +63 -0
  57. solace_agent_mesh/assets/docs/docs/documentation/user-guide/creating-service-providers/index.html +4 -4
  58. solace_agent_mesh/assets/docs/docs/documentation/user-guide/solace-ai-connector/index.html +4 -4
  59. solace_agent_mesh/assets/docs/docs/documentation/user-guide/structure/index.html +4 -4
  60. solace_agent_mesh/assets/docs/lunr-index-1757531604543.json +1 -0
  61. solace_agent_mesh/assets/docs/lunr-index.json +1 -1
  62. solace_agent_mesh/assets/docs/search-doc-1757531604543.json +1 -0
  63. solace_agent_mesh/assets/docs/search-doc.json +1 -1
  64. solace_agent_mesh/assets/docs/sitemap.xml +1 -1
  65. solace_agent_mesh/cli/__init__.py +1 -1
  66. solace_agent_mesh/cli/commands/add_cmd/agent_cmd.py +125 -48
  67. solace_agent_mesh/cli/commands/eval_cmd.py +14 -0
  68. solace_agent_mesh/cli/commands/init_cmd/__init__.py +53 -31
  69. solace_agent_mesh/cli/commands/init_cmd/database_step.py +91 -0
  70. solace_agent_mesh/cli/commands/init_cmd/env_step.py +19 -8
  71. solace_agent_mesh/cli/commands/init_cmd/orchestrator_step.py +80 -25
  72. solace_agent_mesh/cli/commands/init_cmd/web_init_step.py +32 -10
  73. solace_agent_mesh/cli/commands/init_cmd/webui_gateway_step.py +74 -15
  74. solace_agent_mesh/cli/commands/plugin_cmd/create_cmd.py +0 -2
  75. solace_agent_mesh/cli/commands/run_cmd.py +5 -3
  76. solace_agent_mesh/cli/utils.py +68 -12
  77. solace_agent_mesh/client/webui/frontend/static/assets/authCallback-CAX9u8a7.js +1 -0
  78. solace_agent_mesh/client/webui/frontend/static/assets/client-DXU9SPI5.js +25 -0
  79. solace_agent_mesh/client/webui/frontend/static/assets/main-C03yrETa.css +1 -0
  80. solace_agent_mesh/client/webui/frontend/static/assets/main-C1k9E0aC.js +339 -0
  81. solace_agent_mesh/client/webui/frontend/static/assets/vendor-B0BEKoAR.js +390 -0
  82. solace_agent_mesh/client/webui/frontend/static/auth-callback.html +3 -2
  83. solace_agent_mesh/client/webui/frontend/static/index.html +4 -3
  84. solace_agent_mesh/common/utils/embeds/resolver.py +1 -0
  85. solace_agent_mesh/config_portal/backend/common.py +2 -2
  86. solace_agent_mesh/config_portal/frontend/static/client/assets/_index-bFMKlzKf.js +98 -0
  87. solace_agent_mesh/config_portal/frontend/static/client/assets/{manifest-d845808d.js → manifest-89db7c30.js} +1 -1
  88. solace_agent_mesh/config_portal/frontend/static/client/index.html +1 -1
  89. solace_agent_mesh/evaluation/message_organizer.py +35 -56
  90. solace_agent_mesh/evaluation/run.py +26 -5
  91. solace_agent_mesh/evaluation/subscriber.py +35 -10
  92. solace_agent_mesh/evaluation/summary_builder.py +27 -34
  93. solace_agent_mesh/gateway/http_sse/ARCHITECTURE_GUIDE.md +676 -0
  94. solace_agent_mesh/gateway/http_sse/alembic/env.py +85 -0
  95. solace_agent_mesh/gateway/http_sse/alembic/script.py.mako +28 -0
  96. solace_agent_mesh/gateway/http_sse/alembic/versions/b1c2d3e4f5g6_add_database_indexes.py +83 -0
  97. solace_agent_mesh/gateway/http_sse/alembic/versions/d5b3f8f2e9a0_create_initial_database.py +58 -0
  98. solace_agent_mesh/gateway/http_sse/alembic.ini +147 -0
  99. solace_agent_mesh/gateway/http_sse/api/__init__.py +11 -0
  100. solace_agent_mesh/gateway/http_sse/api/controllers/__init__.py +9 -0
  101. solace_agent_mesh/gateway/http_sse/api/controllers/session_controller.py +355 -0
  102. solace_agent_mesh/gateway/http_sse/api/controllers/task_controller.py +279 -0
  103. solace_agent_mesh/gateway/http_sse/api/controllers/user_controller.py +35 -0
  104. solace_agent_mesh/gateway/http_sse/api/dto/__init__.py +10 -0
  105. solace_agent_mesh/gateway/http_sse/api/dto/requests/__init__.py +37 -0
  106. solace_agent_mesh/gateway/http_sse/api/dto/requests/session_requests.py +49 -0
  107. solace_agent_mesh/gateway/http_sse/api/dto/requests/task_requests.py +66 -0
  108. solace_agent_mesh/gateway/http_sse/api/dto/responses/__init__.py +43 -0
  109. solace_agent_mesh/gateway/http_sse/api/dto/responses/session_responses.py +68 -0
  110. solace_agent_mesh/gateway/http_sse/api/dto/responses/task_responses.py +74 -0
  111. solace_agent_mesh/gateway/http_sse/app.py +31 -1
  112. solace_agent_mesh/gateway/http_sse/application/__init__.py +3 -0
  113. solace_agent_mesh/gateway/http_sse/application/services/__init__.py +3 -0
  114. solace_agent_mesh/gateway/http_sse/application/services/session_service.py +135 -0
  115. solace_agent_mesh/gateway/http_sse/component.py +224 -62
  116. solace_agent_mesh/gateway/http_sse/dependencies.py +148 -45
  117. solace_agent_mesh/gateway/http_sse/domain/entities/__init__.py +3 -0
  118. solace_agent_mesh/gateway/http_sse/domain/entities/session.py +90 -0
  119. solace_agent_mesh/gateway/http_sse/domain/repositories/__init__.py +3 -0
  120. solace_agent_mesh/gateway/http_sse/domain/repositories/session_repository.py +54 -0
  121. solace_agent_mesh/gateway/http_sse/infrastructure/__init__.py +4 -0
  122. solace_agent_mesh/gateway/http_sse/infrastructure/dependency_injection/__init__.py +3 -0
  123. solace_agent_mesh/gateway/http_sse/infrastructure/dependency_injection/container.py +123 -0
  124. solace_agent_mesh/gateway/http_sse/infrastructure/persistence/__init__.py +4 -0
  125. solace_agent_mesh/gateway/http_sse/infrastructure/persistence/database_persistence_service.py +16 -0
  126. solace_agent_mesh/gateway/http_sse/infrastructure/persistence/database_service.py +119 -0
  127. solace_agent_mesh/gateway/http_sse/infrastructure/persistence/models.py +31 -0
  128. solace_agent_mesh/gateway/http_sse/infrastructure/persistence_service.py +12 -0
  129. solace_agent_mesh/gateway/http_sse/infrastructure/repositories/__init__.py +3 -0
  130. solace_agent_mesh/gateway/http_sse/infrastructure/repositories/session_repository.py +174 -0
  131. solace_agent_mesh/gateway/http_sse/main.py +291 -87
  132. solace_agent_mesh/gateway/http_sse/routers/{agents.py → agent_cards.py} +7 -7
  133. solace_agent_mesh/gateway/http_sse/routers/artifacts.py +121 -54
  134. solace_agent_mesh/gateway/http_sse/routers/config.py +3 -1
  135. solace_agent_mesh/gateway/http_sse/routers/tasks.py +83 -2
  136. solace_agent_mesh/gateway/http_sse/routers/visualization.py +7 -7
  137. solace_agent_mesh/gateway/http_sse/services/{agent_service.py → agent_card_service.py} +19 -19
  138. solace_agent_mesh/gateway/http_sse/session_manager.py +64 -30
  139. solace_agent_mesh/gateway/http_sse/shared/__init__.py +9 -0
  140. solace_agent_mesh/gateway/http_sse/shared/auth_utils.py +29 -0
  141. solace_agent_mesh/gateway/http_sse/shared/enums.py +45 -0
  142. solace_agent_mesh/gateway/http_sse/shared/types.py +45 -0
  143. solace_agent_mesh/templates/shared_config.yaml +4 -5
  144. solace_agent_mesh/templates/webui.yaml +8 -10
  145. {solace_agent_mesh-1.1.0.dist-info → solace_agent_mesh-1.3.1.dist-info}/METADATA +5 -3
  146. {solace_agent_mesh-1.1.0.dist-info → solace_agent_mesh-1.3.1.dist-info}/RECORD +150 -104
  147. solace_agent_mesh/assets/docs/assets/js/42b3f8d8.8ccb9901.js +0 -1
  148. solace_agent_mesh/assets/docs/assets/js/55f47984.c484bf96.js +0 -1
  149. solace_agent_mesh/assets/docs/assets/js/6e0db977.39a79ca9.js +0 -1
  150. solace_agent_mesh/assets/docs/assets/js/75384d09.bf78fbdb.js +0 -1
  151. solace_agent_mesh/assets/docs/assets/js/90dd9cf6.88f385ea.js +0 -1
  152. solace_agent_mesh/assets/docs/assets/js/aba87c2f.76376d7c.js +0 -1
  153. solace_agent_mesh/assets/docs/assets/js/f284c35a.fb68323a.js +0 -1
  154. solace_agent_mesh/assets/docs/assets/js/main.a75ecc0d.js +0 -2
  155. solace_agent_mesh/assets/docs/assets/js/runtime~main.458efb1d.js +0 -1
  156. solace_agent_mesh/assets/docs/lunr-index-1756992446316.json +0 -1
  157. solace_agent_mesh/assets/docs/search-doc-1756992446316.json +0 -1
  158. solace_agent_mesh/client/webui/frontend/static/assets/authCallback-BmF2l6vg.js +0 -1
  159. solace_agent_mesh/client/webui/frontend/static/assets/client-D881Dttc.js +0 -49
  160. solace_agent_mesh/client/webui/frontend/static/assets/main-C0jZjYa8.js +0 -699
  161. solace_agent_mesh/client/webui/frontend/static/assets/main-CCeG324-.css +0 -1
  162. solace_agent_mesh/config_portal/frontend/static/client/assets/_index-Bym6YkMd.js +0 -98
  163. solace_agent_mesh/gateway/http_sse/routers/sessions.py +0 -85
  164. solace_agent_mesh/gateway/http_sse/routers/users.py +0 -59
  165. /solace_agent_mesh/assets/docs/assets/js/{main.a75ecc0d.js.LICENSE.txt → main.1c79039d.js.LICENSE.txt} +0 -0
  166. {solace_agent_mesh-1.1.0.dist-info → solace_agent_mesh-1.3.1.dist-info}/WHEEL +0 -0
  167. {solace_agent_mesh-1.1.0.dist-info → solace_agent_mesh-1.3.1.dist-info}/entry_points.txt +0 -0
  168. {solace_agent_mesh-1.1.0.dist-info → solace_agent_mesh-1.3.1.dist-info}/licenses/LICENSE +0 -0
@@ -18,6 +18,8 @@ ENV_DEFAULTS = {
18
18
  "FASTAPI_PORT": "8000",
19
19
  "FASTAPI_HTTPS_PORT": "8443",
20
20
  "ENABLE_EMBED_RESOLUTION": "true",
21
+ "WEB_UI_GATEWAY_DATABASE_URL": "sqlite:///data/webui_gateway.db",
22
+ "ORCHESTRATOR_DATABASE_URL": "sqlite:///data/orchestrator.db",
21
23
  "SSL_KEYFILE": "",
22
24
  "SSL_CERTFILE": "",
23
25
  "SSL_KEYFILE_PASSWORD": "",
@@ -39,28 +41,28 @@ def create_env_file(project_root: Path, options: dict, skip_interactive: bool) -
39
41
 
40
42
  env_params_config = [
41
43
  (
42
- "llm_endpoint_url",
44
+ "llm_service_endpoint",
43
45
  "LLM_SERVICE_ENDPOINT",
44
46
  "Enter LLM Service Endpoint URL",
45
47
  False,
46
48
  "LLM_SERVICE_ENDPOINT",
47
49
  ),
48
50
  (
49
- "llm_api_key",
51
+ "llm_service_api_key",
50
52
  "LLM_SERVICE_API_KEY",
51
53
  "Enter LLM Service API Key",
52
54
  True,
53
55
  "LLM_SERVICE_API_KEY",
54
56
  ),
55
57
  (
56
- "llm_planning_model_name",
58
+ "llm_service_planning_model_name",
57
59
  "LLM_SERVICE_PLANNING_MODEL_NAME",
58
60
  "Enter LLM Planning Model Name (e.g., openai/gpt-4o)",
59
61
  False,
60
62
  "LLM_SERVICE_PLANNING_MODEL_NAME",
61
63
  ),
62
64
  (
63
- "llm_general_model_name",
65
+ "llm_service_general_model_name",
64
66
  "LLM_SERVICE_GENERAL_MODEL_NAME",
65
67
  "Enter LLM General Model Name (e.g., openai/gpt-3.5-turbo)",
66
68
  False,
@@ -134,28 +136,28 @@ def create_env_file(project_root: Path, options: dict, skip_interactive: bool) -
134
136
  "FASTAPI_HTTPS_PORT",
135
137
  "Enter Web UI FastAPI HTTPS Port",
136
138
  False,
137
- "FASTAPI_HTTPS_PORT"
139
+ "FASTAPI_HTTPS_PORT",
138
140
  ),
139
141
  (
140
142
  "webui_ssl_keyfile",
141
143
  "SSL_KEYFILE",
142
144
  "Enter SSL Key File Path",
143
145
  False,
144
- "SSL_KEYFILE"
146
+ "SSL_KEYFILE",
145
147
  ),
146
148
  (
147
149
  "webui_ssl_certfile",
148
150
  "SSL_CERTFILE",
149
151
  "Enter SSL Certificate File Path",
150
152
  False,
151
- "SSL_CERTFILE"
153
+ "SSL_CERTFILE",
152
154
  ),
153
155
  (
154
156
  "webui_ssl_keyfile_password",
155
157
  "SSL_KEYFILE_PASSWORD",
156
158
  "Enter SSL Key File Passphrase",
157
159
  True,
158
- "SSL_KEYFILE_PASSWORD"
160
+ "SSL_KEYFILE_PASSWORD",
159
161
  ),
160
162
  (
161
163
  "webui_enable_embed_resolution",
@@ -207,6 +209,15 @@ def create_env_file(project_root: Path, options: dict, skip_interactive: bool) -
207
209
  )
208
210
  env_vars_to_write[env_name] = options.get(opt_key)
209
211
 
212
+ if options.get("web_ui_gateway_database_url"):
213
+ env_vars_to_write["WEB_UI_GATEWAY_DATABASE_URL"] = options[
214
+ "web_ui_gateway_database_url"
215
+ ]
216
+ if options.get("orchestrator_database_url"):
217
+ env_vars_to_write["ORCHESTRATOR_DATABASE_URL"] = options[
218
+ "orchestrator_database_url"
219
+ ]
220
+
210
221
  if (
211
222
  env_vars_to_write.get("NAMESPACE")
212
223
  and env_vars_to_write["NAMESPACE"] != ENV_DEFAULTS.get("NAMESPACE")
@@ -1,17 +1,21 @@
1
- import click
1
+ import re
2
2
  from pathlib import Path
3
+
4
+ import click
3
5
  import yaml
4
- import re
5
- from ...utils import ask_if_not_provided, load_template, get_formatted_names
6
+
6
7
  from config_portal.backend.common import DEFAULT_COMMUNICATION_TIMEOUT
7
8
 
9
+ from ...utils import ask_if_not_provided, get_formatted_names, load_template
10
+
8
11
  ORCHESTRATOR_DEFAULTS = {
9
12
  "agent_name": "OrchestratorAgent",
10
13
  "supports_streaming": True,
11
14
  "artifact_handling_mode": "reference",
12
15
  "enable_embed_resolution": True,
13
16
  "enable_artifact_content_instruction": True,
14
- "session_service": {"type": "memory", "default_behavior": "PERSISTENT"},
17
+ "enable_builtin_artifact_tools": {"enabled": True},
18
+ "enable_builtin_data_tools": {"enabled": True},
15
19
  "artifact_service": {
16
20
  "type": "filesystem",
17
21
  "base_path": "/tmp/samv2",
@@ -83,16 +87,16 @@ def create_orchestrator_config(
83
87
  options,
84
88
  "session_service_type",
85
89
  "Enter session service type",
86
- ORCHESTRATOR_DEFAULTS["session_service"]["type"],
90
+ "memory",
87
91
  skip_interactive,
88
- choices=["memory", "vertex_rag"],
92
+ choices=["sql", "memory", "vertex_rag"],
89
93
  )
90
94
 
91
95
  session_behavior = ask_if_not_provided(
92
96
  options,
93
97
  "session_service_behavior",
94
98
  "Enter session service behavior",
95
- ORCHESTRATOR_DEFAULTS["session_service"]["default_behavior"],
99
+ "PERSISTENT",
96
100
  skip_interactive,
97
101
  choices=["PERSISTENT", "RUN_BASED"],
98
102
  )
@@ -110,7 +114,7 @@ def create_orchestrator_config(
110
114
  s3_bucket_name = None
111
115
  s3_endpoint_url = None
112
116
  s3_region = None
113
-
117
+
114
118
  if artifact_type == "filesystem":
115
119
  artifact_base_path = ask_if_not_provided(
116
120
  options,
@@ -127,7 +131,7 @@ def create_orchestrator_config(
127
131
  options["s3_endpoint_url"] = options["artifact_service_endpoint_url"]
128
132
  if options.get("artifact_service_region"):
129
133
  options["s3_region"] = options["artifact_service_region"]
130
-
134
+
131
135
  s3_bucket_name = ask_if_not_provided(
132
136
  options,
133
137
  "s3_bucket_name",
@@ -304,18 +308,13 @@ def create_orchestrator_config(
304
308
  if artifact_type == "filesystem":
305
309
  artifact_base_path_line = f'base_path: "{artifact_base_path}"'
306
310
  elif artifact_type == "s3":
307
- s3_config_lines = [f'bucket_name: "{s3_bucket_name}"']
308
- if s3_endpoint_url:
309
- s3_config_lines.append(f'endpoint_url: "{s3_endpoint_url}"')
310
- if s3_region:
311
- s3_config_lines.append(f'region: "{s3_region}"')
311
+ s3_config_lines = ["bucket_name: ${S3_BUCKET_NAME}"]
312
+ s3_config_lines.append("endpoint_url: ${S3_ENDPOINT_URL:-}")
313
+ s3_config_lines.append("region: ${S3_REGION}")
312
314
  artifact_base_path_line = "\n ".join(s3_config_lines)
313
315
 
314
316
  shared_replacements = {
315
- "__DEFAULT_SESSION_SERVICE_TYPE__": session_type,
316
- "__DEFAULT_SESSION_SERVICE_BEHAVIOR__": session_behavior,
317
317
  "__DEFAULT_ARTIFACT_SERVICE_TYPE__": artifact_type,
318
- "__DEFAULT_ARTIFACT_SERVICE_BASE_PATH_LINE__": artifact_base_path_line,
319
318
  "__DEFAULT_ARTIFACT_SERVICE_SCOPE__": artifact_scope,
320
319
  }
321
320
 
@@ -325,6 +324,18 @@ def create_orchestrator_config(
325
324
  placeholder, str(value)
326
325
  )
327
326
 
327
+ if not artifact_base_path_line:
328
+ modified_shared_content = re.sub(
329
+ r"\s*# __DEFAULT_ARTIFACT_SERVICE_BASE_PATH_LINE__.*",
330
+ "",
331
+ modified_shared_content,
332
+ )
333
+ else:
334
+ modified_shared_content = modified_shared_content.replace(
335
+ " # __DEFAULT_ARTIFACT_SERVICE_BASE_PATH_LINE__",
336
+ f" {artifact_base_path_line}",
337
+ )
338
+
328
339
  shared_config_dest_path.parent.mkdir(parents=True, exist_ok=True)
329
340
  with open(shared_config_dest_path, "w", encoding="utf-8") as f:
330
341
  f.write(modified_shared_content)
@@ -366,8 +377,8 @@ def create_orchestrator_config(
366
377
  try:
367
378
  orchestrator_template_content = load_template("main_orchestrator.yaml")
368
379
 
369
- session_service_block_for_orchestrator = "*default_session_service"
370
- artifact_service_block_for_orchestrator = "*default_artifact_service"
380
+ formatted_name = get_formatted_names(options["agent_name"])
381
+ kebab_case_name = formatted_name.get("KEBAB_CASE_NAME")
371
382
 
372
383
  deny_list_line = ""
373
384
  if deny_list:
@@ -376,7 +387,7 @@ def create_orchestrator_config(
376
387
  .strip()
377
388
  .replace("'", '"')
378
389
  )
379
- deny_list_line = f"deny_list: {deny_list_yaml}\n "
390
+ deny_list_line = f"deny_list: {deny_list_yaml}"
380
391
 
381
392
  default_instruction = """You are the Orchestrator Agent within an AI agentic system. Your primary responsibilities are to:
382
393
  1. Process tasks received from external sources via the system Gateway.
@@ -390,8 +401,40 @@ def create_orchestrator_config(
390
401
  - You must then review the list of artifacts and return the ones that are important for the user by using the `signal_artifact_for_return` tool.
391
402
  - Provide regular progress updates using `status_update` embed directives, especially before initiating any tool call."""
392
403
 
393
- formatted_name = get_formatted_names(options["agent_name"])
394
- kebab_case_name = formatted_name.get("KEBAB_CASE_NAME")
404
+ if session_type == "sql":
405
+ session_service_lines = [
406
+ f'type: "{session_type}"',
407
+ 'database_url: "${ORCHESTRATOR_DATABASE_URL}"',
408
+ f'default_behavior: "{session_behavior}"',
409
+ ]
410
+ session_service_block = "\n" + "\n".join(
411
+ [f" {line}" for line in session_service_lines]
412
+ )
413
+
414
+ data_dir = project_root / "data"
415
+ data_dir.mkdir(exist_ok=True)
416
+ orchestrator_db_file = data_dir / "orchestrator.db"
417
+ orchestrator_database_url = f"sqlite:///{orchestrator_db_file.resolve()}"
418
+
419
+ try:
420
+ env_path = project_root / ".env"
421
+ with open(env_path, "a", encoding="utf-8") as f:
422
+ f.write(
423
+ f'\nORCHESTRATOR_DATABASE_URL="{orchestrator_database_url}"\n'
424
+ )
425
+ click.echo(
426
+ f" Added ORCHESTRATOR_DATABASE_URL to .env: {orchestrator_database_url}"
427
+ )
428
+ except Exception as e:
429
+ click.echo(
430
+ click.style(
431
+ f"Warning: Could not add ORCHESTRATOR_DATABASE_URL to .env: {e}",
432
+ fg="yellow",
433
+ ),
434
+ err=True,
435
+ )
436
+ else:
437
+ session_service_block = "*default_session_service"
395
438
 
396
439
  orchestrator_replacements = {
397
440
  "__NAMESPACE__": "${NAMESPACE}",
@@ -400,8 +443,8 @@ def create_orchestrator_config(
400
443
  "__AGENT_NAME__": options["agent_name"],
401
444
  "__LOG_FILE_NAME__": f"{kebab_case_name}.log",
402
445
  "__INSTRUCTION__": default_instruction,
403
- "__SESSION_SERVICE__": session_service_block_for_orchestrator,
404
- "__ARTIFACT_SERVICE__": artifact_service_block_for_orchestrator,
446
+ "__SESSION_SERVICE__": session_service_block,
447
+ "__ARTIFACT_SERVICE__": "*default_artifact_service",
405
448
  "__ARTIFACT_HANDLING_MODE__": artifact_handling_mode,
406
449
  "__ENABLE_EMBED_RESOLUTION__": str(enable_embed_resolution).lower(),
407
450
  "__ENABLE_ARTIFACT_CONTENT_INSTRUCTION__": str(
@@ -425,7 +468,6 @@ def create_orchestrator_config(
425
468
  )
426
469
  .strip()
427
470
  .replace("'", '"'),
428
- "__INTER_AGENT_COMMUNICATION_DENY_LIST_LINE__": deny_list_line,
429
471
  "__INTER_AGENT_COMMUNICATION_TIMEOUT__": str(
430
472
  inter_agent_communication_timeout
431
473
  ),
@@ -437,6 +479,19 @@ def create_orchestrator_config(
437
479
  placeholder, str(value)
438
480
  )
439
481
 
482
+ if deny_list:
483
+ modified_orchestrator_content = modified_orchestrator_content.replace(
484
+ "__INTER_AGENT_COMMUNICATION_DENY_LIST_LINE__",
485
+ deny_list_line,
486
+ )
487
+ else:
488
+ modified_orchestrator_content = re.sub(
489
+ r"^\s*__INTER_AGENT_COMMUNICATION_DENY_LIST_LINE__\n?$",
490
+ "",
491
+ modified_orchestrator_content,
492
+ flags=re.MULTILINE,
493
+ )
494
+
440
495
  main_orchestrator_path.parent.mkdir(parents=True, exist_ok=True)
441
496
  with open(main_orchestrator_path, "w", encoding="utf-8") as f:
442
497
  f.write(modified_orchestrator_content)
@@ -1,9 +1,10 @@
1
- import click
2
1
  import multiprocessing
3
2
  import sys
4
3
  import webbrowser
5
- from ...utils import wait_for_server
6
4
 
5
+ import click
6
+
7
+ from ...utils import wait_for_server
7
8
 
8
9
  try:
9
10
  from config_portal.backend.server import run_flask
@@ -19,7 +20,6 @@ except ImportError as e:
19
20
  sys.exit(1)
20
21
 
21
22
 
22
-
23
23
  def perform_web_init(current_cli_params: dict) -> dict:
24
24
  """
25
25
  Launches the web-based configuration portal and updates params.
@@ -55,7 +55,7 @@ def perform_web_init(current_cli_params: dict) -> dict:
55
55
  else:
56
56
  click.echo(
57
57
  click.style(
58
- f"Server did not start in time. Please check for errors and try again.",
58
+ "Server did not start in time. Please check for errors and try again.",
59
59
  fg="red",
60
60
  )
61
61
  )
@@ -67,12 +67,34 @@ def perform_web_init(current_cli_params: dict) -> dict:
67
67
  init_gui_process.join()
68
68
  if shared_config_from_web:
69
69
  config_from_portal = dict(shared_config_from_web)
70
- config_from_portal["llm_planning_model_name"] = config_from_portal.get(
71
- "llm_planning_model_name"
72
- ) or config_from_portal.get("llm_model_name")
73
- config_from_portal["llm_general_model_name"] = config_from_portal.get(
74
- "llm_general_model_name"
75
- ) or config_from_portal.get("llm_model_name")
70
+
71
+ # Map web portal keys to CLI expected keys for backwards compatibility
72
+ key_mappings = {
73
+ "llm_api_key": "llm_service_api_key",
74
+ "llm_endpoint_url": "llm_service_endpoint",
75
+ "llm_model_name": "llm_service_model_name",
76
+ }
77
+
78
+ for old_key, new_key in key_mappings.items():
79
+ if old_key in config_from_portal and new_key not in config_from_portal:
80
+ config_from_portal[new_key] = config_from_portal[old_key]
81
+
82
+ # Handle planning and general model names with fallback to single model name
83
+ config_from_portal["llm_service_planning_model_name"] = (
84
+ config_from_portal.get("llm_service_planning_model_name")
85
+ or config_from_portal.get("llm_planning_model_name")
86
+ or config_from_portal.get("llm_model_name")
87
+ )
88
+
89
+ config_from_portal["llm_service_general_model_name"] = (
90
+ config_from_portal.get("llm_service_general_model_name")
91
+ or config_from_portal.get("llm_general_model_name")
92
+ or config_from_portal.get("llm_model_name")
93
+ )
94
+
95
+ # Clean up deprecated keys if new keys are present
96
+ config_from_portal.pop("llm_planning_model_name", None)
97
+ config_from_portal.pop("llm_general_model_name", None)
76
98
 
77
99
  click.echo(
78
100
  click.style("Configuration received from web portal.", fg="green")
@@ -3,14 +3,15 @@ from pathlib import Path
3
3
 
4
4
  from ...utils import ask_if_not_provided, ask_yes_no_question, load_template
5
5
 
6
+
6
7
  WEBUI_GATEWAY_DEFAULTS = {
7
8
  "webui_frontend_welcome_message": "",
8
9
  "webui_frontend_bot_name": "Solace Agent Mesh",
9
10
  "webui_frontend_collect_feedback": False,
10
11
  "webui_session_secret_key": "please_change_me_in",
11
12
  "webui_fastapi_host": "127.0.0.1",
12
- "webui_fastapi_port": 8000, # Store as int if CLI option is int
13
- "webui_fastapi_https_port": 8443, # Store as int if CLI option is int
13
+ "webui_fastapi_port": 8000,
14
+ "webui_fastapi_https_port": 8443,
14
15
  "webui_ssl_keyfile": "",
15
16
  "webui_ssl_certfile": "",
16
17
  "webui_ssl_keyfile_password": "",
@@ -39,6 +40,10 @@ def create_webui_gateway_config(
39
40
 
40
41
  options["add_webui_gateway"] = add_gateway
41
42
 
43
+ if not add_gateway:
44
+ click.echo(click.style(" Skipping Web UI Gateway file creation.", fg="yellow"))
45
+ return True
46
+
42
47
  options["webui_session_secret_key"] = ask_if_not_provided(
43
48
  options,
44
49
  "webui_session_secret_key",
@@ -69,9 +74,11 @@ def create_webui_gateway_config(
69
74
  none_interactive=skip_interactive,
70
75
  )
71
76
  options["webui_fastapi_https_port"] = ask_if_not_provided(
72
- options, "webui_fastapi_https_port", "Enter Web UI FastAPI HTTPS Port",
77
+ options,
78
+ "webui_fastapi_https_port",
79
+ "Enter Web UI FastAPI HTTPS Port",
73
80
  default=default_values.get("webui_fastapi_https_port", 8443),
74
- none_interactive=skip_interactive
81
+ none_interactive=skip_interactive,
75
82
  )
76
83
  options["webui_enable_embed_resolution"] = ask_if_not_provided(
77
84
  options,
@@ -85,19 +92,26 @@ def create_webui_gateway_config(
85
92
  is_bool=True,
86
93
  )
87
94
  options["webui_ssl_keyfile"] = ask_if_not_provided(
88
- options, "webui_ssl_keyfile", "Enter SSL Key File Path",
95
+ options,
96
+ "webui_ssl_keyfile",
97
+ "Enter SSL Key File Path",
89
98
  default=default_values.get("webui_ssl_keyfile", ""),
90
- none_interactive=skip_interactive
99
+ none_interactive=skip_interactive,
91
100
  )
92
101
  options["webui_ssl_certfile"] = ask_if_not_provided(
93
- options, "webui_ssl_certfile", "Enter SSL Certificate File Path",
102
+ options,
103
+ "webui_ssl_certfile",
104
+ "Enter SSL Certificate File Path",
94
105
  default=default_values.get("webui_ssl_certfile", ""),
95
- none_interactive=skip_interactive
106
+ none_interactive=skip_interactive,
96
107
  )
97
108
  options["webui_ssl_keyfile_password"] = ask_if_not_provided(
98
- options, "webui_ssl_keyfile_password", "Enter SSL Key File Passphrase",
109
+ options,
110
+ "webui_ssl_keyfile_password",
111
+ "Enter SSL Key File Passphrase",
99
112
  default=default_values.get("webui_ssl_keyfile_password", ""),
100
- none_interactive=skip_interactive, hide_input=True
113
+ none_interactive=skip_interactive,
114
+ hide_input=True,
101
115
  )
102
116
 
103
117
  options["webui_frontend_welcome_message"] = ask_if_not_provided(
@@ -131,15 +145,58 @@ def create_webui_gateway_config(
131
145
  is_bool=True,
132
146
  )
133
147
 
134
- if not add_gateway:
135
- click.echo(click.style(" Skipping Web UI Gateway file creation.", fg="yellow"))
136
- return True
148
+ session_type = ask_if_not_provided(
149
+ options,
150
+ "webui_session_service_type",
151
+ "Enter WebUI session service type",
152
+ "sql",
153
+ skip_interactive,
154
+ choices=["sql", "memory"],
155
+ )
156
+
157
+ session_behavior = ask_if_not_provided(
158
+ options,
159
+ "webui_session_service_behavior",
160
+ "Enter WebUI session service behavior",
161
+ "PERSISTENT",
162
+ skip_interactive,
163
+ choices=["PERSISTENT", "RUN_BASED"],
164
+ )
137
165
 
138
166
  click.echo("Creating Web UI Gateway configuration file...")
139
167
  destination_path = project_root / "configs" / "gateways" / "webui.yaml"
140
168
 
141
169
  try:
142
170
  template_content = load_template("webui.yaml")
171
+
172
+ if session_type == "sql":
173
+ session_service_lines = [
174
+ f'type: "{session_type}"',
175
+ f'database_url: "${{WEB_UI_GATEWAY_DATABASE_URL}}"',
176
+ f'default_behavior: "{session_behavior}"',
177
+ ]
178
+ session_service_block = "\n" + "\n".join(
179
+ [f" {line}" for line in session_service_lines]
180
+ )
181
+
182
+ data_dir = project_root / "data"
183
+ data_dir.mkdir(exist_ok=True)
184
+ webui_db_file = data_dir / "webui_gateway.db"
185
+ webui_database_url = f"sqlite:///{webui_db_file.resolve()}"
186
+
187
+ try:
188
+ env_path = project_root / ".env"
189
+ with open(env_path, "a", encoding="utf-8") as f:
190
+ f.write(f'\nWEB_UI_GATEWAY_DATABASE_URL="{webui_database_url}"\n')
191
+ click.echo(f" Added WEB_UI_GATEWAY_DATABASE_URL to .env: {webui_database_url}")
192
+ except Exception as e:
193
+ click.echo(
194
+ click.style(f"Warning: Could not add WEB_UI_GATEWAY_DATABASE_URL to .env: {e}", fg="yellow"),
195
+ err=True,
196
+ )
197
+ else:
198
+ session_service_block = "*default_session_service"
199
+
143
200
  replacements = {
144
201
  "__FRONTEND_WELCOME_MESSAGE__": str(
145
202
  options.get("webui_frontend_welcome_message", "")
@@ -150,11 +207,13 @@ def create_webui_gateway_config(
150
207
  "__FRONTEND_COLLECT_FEEDBACK__": str(
151
208
  options.get("webui_frontend_collect_feedback", False)
152
209
  ).lower(),
210
+ "__SESSION_SERVICE__": session_service_block,
153
211
  }
154
212
 
155
213
  modified_content = template_content
156
214
  for placeholder, value in replacements.items():
157
- modified_content = modified_content.replace(placeholder, value)
215
+ if value is not None:
216
+ modified_content = modified_content.replace(placeholder, str(value))
158
217
 
159
218
  destination_path.parent.mkdir(parents=True, exist_ok=True)
160
219
  with open(destination_path, "w", encoding="utf-8") as f:
@@ -164,7 +223,7 @@ def create_webui_gateway_config(
164
223
  return True
165
224
 
166
225
  except FileNotFoundError:
167
- click.echo(click.style(f"Error: Template file not found.", fg="red"), err=True)
226
+ click.echo(click.style("Error: Template file not found.", fg="red"), err=True)
168
227
  return False
169
228
  except IOError as e:
170
229
  click.echo(
@@ -18,12 +18,10 @@ DEFAULT_PLUGIN_VERSION = "0.1.0"
18
18
 
19
19
 
20
20
  def ensure_directory_exists(path: pathlib.Path):
21
- """Creates a directory if it doesn't exist."""
22
21
  path.mkdir(parents=True, exist_ok=True)
23
22
 
24
23
 
25
24
  def replace_placeholders(content: str, replacements: dict) -> str:
26
- """Replaces placeholders in a string."""
27
25
  for placeholder, value in replacements.items():
28
26
  content = content.replace(placeholder, str(value))
29
27
  return content
@@ -1,8 +1,10 @@
1
- import click
2
1
  import os
3
2
  import sys
4
3
  from pathlib import Path
5
- from dotenv import load_dotenv, find_dotenv
4
+
5
+ import click
6
+ from dotenv import find_dotenv, load_dotenv
7
+
6
8
  from cli.utils import error_exit
7
9
  from solace_agent_mesh.common.utils.initializer import initialize
8
10
 
@@ -110,7 +112,7 @@ def run(files: tuple[str, ...], skip_files: tuple[str, ...], system_env: bool):
110
112
  ),
111
113
  err=True,
112
114
  )
113
- return 1
115
+ sys.exit(1)
114
116
 
115
117
  for filepath in configs_dir.rglob("*.yaml"):
116
118
  if filepath.name.startswith("_") or filepath.name.startswith(