solace-agent-mesh 0.0.1__py3-none-any.whl → 0.1.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 (176) hide show
  1. solace_agent_mesh/__init__.py +0 -3
  2. solace_agent_mesh/agents/__init__.py +0 -0
  3. solace_agent_mesh/agents/base_agent_component.py +224 -0
  4. solace_agent_mesh/agents/global/__init__.py +0 -0
  5. solace_agent_mesh/agents/global/actions/__init__.py +0 -0
  6. solace_agent_mesh/agents/global/actions/agent_state_change.py +54 -0
  7. solace_agent_mesh/agents/global/actions/clear_history.py +32 -0
  8. solace_agent_mesh/agents/global/actions/convert_file_to_markdown.py +160 -0
  9. solace_agent_mesh/agents/global/actions/create_file.py +70 -0
  10. solace_agent_mesh/agents/global/actions/error_action.py +45 -0
  11. solace_agent_mesh/agents/global/actions/plantuml_diagram.py +93 -0
  12. solace_agent_mesh/agents/global/actions/plotly_graph.py +117 -0
  13. solace_agent_mesh/agents/global/actions/retrieve_file.py +51 -0
  14. solace_agent_mesh/agents/global/global_agent_component.py +38 -0
  15. solace_agent_mesh/agents/image_processing/__init__.py +0 -0
  16. solace_agent_mesh/agents/image_processing/actions/__init__.py +0 -0
  17. solace_agent_mesh/agents/image_processing/actions/create_image.py +75 -0
  18. solace_agent_mesh/agents/image_processing/actions/describe_image.py +115 -0
  19. solace_agent_mesh/agents/image_processing/image_processing_agent_component.py +23 -0
  20. solace_agent_mesh/agents/slack/__init__.py +1 -0
  21. solace_agent_mesh/agents/slack/actions/__init__.py +1 -0
  22. solace_agent_mesh/agents/slack/actions/post_message.py +177 -0
  23. solace_agent_mesh/agents/slack/slack_agent_component.py +59 -0
  24. solace_agent_mesh/agents/web_request/__init__.py +0 -0
  25. solace_agent_mesh/agents/web_request/actions/__init__.py +0 -0
  26. solace_agent_mesh/agents/web_request/actions/do_image_search.py +84 -0
  27. solace_agent_mesh/agents/web_request/actions/do_news_search.py +47 -0
  28. solace_agent_mesh/agents/web_request/actions/do_suggestion_search.py +34 -0
  29. solace_agent_mesh/agents/web_request/actions/do_web_request.py +134 -0
  30. solace_agent_mesh/agents/web_request/actions/download_file.py +69 -0
  31. solace_agent_mesh/agents/web_request/web_request_agent_component.py +33 -0
  32. solace_agent_mesh/assets/web-visualizer/assets/index-C5awueeJ.js +109 -0
  33. solace_agent_mesh/assets/web-visualizer/assets/index-D0qORgkg.css +1 -0
  34. solace_agent_mesh/assets/web-visualizer/index.html +14 -0
  35. solace_agent_mesh/assets/web-visualizer/vite.svg +1 -0
  36. solace_agent_mesh/cli/__init__.py +1 -0
  37. solace_agent_mesh/cli/commands/__init__.py +0 -0
  38. solace_agent_mesh/cli/commands/add/__init__.py +3 -0
  39. solace_agent_mesh/cli/commands/add/add.py +88 -0
  40. solace_agent_mesh/cli/commands/add/agent.py +110 -0
  41. solace_agent_mesh/cli/commands/add/copy_from_plugin.py +90 -0
  42. solace_agent_mesh/cli/commands/add/gateway.py +221 -0
  43. solace_agent_mesh/cli/commands/build.py +631 -0
  44. solace_agent_mesh/cli/commands/chat/__init__.py +3 -0
  45. solace_agent_mesh/cli/commands/chat/chat.py +361 -0
  46. solace_agent_mesh/cli/commands/config.py +29 -0
  47. solace_agent_mesh/cli/commands/init/__init__.py +3 -0
  48. solace_agent_mesh/cli/commands/init/ai_provider_step.py +76 -0
  49. solace_agent_mesh/cli/commands/init/broker_step.py +102 -0
  50. solace_agent_mesh/cli/commands/init/builtin_agent_step.py +88 -0
  51. solace_agent_mesh/cli/commands/init/check_if_already_done.py +13 -0
  52. solace_agent_mesh/cli/commands/init/create_config_file_step.py +52 -0
  53. solace_agent_mesh/cli/commands/init/create_other_project_files_step.py +96 -0
  54. solace_agent_mesh/cli/commands/init/file_service_step.py +73 -0
  55. solace_agent_mesh/cli/commands/init/init.py +114 -0
  56. solace_agent_mesh/cli/commands/init/project_structure_step.py +45 -0
  57. solace_agent_mesh/cli/commands/init/rest_api_step.py +50 -0
  58. solace_agent_mesh/cli/commands/init/web_ui_step.py +40 -0
  59. solace_agent_mesh/cli/commands/plugin/__init__.py +3 -0
  60. solace_agent_mesh/cli/commands/plugin/add.py +98 -0
  61. solace_agent_mesh/cli/commands/plugin/build.py +217 -0
  62. solace_agent_mesh/cli/commands/plugin/create.py +117 -0
  63. solace_agent_mesh/cli/commands/plugin/plugin.py +109 -0
  64. solace_agent_mesh/cli/commands/plugin/remove.py +71 -0
  65. solace_agent_mesh/cli/commands/run.py +68 -0
  66. solace_agent_mesh/cli/commands/visualizer.py +138 -0
  67. solace_agent_mesh/cli/config.py +81 -0
  68. solace_agent_mesh/cli/main.py +306 -0
  69. solace_agent_mesh/cli/utils.py +246 -0
  70. solace_agent_mesh/common/__init__.py +0 -0
  71. solace_agent_mesh/common/action.py +91 -0
  72. solace_agent_mesh/common/action_list.py +37 -0
  73. solace_agent_mesh/common/action_response.py +327 -0
  74. solace_agent_mesh/common/constants.py +3 -0
  75. solace_agent_mesh/common/mysql_database.py +40 -0
  76. solace_agent_mesh/common/postgres_database.py +79 -0
  77. solace_agent_mesh/common/prompt_templates.py +30 -0
  78. solace_agent_mesh/common/prompt_templates_unused_delete.py +161 -0
  79. solace_agent_mesh/common/stimulus_utils.py +152 -0
  80. solace_agent_mesh/common/time.py +24 -0
  81. solace_agent_mesh/common/utils.py +638 -0
  82. solace_agent_mesh/configs/agent_global.yaml +74 -0
  83. solace_agent_mesh/configs/agent_image_processing.yaml +82 -0
  84. solace_agent_mesh/configs/agent_slack.yaml +64 -0
  85. solace_agent_mesh/configs/agent_web_request.yaml +75 -0
  86. solace_agent_mesh/configs/conversation_to_file.yaml +56 -0
  87. solace_agent_mesh/configs/error_catcher.yaml +56 -0
  88. solace_agent_mesh/configs/monitor.yaml +0 -0
  89. solace_agent_mesh/configs/monitor_stim_and_errors_to_slack.yaml +106 -0
  90. solace_agent_mesh/configs/monitor_user_feedback.yaml +58 -0
  91. solace_agent_mesh/configs/orchestrator.yaml +241 -0
  92. solace_agent_mesh/configs/service_embedding.yaml +81 -0
  93. solace_agent_mesh/configs/service_llm.yaml +265 -0
  94. solace_agent_mesh/configs/visualize_websocket.yaml +55 -0
  95. solace_agent_mesh/gateway/__init__.py +0 -0
  96. solace_agent_mesh/gateway/components/__init__.py +0 -0
  97. solace_agent_mesh/gateway/components/gateway_base.py +41 -0
  98. solace_agent_mesh/gateway/components/gateway_input.py +265 -0
  99. solace_agent_mesh/gateway/components/gateway_output.py +289 -0
  100. solace_agent_mesh/gateway/identity/bamboohr_identity.py +18 -0
  101. solace_agent_mesh/gateway/identity/identity_base.py +10 -0
  102. solace_agent_mesh/gateway/identity/identity_provider.py +60 -0
  103. solace_agent_mesh/gateway/identity/no_identity.py +9 -0
  104. solace_agent_mesh/gateway/identity/passthru_identity.py +9 -0
  105. solace_agent_mesh/monitors/base_monitor_component.py +26 -0
  106. solace_agent_mesh/monitors/feedback/user_feedback_monitor.py +75 -0
  107. solace_agent_mesh/monitors/stim_and_errors/stim_and_error_monitor.py +560 -0
  108. solace_agent_mesh/orchestrator/__init__.py +0 -0
  109. solace_agent_mesh/orchestrator/action_manager.py +225 -0
  110. solace_agent_mesh/orchestrator/components/__init__.py +0 -0
  111. solace_agent_mesh/orchestrator/components/orchestrator_action_manager_timeout_component.py +54 -0
  112. solace_agent_mesh/orchestrator/components/orchestrator_action_response_component.py +179 -0
  113. solace_agent_mesh/orchestrator/components/orchestrator_register_component.py +107 -0
  114. solace_agent_mesh/orchestrator/components/orchestrator_stimulus_processor_component.py +477 -0
  115. solace_agent_mesh/orchestrator/components/orchestrator_streaming_output_component.py +246 -0
  116. solace_agent_mesh/orchestrator/orchestrator_main.py +166 -0
  117. solace_agent_mesh/orchestrator/orchestrator_prompt.py +410 -0
  118. solace_agent_mesh/services/__init__.py +0 -0
  119. solace_agent_mesh/services/authorization/providers/base_authorization_provider.py +56 -0
  120. solace_agent_mesh/services/bamboo_hr_service/__init__.py +3 -0
  121. solace_agent_mesh/services/bamboo_hr_service/bamboo_hr.py +182 -0
  122. solace_agent_mesh/services/common/__init__.py +4 -0
  123. solace_agent_mesh/services/common/auto_expiry.py +45 -0
  124. solace_agent_mesh/services/common/singleton.py +18 -0
  125. solace_agent_mesh/services/file_service/__init__.py +14 -0
  126. solace_agent_mesh/services/file_service/file_manager/__init__.py +0 -0
  127. solace_agent_mesh/services/file_service/file_manager/bucket_file_manager.py +149 -0
  128. solace_agent_mesh/services/file_service/file_manager/file_manager_base.py +162 -0
  129. solace_agent_mesh/services/file_service/file_manager/memory_file_manager.py +64 -0
  130. solace_agent_mesh/services/file_service/file_manager/volume_file_manager.py +106 -0
  131. solace_agent_mesh/services/file_service/file_service.py +432 -0
  132. solace_agent_mesh/services/file_service/file_service_constants.py +54 -0
  133. solace_agent_mesh/services/file_service/file_transformations.py +131 -0
  134. solace_agent_mesh/services/file_service/file_utils.py +322 -0
  135. solace_agent_mesh/services/file_service/transformers/__init__.py +5 -0
  136. solace_agent_mesh/services/history_service/__init__.py +3 -0
  137. solace_agent_mesh/services/history_service/history_providers/__init__.py +0 -0
  138. solace_agent_mesh/services/history_service/history_providers/base_history_provider.py +78 -0
  139. solace_agent_mesh/services/history_service/history_providers/memory_history_provider.py +167 -0
  140. solace_agent_mesh/services/history_service/history_providers/redis_history_provider.py +163 -0
  141. solace_agent_mesh/services/history_service/history_service.py +139 -0
  142. solace_agent_mesh/services/llm_service/components/llm_request_component.py +293 -0
  143. solace_agent_mesh/services/llm_service/components/llm_service_component_base.py +152 -0
  144. solace_agent_mesh/services/middleware_service/__init__.py +0 -0
  145. solace_agent_mesh/services/middleware_service/middleware_service.py +20 -0
  146. solace_agent_mesh/templates/action.py +38 -0
  147. solace_agent_mesh/templates/agent.py +29 -0
  148. solace_agent_mesh/templates/agent.yaml +70 -0
  149. solace_agent_mesh/templates/gateway-config-template.yaml +6 -0
  150. solace_agent_mesh/templates/gateway-default-config.yaml +28 -0
  151. solace_agent_mesh/templates/gateway-flows.yaml +81 -0
  152. solace_agent_mesh/templates/gateway-header.yaml +16 -0
  153. solace_agent_mesh/templates/gateway_base.py +15 -0
  154. solace_agent_mesh/templates/gateway_input.py +98 -0
  155. solace_agent_mesh/templates/gateway_output.py +71 -0
  156. solace_agent_mesh/templates/plugin-pyproject.toml +30 -0
  157. solace_agent_mesh/templates/rest-api-default-config.yaml +24 -0
  158. solace_agent_mesh/templates/rest-api-flows.yaml +80 -0
  159. solace_agent_mesh/templates/slack-default-config.yaml +9 -0
  160. solace_agent_mesh/templates/slack-flows.yaml +90 -0
  161. solace_agent_mesh/templates/solace-agent-mesh-default.yaml +77 -0
  162. solace_agent_mesh/templates/solace-agent-mesh-plugin-default.yaml +8 -0
  163. solace_agent_mesh/templates/web-default-config.yaml +5 -0
  164. solace_agent_mesh/templates/web-flows.yaml +86 -0
  165. solace_agent_mesh/tools/__init__.py +0 -0
  166. solace_agent_mesh/tools/components/__init__.py +0 -0
  167. solace_agent_mesh/tools/components/conversation_formatter.py +111 -0
  168. solace_agent_mesh/tools/components/file_resolver_component.py +58 -0
  169. solace_agent_mesh/tools/config/runtime_config.py +26 -0
  170. solace_agent_mesh-0.1.1.dist-info/METADATA +179 -0
  171. solace_agent_mesh-0.1.1.dist-info/RECORD +174 -0
  172. solace_agent_mesh-0.1.1.dist-info/entry_points.txt +3 -0
  173. solace_agent_mesh-0.0.1.dist-info/licenses/LICENSE.txt → solace_agent_mesh-0.1.1.dist-info/licenses/LICENSE +1 -2
  174. solace_agent_mesh-0.0.1.dist-info/METADATA +0 -51
  175. solace_agent_mesh-0.0.1.dist-info/RECORD +0 -5
  176. {solace_agent_mesh-0.0.1.dist-info → solace_agent_mesh-0.1.1.dist-info}/WHEEL +0 -0
@@ -0,0 +1,52 @@
1
+ import click
2
+
3
+ from cli.config import Config
4
+
5
+
6
+ def create_config_file_step(options, default_options, none_interactive, abort):
7
+ """
8
+ Creates the configuration files.
9
+ """
10
+ sam_config = Config.get_default_config()
11
+
12
+ # Set up the built-in agents
13
+ builtin_agents_ref = (
14
+ sam_config.get("solace_agent_mesh", {}).get("built_in", {}).get("agents", [])
15
+ )
16
+ builtin_agents = options.get("built_in_agent", [])
17
+ for agent in builtin_agents_ref:
18
+ agent["enabled"] = agent["name"] in builtin_agents or agent["name"] == "global"
19
+
20
+ # Set up the project structure
21
+ sam_config.get("solace_agent_mesh", {})["config_directory"] = options.get("config_dir")
22
+ sam_config.get("solace_agent_mesh", {})["modules_directory"] = options.get("module_dir")
23
+ sam_config.get("solace_agent_mesh", {})["env_file"] = options.get("env_file")
24
+ sam_config.get("solace_agent_mesh", {}).get("build", {})["build_directory"] = (
25
+ options.get("build_dir")
26
+ )
27
+
28
+ # Set up the file service
29
+ file_service_ref = (
30
+ sam_config.get("solace_agent_mesh", {})
31
+ .get("runtime", {})
32
+ .get("services", {})
33
+ .get("file_service", {})
34
+ )
35
+ provider = options.get("file_service_provider")
36
+ file_service_ref["type"] = provider
37
+ if "config" not in file_service_ref:
38
+ file_service_ref["config"] = {}
39
+ if provider not in file_service_ref["config"]:
40
+ file_service_ref["config"][provider] = {}
41
+ for pair in options.get("file_service_config", []):
42
+ if "=" not in pair:
43
+ continue
44
+ key, value = pair.split("=")
45
+ file_service_ref["config"][provider][key] = value
46
+
47
+ Config.write_config(sam_config)
48
+ click.echo("Project files have been created.")
49
+
50
+ #update context (this is needed for add_gateway_command to work properly in the next step)
51
+ ctx = click.get_current_context()
52
+ ctx.obj['solace_agent_mesh'] = sam_config['solace_agent_mesh']
@@ -0,0 +1,96 @@
1
+ import os
2
+ from cli.commands.add.gateway import add_gateway_command
3
+
4
+ def create_if_not_exists(file_path, content):
5
+ if not os.path.exists(file_path):
6
+ with open(file_path, "w", encoding="utf-8") as f:
7
+ f.write(content)
8
+
9
+
10
+ def add_pair_to_file_if_not_exists(file_path, pairs):
11
+ with open(file_path, "r", encoding="utf-8") as f:
12
+ content = f.read()
13
+
14
+ for key, value in pairs:
15
+ if key not in content:
16
+ with open(file_path, "a", encoding="utf-8") as f:
17
+ f.write(f"{key}{value}\n")
18
+
19
+
20
+ def create_other_project_files_step(options, default_options, none_interactive, abort):
21
+ """
22
+ Creates the other project files. i.e. .gitignore, .env, requirements.txt, etc.
23
+ """
24
+ # Create .gitignore file
25
+ ignore = (
26
+ "*.pyc\n"
27
+ "__pycache__\n"
28
+ ".env\n"
29
+ ".venv\n"
30
+ "env/\n"
31
+ "venv/\n"
32
+ "log\n"
33
+ f"{options['env_file']}\n"
34
+ f"{options['build_dir']}\n"
35
+ )
36
+ create_if_not_exists(".gitignore", ignore)
37
+
38
+ # Create requirements.txt file
39
+ required_dependencies = [
40
+ ("solace-agent-mesh", "~=0.1.0"),
41
+ ]
42
+ create_if_not_exists("requirements.txt", "")
43
+ add_pair_to_file_if_not_exists("requirements.txt", required_dependencies)
44
+
45
+ # Create .env file
46
+ required_env_variables = [
47
+ ("SOLACE_AGENT_MESH_NAMESPACE", f"={options['namespace']}"),
48
+ ("SOLACE_DEV_MODE", f"={options['dev_mode']}"),
49
+ ("SOLACE_BROKER_URL", f"={options['broker_url']}"),
50
+ ("SOLACE_BROKER_VPN", f"={options['broker_vpn']}"),
51
+ ("SOLACE_BROKER_USERNAME", f"={options['broker_username']}"),
52
+ ("SOLACE_BROKER_PASSWORD", f"={options['broker_password']}"),
53
+ ("LLM_SERVICE_API_KEY", f"={options['llm_api_key']}"),
54
+ ("LLM_SERVICE_ENDPOINT", f"={options['llm_endpoint_url']}"),
55
+ ("LLM_SERVICE_PLANNING_MODEL_NAME", f"={options['llm_model_name']}"),
56
+ ("EMBEDDING_SERVICE_MODEL_NAME", f"={options['embedding_model_name']}"),
57
+ ("EMBEDDING_SERVICE_API_KEY", f"={options['embedding_api_key']}"),
58
+ ("EMBEDDING_SERVICE_ENDPOINT", f"={options['embedding_endpoint_url']}"),
59
+ ("RUNTIME_CONFIG_PATH", f"={options['build_dir']}/config.yaml"),
60
+ ]
61
+
62
+ if options.get("rest_api_enabled"):
63
+ #REST API env variables
64
+ rest_api_env_variables = [
65
+ ("REST_API_SERVER_INPUT_PORT", f"={options.get('rest_api_server_input_port', '')}"),
66
+ ("REST_API_SERVER_HOST", f"={options.get('rest_api_server_host', '')}"),
67
+ ("REST_API_SERVER_INPUT_ENDPOINT", f"={options.get('rest_api_server_input_endpoint', '')}"),
68
+ ]
69
+
70
+ required_env_variables.extend(rest_api_env_variables)
71
+
72
+ if options.get("webui_enabled"):
73
+ webui_env_variables = [
74
+ #Web UI env variables
75
+ ("WEBUI_ENABLED", f"={options['webui_enabled']}"),
76
+ ("WEBUI_PORT", f"={options['webui_listen_port']}"),
77
+ ("WEBUI_HOST", f"={options['webui_host']}"),
78
+ ("WEBUI_RESPONSE_API_URL", f"=http://{options['rest_api_server_host']}:{options['rest_api_server_input_port']}{options['rest_api_server_input_endpoint']}"),
79
+ ("WEBUI_FRONTEND_SERVER_URL", f"=http://{options['webui_host']}:{options['webui_listen_port']}"),
80
+ ("WEBUI_FRONTEND_URL", f"=http://{options['webui_host']}:{options['webui_listen_port']}"),
81
+ ]
82
+
83
+ required_env_variables.extend(webui_env_variables)
84
+
85
+ env_var_list = [
86
+ *default_options.get("env_var", []),
87
+ *list(options.get("env_var", [])),
88
+ ]
89
+ for env_var in env_var_list:
90
+ if "=" in env_var:
91
+ key, value = env_var.split("=")
92
+ required_env_variables.append((key, f"={value}"))
93
+
94
+ create_if_not_exists(options["env_file"], "")
95
+ add_pair_to_file_if_not_exists(options["env_file"], required_env_variables)
96
+ add_gateway_command(options["rest_api_gateway_name"],["rest-api"])
@@ -0,0 +1,73 @@
1
+ import click
2
+
3
+ from cli.utils import ask_if_not_provided, get_display_path
4
+
5
+
6
+ def file_service_step(options, default_options, none_interactive, abort):
7
+ """
8
+ Initialize the file service.
9
+ """
10
+ provider = ask_if_not_provided(
11
+ options,
12
+ "file_service_provider",
13
+ (
14
+ "Choose a file service provider\n"
15
+ "\t- Volume: Use a local volume (directory) to store files\n"
16
+ "\t- Bucket: Use a cloud bucket to store files (Must use AWS S3 API)\n"
17
+ "Enter the provider"
18
+ ),
19
+ default_options["file_service_provider"],
20
+ none_interactive,
21
+ ("volume", "bucket"),
22
+ )
23
+
24
+ configs = {}
25
+ if "file_service_config" in options and options["file_service_config"]:
26
+ config_list = list(options["file_service_config"])
27
+ for config in config_list:
28
+ if "=" in config:
29
+ key, value = config.split("=")
30
+ configs[key] = value
31
+
32
+ default_config = {
33
+ "directory": "/tmp/solace-agent-mesh"
34
+ }
35
+ for config in default_options["file_service_config"]:
36
+ if "=" in config:
37
+ key, value = config.split("=")
38
+ default_config[key] = value
39
+
40
+ if provider == "volume":
41
+ ask_if_not_provided(
42
+ configs,
43
+ "directory",
44
+ "Provide the path to the volume directory",
45
+ default_config.get("directory"),
46
+ none_interactive,
47
+ )
48
+ elif provider == "bucket":
49
+ ask_if_not_provided(
50
+ configs,
51
+ "bucket_name",
52
+ "Provide the name of the bucket",
53
+ default_config.get("bucket_name"),
54
+ none_interactive,
55
+ )
56
+ # endpoint_url
57
+ ask_if_not_provided(
58
+ configs,
59
+ "endpoint_url",
60
+ "Provide the endpoint URL",
61
+ default_config.get("endpoint_url", ""),
62
+ none_interactive,
63
+ )
64
+ click.echo(
65
+ click.style(
66
+ f"You can setup the Boto3 authentication configuration in the {get_display_path('solace-agent-mesh.yaml')} file",
67
+ fg="yellow",
68
+ )
69
+ )
70
+
71
+ options["file_service_config"] = [
72
+ f"{key}={value}" for key, value in configs.items()
73
+ ]
@@ -0,0 +1,114 @@
1
+ import click
2
+ import sys
3
+
4
+ from .check_if_already_done import check_if_already_done
5
+ from .ai_provider_step import ai_provider_step
6
+ from .broker_step import broker_step
7
+ from .builtin_agent_step import builtin_agent_step
8
+ from .create_config_file_step import create_config_file_step
9
+ from .file_service_step import file_service_step
10
+ from .project_structure_step import project_structure_step
11
+ from .create_other_project_files_step import create_other_project_files_step
12
+ from .rest_api_step import rest_api_step
13
+ from .web_ui_step import webui_step
14
+
15
+ from cli.utils import (
16
+ log_error,
17
+ )
18
+
19
+ default_options = {
20
+ "namespace": "",
21
+ "config_dir": "configs",
22
+ "module_dir": "modules",
23
+ "env_file": ".env",
24
+ "build_dir": "build",
25
+ "broker_type": "container",
26
+ "broker_url": "ws://localhost:8008",
27
+ "broker_vpn": "default",
28
+ "broker_username": "default",
29
+ "broker_password": "default",
30
+ "container_engine": "docker",
31
+ "llm_model_name": "openai/gpt-4o",
32
+ "llm_endpoint_url": "https://api.openai.com/v1",
33
+ "llm_api_key": "",
34
+ "embedding_model_name": "openai/text-embedding-ada-002",
35
+ "embedding_endpoint_url": "https://api.openai.com/v1",
36
+ "embedding_api_key": "",
37
+ "built_in_agent": [],
38
+ "file_service_provider": "volume",
39
+ "file_service_config": ["volume=/tmp/solace-agent-mesh"],
40
+ "env_var": [],
41
+ "rest_api_enabled": True,
42
+ "rest_api_server_input_port": "5050",
43
+ "rest_api_server_host": "127.0.0.1",
44
+ "rest_api_server_input_endpoint": "/api/v1/request",
45
+ "rest_api_gateway_name": "rest-api",
46
+ "webui_enabled": True,
47
+ "webui_listen_port": "5001",
48
+ "webui_host": "localhost"
49
+ }
50
+ """
51
+ Default options for the init command.
52
+ """
53
+
54
+
55
+ def abort(message: str):
56
+ """Abort the init and cleanup"""
57
+ log_error(f"Init failed: {message}.")
58
+ # os.system(f"rm -rf {build_dir}")
59
+ sys.exit(1)
60
+
61
+
62
+ def init_command(options={}):
63
+ """
64
+ Initialize the Solace Agent Mesh application.
65
+ """
66
+ click.echo(click.style("Initializing Solace Agent Mesh", bold=True, fg="blue"))
67
+ skip = False
68
+ if "skip" in options and options["skip"]:
69
+ skip = True
70
+
71
+ # no description for hidden steps
72
+ steps = [
73
+ ("", check_if_already_done),
74
+ ("Project structure setup", project_structure_step),
75
+ ("Broker setup", broker_step),
76
+ ("AI provider setup", ai_provider_step),
77
+ ("Builtin agent setup", builtin_agent_step),
78
+ ("File service setup", file_service_step),
79
+ ("REST API setup", rest_api_step),
80
+ ("Web UI setup", webui_step),
81
+ ("", create_config_file_step),
82
+ ("Setting up project", create_other_project_files_step),
83
+ ]
84
+ non_hidden_steps_count = len([step for step in steps if step[0]])
85
+
86
+ step = 0
87
+ try:
88
+ for name, function in steps:
89
+ if name:
90
+ step += 1
91
+ click.echo(
92
+ click.style(
93
+ f"Step {step} of {non_hidden_steps_count}: {name}", fg="blue"
94
+ )
95
+ )
96
+ function(options, default_options, skip, abort)
97
+ except KeyboardInterrupt:
98
+ abort("\n\nAborted by user")
99
+
100
+ click.echo(click.style("Solace Agent Mesh has been initialized", fg="green"))
101
+
102
+ if not skip:
103
+ click.echo(
104
+ click.style(
105
+ "Review the `solace-agent-mesh` config file and make any necessary changes.",
106
+ fg="yellow",
107
+ )
108
+ )
109
+ click.echo(
110
+ click.style(
111
+ "To get started, use the `solace-agent-mesh add` command to add agents and gateways",
112
+ fg="blue",
113
+ )
114
+ )
@@ -0,0 +1,45 @@
1
+ from cli.utils import ask_if_not_provided
2
+
3
+
4
+ def project_structure_step(options, default_options, none_interactive, abort):
5
+ """
6
+ Initialize the project structure.
7
+ """
8
+ namespace = ask_if_not_provided(
9
+ options,
10
+ "namespace",
11
+ "Enter a namespace for the project (It will be used as the topic prefix for all events.)",
12
+ default_options["namespace"],
13
+ none_interactive,
14
+ )
15
+ if namespace and not namespace.endswith("/"):
16
+ options["namespace"] = f"{namespace}/"
17
+
18
+ ask_if_not_provided(
19
+ options,
20
+ "config_dir",
21
+ "Enter base directory for config files",
22
+ default_options["config_dir"],
23
+ none_interactive,
24
+ )
25
+ ask_if_not_provided(
26
+ options,
27
+ "module_dir",
28
+ "Enter base directory for python modules",
29
+ default_options["module_dir"],
30
+ none_interactive,
31
+ )
32
+ ask_if_not_provided(
33
+ options,
34
+ "build_dir",
35
+ "Enter base directory for the build output",
36
+ default_options["build_dir"],
37
+ none_interactive,
38
+ )
39
+ ask_if_not_provided(
40
+ options,
41
+ "env_file",
42
+ "Enter environment file path",
43
+ default_options["env_file"],
44
+ none_interactive,
45
+ )
@@ -0,0 +1,50 @@
1
+ from cli.utils import ask_if_not_provided
2
+ import click
3
+
4
+ def rest_api_step(options, default_options, none_interactive, abort):
5
+ """
6
+ Initialize the REST API.
7
+ """
8
+
9
+ enabled = ask_if_not_provided(
10
+ options,
11
+ "rest_api_enabled",
12
+ "Set up the REST API interface? (Required for Web UI setup in the next step.)",
13
+ default_options["rest_api_enabled"],
14
+ none_interactive,
15
+ )
16
+
17
+ if not enabled:
18
+ return
19
+
20
+ ask_if_not_provided(
21
+ options,
22
+ "rest_api_server_input_port",
23
+ "REST API server port",
24
+ default_options["rest_api_server_input_port"],
25
+ none_interactive,
26
+ )
27
+ ask_if_not_provided(
28
+ options,
29
+ "rest_api_server_host",
30
+ "REST API server host",
31
+ default_options["rest_api_server_host"],
32
+ none_interactive,
33
+ )
34
+ ask_if_not_provided(
35
+ options,
36
+ "rest_api_server_input_endpoint",
37
+ "REST API endpoint",
38
+ default_options["rest_api_server_input_endpoint"],
39
+ none_interactive,
40
+ )
41
+ ask_if_not_provided(
42
+ options,
43
+ "rest_api_gateway_name",
44
+ "What would you like to call the gateway",
45
+ default_options["rest_api_gateway_name"],
46
+ none_interactive,
47
+ )
48
+
49
+ click.echo("\nAdditional configuration options are availale for the REST API such as enabling authentication, rate limits etc.")
50
+ click.echo("Please refer to our documentation for detailed setup instructions.\n")
@@ -0,0 +1,40 @@
1
+ from cli.utils import ask_if_not_provided
2
+ import click
3
+
4
+ def webui_step(options, default_options, none_interactive, abort):
5
+ """
6
+ Initialize the Web UI configuration.
7
+ """
8
+ if not options.get("rest_api_enabled"):
9
+ click.echo(click.style("Skipping setup for Web UI because REST API was not enabled", bold=False, fg="yellow"))
10
+ return
11
+
12
+ enabled = ask_if_not_provided(
13
+ options,
14
+ "webui_enabled",
15
+ "Enable Web UI?",
16
+ default_options["webui_enabled"],
17
+ none_interactive=none_interactive,
18
+ )
19
+
20
+ if not enabled:
21
+ return
22
+
23
+ ask_if_not_provided(
24
+ options,
25
+ "webui_listen_port",
26
+ "Server listen port",
27
+ default_options["webui_listen_port"],
28
+ none_interactive,
29
+ )
30
+
31
+ ask_if_not_provided(
32
+ options,
33
+ "webui_host",
34
+ "Server host",
35
+ default_options["webui_host"],
36
+ none_interactive,
37
+ )
38
+
39
+ click.echo("\nAdditional configuration options are availale for the Web UI such as enabling authentication, collecting feedback etc.")
40
+ click.echo("Please refer to our documentation for detailed setup instructions.\n")
@@ -0,0 +1,3 @@
1
+ from .plugin import plugin_command
2
+
3
+ __all__ = ["plugin_command"]
@@ -0,0 +1,98 @@
1
+ import os
2
+ import subprocess
3
+ import click
4
+
5
+ from cli.utils import log_error, load_plugin
6
+ from cli.config import Config
7
+
8
+
9
+ def add_command(name: str, installer: str = None, from_url=None, add_all=False):
10
+ """
11
+ Add a new plugin to solace-agent-mesh config yaml
12
+ Optional install the module if not found
13
+
14
+ Args:
15
+ name (str): The name of the plugin module to import.
16
+ installer (str, optional): Installer to use if the module is not installed.
17
+ Should be one of 'pip', 'poetry', 'conda', or None.
18
+ """
19
+ name = name.replace("-", "_")
20
+ sam_config = Config.get_user_config()
21
+ if not sam_config:
22
+ sam_config = Config.get_default_config()
23
+
24
+ if "plugins" not in sam_config["solace_agent_mesh"] or not sam_config["solace_agent_mesh"]["plugins"]:
25
+ sam_config["solace_agent_mesh"]["plugins"] = []
26
+
27
+ if any(plugin["name"] == name for plugin in sam_config["solace_agent_mesh"]["plugins"]):
28
+ log_error(f"Plugin '{name}' already exists.")
29
+ return 1
30
+
31
+ # Attempt to import the module
32
+ module, module_path = load_plugin(name)
33
+ if not module:
34
+ if installer:
35
+ install_name = from_url or name
36
+ click.echo(
37
+ f"Module '{name}' not found. Attempting to install '{install_name}' using {installer}..."
38
+ )
39
+ if installer == "pip":
40
+ subprocess.check_call(["pip", "install", install_name])
41
+ elif installer == "poetry":
42
+ subprocess.check_call(["poetry", "add", install_name])
43
+ elif installer == "conda":
44
+ subprocess.check_call(["conda", "install", install_name])
45
+ else:
46
+ log_error(f"Unsupported installer: {installer}")
47
+ return 1
48
+ # Retry importing after installation
49
+ module, module_path = load_plugin(name)
50
+ if not module:
51
+ log_error(f"Failed to import module '{name}' after installation.")
52
+ return 1
53
+
54
+ # Adding to requirements.txt if exists and not already added
55
+ if os.path.exists("requirements.txt"):
56
+ with open("requirements.txt", "r", encoding="utf-8") as f:
57
+ requirements = f.read().splitlines()
58
+ if install_name not in requirements:
59
+ with open("requirements.txt", "a", encoding="utf-8") as f:
60
+ f.write(f"\n{install_name}")
61
+ else:
62
+ log_error(
63
+ f"Module '{name}' is not installed, and no installer was provided."
64
+ )
65
+ return 1
66
+
67
+ # Path to plugin config in the module
68
+ plugin_file_path = os.path.join(module_path, Config.user_plugin_config_file)
69
+
70
+ if not os.path.exists(plugin_file_path):
71
+ log_error("Invalid solace-agent-mesh plugin module.")
72
+ return 1
73
+
74
+ plugin_config = Config.load_config(plugin_file_path)
75
+
76
+ if not plugin_config or "solace_agent_mesh_plugin" not in plugin_config:
77
+ log_error("Invalid solace-agent-mesh plugin module.")
78
+ return 1
79
+ plugin_config = plugin_config["solace_agent_mesh_plugin"]
80
+
81
+ plugin_data = {
82
+ "name": name,
83
+ "load_unspecified_files": add_all,
84
+ "includes_gateway_interface": plugin_config.get("includes_gateway_interface", False),
85
+ "load": {
86
+ "agents": [],
87
+ "gateways": [],
88
+ "overwrites": [],
89
+ },
90
+ }
91
+
92
+ if from_url:
93
+ plugin_data["from_url"] = from_url
94
+
95
+ sam_config["solace_agent_mesh"]["plugins"].append(plugin_data)
96
+ Config.write_config(sam_config)
97
+
98
+ click.echo(f"Successfully added plugin '{name}'.")