meshagent-cli 0.41.0__tar.gz → 0.41.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/PKG-INFO +16 -16
  2. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/ask.py +12 -11
  3. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/chatbot.py +0 -12
  4. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/create.py +185 -66
  5. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/create_test.py +331 -102
  6. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/image.py +26 -1
  7. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/image_test.py +69 -7
  8. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/local_settings.py +12 -0
  9. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/local_settings_test.py +14 -0
  10. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/process.py +15 -12
  11. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/process_test.py +107 -0
  12. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/rooms.py +50 -8
  13. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/rooms_test.py +75 -6
  14. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/subscriptions.py +26 -0
  15. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/tui/create.py +18 -6
  16. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/tui/deploy_room.py +92 -12
  17. meshagent_cli-0.41.2/meshagent/cli/tui/deploy_room_test.py +19 -0
  18. meshagent_cli-0.41.2/meshagent/cli/version.py +1 -0
  19. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent_cli.egg-info/PKG-INFO +16 -16
  20. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent_cli.egg-info/SOURCES.txt +1 -0
  21. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent_cli.egg-info/requires.txt +15 -15
  22. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/pyproject.toml +15 -15
  23. meshagent_cli-0.41.0/meshagent/cli/version.py +0 -1
  24. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/LICENSE +0 -0
  25. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/README.md +0 -0
  26. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/__init__.py +0 -0
  27. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/agent.py +0 -0
  28. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/agent_cli_options_test.py +0 -0
  29. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/agent_package_cli.py +0 -0
  30. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/agent_package_cli_test.py +0 -0
  31. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/agents.py +0 -0
  32. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/agents_test.py +0 -0
  33. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/api_keys.py +0 -0
  34. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/api_keys_test.py +0 -0
  35. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/ask_test.py +0 -0
  36. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/async_typer.py +0 -0
  37. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/async_typer_test.py +0 -0
  38. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/auth.py +0 -0
  39. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/auth_async.py +0 -0
  40. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/auth_async_test.py +0 -0
  41. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/auth_test.py +0 -0
  42. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/call.py +0 -0
  43. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/cli.py +0 -0
  44. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/cli_mcp.py +0 -0
  45. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/cli_secrets.py +0 -0
  46. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/cli_test.py +0 -0
  47. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/common_options.py +0 -0
  48. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/config.py +0 -0
  49. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/config_test.py +0 -0
  50. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/containers.py +0 -0
  51. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/containers_test.py +0 -0
  52. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/create_project_templates/__init__.py +0 -0
  53. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/create_project_templates/python/backend-agent/server.py +0 -0
  54. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/create_project_templates/python/webserver/server.py +0 -0
  55. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/dataset.py +0 -0
  56. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/dataset_test.py +0 -0
  57. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/developer.py +0 -0
  58. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/developer_test.py +0 -0
  59. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/doctor.py +0 -0
  60. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/doctor_dockerfiles/__init__.py +0 -0
  61. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/doctor_templates/__init__.py +0 -0
  62. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/doctor_test.py +0 -0
  63. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/feeds.py +0 -0
  64. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/helper.py +0 -0
  65. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/helper_test.py +0 -0
  66. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/helpers.py +0 -0
  67. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/host.py +0 -0
  68. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/launch.py +0 -0
  69. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/launch_test.py +0 -0
  70. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/llm.py +0 -0
  71. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/llm_test.py +0 -0
  72. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/mailbot.py +0 -0
  73. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/mailbot_test.py +0 -0
  74. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/mailboxes.py +0 -0
  75. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/meeting_transcriber.py +0 -0
  76. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/memory.py +0 -0
  77. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/memory_test.py +0 -0
  78. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/meshagent_images.py +0 -0
  79. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/meshagent_images_test.py +0 -0
  80. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/messaging.py +0 -0
  81. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/multi.py +0 -0
  82. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/oauth2.py +0 -0
  83. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/oauth2_test.py +0 -0
  84. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/oci_archive.py +0 -0
  85. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/oci_archive_test.py +0 -0
  86. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/participant_token.py +0 -0
  87. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/port.py +0 -0
  88. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/port_test.py +0 -0
  89. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/preamble_rules.py +0 -0
  90. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/preamble_rules_test.py +0 -0
  91. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/process_live_test.py +0 -0
  92. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/projects.py +0 -0
  93. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/projects_test.py +0 -0
  94. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/queue.py +0 -0
  95. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/queue_test.py +0 -0
  96. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/registry.py +0 -0
  97. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/registry_test.py +0 -0
  98. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/room.py +0 -0
  99. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/room_connect.py +0 -0
  100. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/room_connect_test.py +0 -0
  101. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/room_services.py +0 -0
  102. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/root_commands.py +0 -0
  103. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/root_commands_test.py +0 -0
  104. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/routes.py +0 -0
  105. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/scheduled_tasks.py +0 -0
  106. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/scheduled_tasks_test.py +0 -0
  107. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/services.py +0 -0
  108. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/services_test.py +0 -0
  109. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/sessions.py +0 -0
  110. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/sessions_test.py +0 -0
  111. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/storage.py +0 -0
  112. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/storage_test.py +0 -0
  113. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/sync.py +0 -0
  114. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/sync_test.py +0 -0
  115. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/task_runner.py +0 -0
  116. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/task_runner_test.py +0 -0
  117. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/test.py +0 -0
  118. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/tool_call_summary.py +0 -0
  119. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/tool_call_summary_test.py +0 -0
  120. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/tool_integrations.py +0 -0
  121. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/tool_integrations_test.py +0 -0
  122. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/tui/__init__.py +0 -0
  123. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/tui/auth_switch.py +0 -0
  124. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/tui/auth_switch_test.py +0 -0
  125. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/tui/project_activate.py +0 -0
  126. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/tui/project_activate_test.py +0 -0
  127. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/tui/setup.py +0 -0
  128. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/tui/setup_splash_frames.py +0 -0
  129. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/tui/setup_test.py +0 -0
  130. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/voicebot.py +0 -0
  131. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/webhook.py +0 -0
  132. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/webserver.py +0 -0
  133. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/webserver_test.py +0 -0
  134. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/worker.py +0 -0
  135. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent/cli/worker_test.py +0 -0
  136. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent_cli.egg-info/dependency_links.txt +0 -0
  137. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent_cli.egg-info/entry_points.txt +0 -0
  138. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/meshagent_cli.egg-info/top_level.txt +0 -0
  139. {meshagent_cli-0.41.0 → meshagent_cli-0.41.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: meshagent-cli
3
- Version: 0.41.0
3
+ Version: 0.41.2
4
4
  Summary: CLI for Meshagent
5
5
  License-Expression: Apache-2.0
6
6
  Project-URL: Documentation, https://docs.meshagent.com
@@ -22,7 +22,7 @@ Requires-Dist: openpyxl~=3.1
22
22
  Requires-Dist: xlsxwriter~=3.2
23
23
  Requires-Dist: pathspec<2,>=1.0.3
24
24
  Requires-Dist: zstandard~=0.25.0
25
- Requires-Dist: meshagent-llm-proxy==0.41.0
25
+ Requires-Dist: meshagent-llm-proxy==0.41.2
26
26
  Requires-Dist: rich~=14.3.0
27
27
  Requires-Dist: sounddevice~=0.5
28
28
  Requires-Dist: textual<9.0,>=8.2.3
@@ -30,23 +30,23 @@ Requires-Dist: prompt-toolkit~=3.0.52
30
30
  Requires-Dist: ascii-magic~=2.3
31
31
  Requires-Dist: pillow~=11.3.0
32
32
  Provides-Extra: all
33
- Requires-Dist: meshagent-agents[all]==0.41.0; extra == "all"
34
- Requires-Dist: meshagent-api[all]==0.41.0; extra == "all"
35
- Requires-Dist: meshagent-commoncrawl==0.41.0; extra == "all"
36
- Requires-Dist: meshagent-scrapy==0.41.0; extra == "all"
37
- Requires-Dist: meshagent-computers==0.41.0; extra == "all"
38
- Requires-Dist: meshagent-openai==0.41.0; extra == "all"
39
- Requires-Dist: meshagent-anthropic==0.41.0; extra == "all"
40
- Requires-Dist: meshagent-otel==0.41.0; extra == "all"
41
- Requires-Dist: meshagent-mcp==0.41.0; extra == "all"
42
- Requires-Dist: meshagent-tools==0.41.0; extra == "all"
33
+ Requires-Dist: meshagent-agents[all]==0.41.2; extra == "all"
34
+ Requires-Dist: meshagent-api[all]==0.41.2; extra == "all"
35
+ Requires-Dist: meshagent-commoncrawl==0.41.2; extra == "all"
36
+ Requires-Dist: meshagent-scrapy==0.41.2; extra == "all"
37
+ Requires-Dist: meshagent-computers==0.41.2; extra == "all"
38
+ Requires-Dist: meshagent-openai==0.41.2; extra == "all"
39
+ Requires-Dist: meshagent-anthropic==0.41.2; extra == "all"
40
+ Requires-Dist: meshagent-otel==0.41.2; extra == "all"
41
+ Requires-Dist: meshagent-mcp==0.41.2; extra == "all"
42
+ Requires-Dist: meshagent-tools==0.41.2; extra == "all"
43
43
  Requires-Dist: supabase-auth~=2.28.0; extra == "all"
44
44
  Requires-Dist: prompt-toolkit~=3.0.52; extra == "all"
45
45
  Provides-Extra: mcp-service
46
- Requires-Dist: meshagent-agents[all]==0.41.0; extra == "mcp-service"
47
- Requires-Dist: meshagent-api==0.41.0; extra == "mcp-service"
48
- Requires-Dist: meshagent-mcp==0.41.0; extra == "mcp-service"
49
- Requires-Dist: meshagent-tools==0.41.0; extra == "mcp-service"
46
+ Requires-Dist: meshagent-agents[all]==0.41.2; extra == "mcp-service"
47
+ Requires-Dist: meshagent-api==0.41.2; extra == "mcp-service"
48
+ Requires-Dist: meshagent-mcp==0.41.2; extra == "mcp-service"
49
+ Requires-Dist: meshagent-tools==0.41.2; extra == "mcp-service"
50
50
  Requires-Dist: supabase-auth~=2.28.0; extra == "mcp-service"
51
51
  Dynamic: license-file
52
52
 
@@ -2440,6 +2440,18 @@ async def _run_ask_tui(
2440
2440
  active_item_id = self._active_assistant_item_id
2441
2441
  await self._stop_active_assistant_stream()
2442
2442
  with self.batch_update():
2443
+ if active_text.strip() != "":
2444
+ changed = self._append_or_replace_feed_entry(
2445
+ _AskFeedEntry(
2446
+ role=active_name or "agent",
2447
+ text=active_text,
2448
+ message_id=active_item_id,
2449
+ ),
2450
+ )
2451
+ if changed:
2452
+ self._render_feed()
2453
+ if active_item_id is not None:
2454
+ self._rendered_session_message_ids.add(active_item_id)
2443
2455
  if self._active_assistant_event_break is not None:
2444
2456
  self._active_assistant_event_break.styles.display = "none"
2445
2457
  if self._active_assistant_entry_view is not None:
@@ -2449,17 +2461,6 @@ async def _run_ask_tui(
2449
2461
  self._active_assistant_header.update("")
2450
2462
  if self._active_assistant_body is not None:
2451
2463
  self._active_assistant_body.update("")
2452
- if active_text.strip() != "":
2453
- self._entries.append(
2454
- _AskFeedEntry(
2455
- role=active_name or "agent",
2456
- text=active_text,
2457
- message_id=active_item_id,
2458
- )
2459
- )
2460
- self._render_feed()
2461
- if active_item_id is not None:
2462
- self._rendered_session_message_ids.add(active_item_id)
2463
2464
  self._active_assistant_text = ""
2464
2465
  self._active_assistant_name = None
2465
2466
  self._active_assistant_item_id = None
@@ -2682,18 +2682,6 @@ def build_process_agent(
2682
2682
  combined_toolkits.extend(built_required_toolkits)
2683
2683
  combined_toolkits.extend(required_toolkits)
2684
2684
  combined_toolkits.extend(extra_toolkits)
2685
- if process.supervisor is not None:
2686
- for channel in process.supervisor.channels:
2687
- if channel.state != "started":
2688
- continue
2689
- turn_id = turns[-1].turn_id if len(turns) > 0 else None
2690
- if process.thread_id is not None:
2691
- combined_toolkits.extend(
2692
- channel.get_turn_toolkits(
2693
- thread_id=process.thread_id,
2694
- turn_id=turn_id,
2695
- )
2696
- )
2697
2685
  if process.thread_storage is not None:
2698
2686
  combined_toolkits.append(process.thread_storage.make_toolkit())
2699
2687
  return combined_toolkits
@@ -4,6 +4,7 @@ import asyncio
4
4
  from dataclasses import dataclass
5
5
  from importlib import resources
6
6
  from pathlib import Path
7
+ import shlex
7
8
  import sys
8
9
  from typing import Literal, Mapping, Sequence
9
10
 
@@ -57,6 +58,7 @@ IGNORED_FILE_NAMES = {
57
58
  WEB_FOCUS = "webserver"
58
59
  AGENT_FOCUS = "backend-agent"
59
60
  CHATBOT_FOCUS = "chatbot"
61
+ ANTHROPIC_CHATBOT_FOCUS = "chatbot-anthropic"
60
62
  CHATBOT_UI_FOCUS = "chatbot-ui"
61
63
  DEFAULT_LANGUAGE = "python"
62
64
  DEFAULT_FOCUS = AGENT_FOCUS
@@ -95,101 +97,113 @@ class ExistingProjectSelection:
95
97
 
96
98
 
97
99
  WEBSERVER_NEXT_STEPS = (
98
- "meshagent doctor",
99
100
  "./scripts/install.sh",
100
- "MESHAGENT_ROOM=<room> ./scripts/dev.sh",
101
+ "./scripts/dev.sh",
101
102
  "./scripts/deploy.sh",
102
103
  )
103
104
  STATIC_WEBSERVER_NEXT_STEPS = (
104
- "meshagent doctor",
105
105
  "./scripts/install.sh",
106
- "MESHAGENT_ROOM=<room> ./scripts/dev.sh",
106
+ "./scripts/dev.sh",
107
107
  "./scripts/deploy.sh",
108
108
  )
109
109
  AGENT_NEXT_STEPS = (
110
- "meshagent doctor",
111
110
  "./scripts/install.sh",
112
- "MESHAGENT_ROOM=<room> ./scripts/dev.sh",
111
+ "./scripts/dev.sh",
113
112
  "./scripts/deploy.sh",
114
113
  )
115
114
  NPM_WEBSERVER_NEXT_STEPS = (
116
- "meshagent doctor",
117
115
  "npm install",
118
- "MESHAGENT_ROOM=<room> npm run dev",
116
+ "npm run dev",
119
117
  "npm run deploy",
120
118
  )
121
119
  NPM_STATIC_WEBSERVER_NEXT_STEPS = (
122
- "meshagent doctor",
123
120
  "npm install",
124
- "MESHAGENT_ROOM=<room> npm run dev",
121
+ "npm run dev",
125
122
  "npm run deploy",
126
123
  )
127
124
  NPM_CHATBOT_UI_NEXT_STEPS = (
128
- "meshagent doctor",
129
125
  "npm install",
130
- "MESHAGENT_ROOM=<room> npm run dev",
126
+ "npm run dev",
131
127
  "npm run deploy",
132
128
  )
133
129
  NPM_AGENT_NEXT_STEPS = (
134
- "meshagent doctor",
135
130
  "npm install",
136
- "MESHAGENT_ROOM=<room> npm run dev",
131
+ "npm run dev",
137
132
  "npm run deploy",
138
133
  )
134
+ AGENT_TOOLKIT_NAMES = {
135
+ "python": "meshagent.create.python-agent",
136
+ "javascript": "meshagent.create.javascript-agent",
137
+ "typescript": "meshagent.create.typescript-agent",
138
+ "dotnet": "meshagent.create.dotnet-agent",
139
+ "dart-flutter": "meshagent.create.dart-agent",
140
+ }
141
+ AGENT_PROCESS_NAMES = {
142
+ "python": "meshagent-create-python-agent",
143
+ "javascript": "meshagent-create-javascript-agent",
144
+ "typescript": "meshagent-create-typescript-agent",
145
+ "dotnet": "meshagent-create-dotnet-agent",
146
+ "dart-flutter": "meshagent-create-dart-agent",
147
+ }
139
148
 
140
149
  LANGUAGES: Mapping[str, CreateLanguage] = {
141
150
  "python": CreateLanguage(
142
151
  id="python",
143
152
  label="Python",
144
- description="Python 3.13.",
153
+ description="Python 3.13 services and agents.",
145
154
  ),
146
155
  "javascript": CreateLanguage(
147
156
  id="javascript",
148
157
  label="JavaScript",
149
- description="Node.js/CommonJS.",
158
+ description="Node.js CommonJS services and agents.",
150
159
  ),
151
160
  "typescript": CreateLanguage(
152
161
  id="typescript",
153
162
  label="TypeScript",
154
- description="Node.js/TypeScript.",
163
+ description="Node.js TypeScript services, agents, and chat apps.",
155
164
  ),
156
165
  "react": CreateLanguage(
157
166
  id="react",
158
167
  label="React",
159
- description="React/Vite.",
168
+ description="React/Vite browser app.",
160
169
  ),
161
170
  "dotnet": CreateLanguage(
162
171
  id="dotnet",
163
172
  label=".NET",
164
- description=".NET.",
173
+ description=".NET service or agent.",
165
174
  ),
166
175
  "dart-flutter": CreateLanguage(
167
176
  id="dart-flutter",
168
177
  label="Dart/Flutter",
169
- description="Dart or Flutter.",
178
+ description="Flutter Web App or Dart Agent Toolkit.",
170
179
  ),
171
180
  }
172
181
 
173
182
  FOCUSES: Mapping[str, CreateFocus] = {
174
183
  WEB_FOCUS: CreateFocus(
175
184
  id=WEB_FOCUS,
176
- label="Web server",
177
- description="HTTP app with a health endpoint and public route.",
185
+ label="Web App",
186
+ description="Public HTTP service with a health endpoint.",
178
187
  ),
179
188
  AGENT_FOCUS: CreateFocus(
180
189
  id=AGENT_FOCUS,
181
- label="Backend agent",
182
- description="Headless RoomClient SDK service without a public port.",
190
+ label="Agent Toolkit",
191
+ description="Expose custom functionality to agents in the room.",
183
192
  ),
184
193
  CHATBOT_FOCUS: CreateFocus(
185
194
  id=CHATBOT_FOCUS,
186
- label="Chatbot",
187
- description="TypeScript RoomClient chatbot with one chat tool.",
195
+ label="OpenAI Chatbot",
196
+ description="Browser chat app backed by the room OpenAI proxy.",
197
+ ),
198
+ ANTHROPIC_CHATBOT_FOCUS: CreateFocus(
199
+ id=ANTHROPIC_CHATBOT_FOCUS,
200
+ label="Anthropic Chatbot",
201
+ description="Browser chat app backed by the room Anthropic proxy.",
188
202
  ),
189
203
  CHATBOT_UI_FOCUS: CreateFocus(
190
204
  id=CHATBOT_UI_FOCUS,
191
- label="Chatbot UI",
192
- description="TypeScript/Next.js UI that chats with a MeshAgent assistant.",
205
+ label="Agent UI",
206
+ description="Browser chat interface for a deployed MeshAgent agent.",
193
207
  ),
194
208
  }
195
209
 
@@ -208,8 +222,8 @@ TEMPLATES: Mapping[tuple[str, str], CreateTemplate] = {
208
222
  ("python", WEB_FOCUS): CreateTemplate(
209
223
  language_id="python",
210
224
  focus_id=WEB_FOCUS,
211
- label="Python web server",
212
- description="Async Python HTTP service on a declared container port.",
225
+ label="Python Web App",
226
+ description="Async Python public HTTP service with a health route.",
213
227
  files=_template_files(
214
228
  "python",
215
229
  WEB_FOCUS,
@@ -229,8 +243,8 @@ TEMPLATES: Mapping[tuple[str, str], CreateTemplate] = {
229
243
  ("python", AGENT_FOCUS): CreateTemplate(
230
244
  language_id="python",
231
245
  focus_id=AGENT_FOCUS,
232
- label="Python backend agent",
233
- description="Headless Python RoomClient service.",
246
+ label="Python Agent Toolkit",
247
+ description="Headless Python service that exposes custom tools to agents.",
234
248
  files=_template_files(
235
249
  "python",
236
250
  AGENT_FOCUS,
@@ -249,8 +263,8 @@ TEMPLATES: Mapping[tuple[str, str], CreateTemplate] = {
249
263
  ("javascript", WEB_FOCUS): CreateTemplate(
250
264
  language_id="javascript",
251
265
  focus_id=WEB_FOCUS,
252
- label="JavaScript web server",
253
- description="Node.js HTTP service on a declared container port.",
266
+ label="JavaScript Web App",
267
+ description="Node.js public HTTP service with a health route.",
254
268
  files=_template_files(
255
269
  "javascript",
256
270
  WEB_FOCUS,
@@ -268,8 +282,8 @@ TEMPLATES: Mapping[tuple[str, str], CreateTemplate] = {
268
282
  ("javascript", AGENT_FOCUS): CreateTemplate(
269
283
  language_id="javascript",
270
284
  focus_id=AGENT_FOCUS,
271
- label="JavaScript backend agent",
272
- description="Headless Node.js RoomClient service.",
285
+ label="JavaScript Agent Toolkit",
286
+ description="Headless Node.js service that exposes custom tools to agents.",
273
287
  files=_template_files(
274
288
  "javascript",
275
289
  AGENT_FOCUS,
@@ -286,8 +300,8 @@ TEMPLATES: Mapping[tuple[str, str], CreateTemplate] = {
286
300
  ("typescript", WEB_FOCUS): CreateTemplate(
287
301
  language_id="typescript",
288
302
  focus_id=WEB_FOCUS,
289
- label="TypeScript web server",
290
- description="Node.js TypeScript HTTP service on a declared container port.",
303
+ label="TypeScript Web App",
304
+ description="TypeScript public HTTP service with a health route.",
291
305
  files=_template_files(
292
306
  "typescript",
293
307
  WEB_FOCUS,
@@ -306,8 +320,8 @@ TEMPLATES: Mapping[tuple[str, str], CreateTemplate] = {
306
320
  ("typescript", AGENT_FOCUS): CreateTemplate(
307
321
  language_id="typescript",
308
322
  focus_id=AGENT_FOCUS,
309
- label="TypeScript backend agent",
310
- description="Headless TypeScript RoomClient service.",
323
+ label="TypeScript Agent Toolkit",
324
+ description="Headless TypeScript service that exposes custom tools to agents.",
311
325
  files=_template_files(
312
326
  "typescript",
313
327
  AGENT_FOCUS,
@@ -325,23 +339,38 @@ TEMPLATES: Mapping[tuple[str, str], CreateTemplate] = {
325
339
  ("typescript", CHATBOT_FOCUS): CreateTemplate(
326
340
  language_id="typescript",
327
341
  focus_id=CHATBOT_FOCUS,
328
- label="TypeScript chatbot",
329
- description="Headless TypeScript RoomClient chatbot.",
342
+ label="TypeScript OpenAI Chatbot",
343
+ description="Browser chatbot backed by the room OpenAI proxy.",
330
344
  files={
331
345
  "package.json": "typescript/chatbot/package.json",
332
346
  ".npmrc": "typescript/backend-agent/.npmrc",
333
347
  "tsconfig.json": "typescript/backend-agent/tsconfig.json",
334
348
  "src/server.ts": "typescript/chatbot/src/server.ts",
335
- "Dockerfile": "typescript/backend-agent/Dockerfile",
349
+ "Dockerfile": "typescript/webserver/Dockerfile",
336
350
  ".dockerignore": "typescript/backend-agent/.dockerignore",
337
351
  },
338
- next_steps=NPM_AGENT_NEXT_STEPS,
352
+ next_steps=NPM_WEBSERVER_NEXT_STEPS,
353
+ ),
354
+ ("typescript", ANTHROPIC_CHATBOT_FOCUS): CreateTemplate(
355
+ language_id="typescript",
356
+ focus_id=ANTHROPIC_CHATBOT_FOCUS,
357
+ label="TypeScript Anthropic Chatbot",
358
+ description="Browser chatbot backed by the room Anthropic proxy.",
359
+ files={
360
+ "package.json": "typescript/chatbot-anthropic/package.json",
361
+ ".npmrc": "typescript/backend-agent/.npmrc",
362
+ "tsconfig.json": "typescript/backend-agent/tsconfig.json",
363
+ "src/server.ts": "typescript/chatbot-anthropic/src/server.ts",
364
+ "Dockerfile": "typescript/webserver/Dockerfile",
365
+ ".dockerignore": "typescript/backend-agent/.dockerignore",
366
+ },
367
+ next_steps=NPM_WEBSERVER_NEXT_STEPS,
339
368
  ),
340
369
  ("react", WEB_FOCUS): CreateTemplate(
341
370
  language_id="react",
342
371
  focus_id=WEB_FOCUS,
343
- label="React web server",
344
- description="React/Vite web app served by nginx on a declared container port.",
372
+ label="React/Vite Web App",
373
+ description="React/Vite browser app served as a public route.",
345
374
  files=_template_files(
346
375
  "react",
347
376
  WEB_FOCUS,
@@ -363,8 +392,8 @@ TEMPLATES: Mapping[tuple[str, str], CreateTemplate] = {
363
392
  ("typescript", CHATBOT_UI_FOCUS): CreateTemplate(
364
393
  language_id="typescript",
365
394
  focus_id=CHATBOT_UI_FOCUS,
366
- label="TypeScript chatbot UI",
367
- description="TypeScript/Next.js UI that chats with a MeshAgent assistant.",
395
+ label="TypeScript Agent UI",
396
+ description="Browser chat interface for a deployed MeshAgent agent.",
368
397
  files=_template_files(
369
398
  "typescript",
370
399
  CHATBOT_UI_FOCUS,
@@ -387,8 +416,8 @@ TEMPLATES: Mapping[tuple[str, str], CreateTemplate] = {
387
416
  ("dotnet", WEB_FOCUS): CreateTemplate(
388
417
  language_id="dotnet",
389
418
  focus_id=WEB_FOCUS,
390
- label=".NET web server",
391
- description="ASP.NET Core HTTP service on a declared container port.",
419
+ label=".NET Web App",
420
+ description="ASP.NET Core public HTTP service with a health route.",
392
421
  files=_template_files(
393
422
  "dotnet",
394
423
  WEB_FOCUS,
@@ -407,8 +436,8 @@ TEMPLATES: Mapping[tuple[str, str], CreateTemplate] = {
407
436
  ("dotnet", AGENT_FOCUS): CreateTemplate(
408
437
  language_id="dotnet",
409
438
  focus_id=AGENT_FOCUS,
410
- label=".NET backend agent",
411
- description="Headless .NET RoomClient service.",
439
+ label=".NET Agent Toolkit",
440
+ description="Headless .NET service that exposes custom tools to agents.",
412
441
  files=_template_files(
413
442
  "dotnet",
414
443
  AGENT_FOCUS,
@@ -427,8 +456,8 @@ TEMPLATES: Mapping[tuple[str, str], CreateTemplate] = {
427
456
  ("dart-flutter", WEB_FOCUS): CreateTemplate(
428
457
  language_id="dart-flutter",
429
458
  focus_id=WEB_FOCUS,
430
- label="Flutter web server",
431
- description="Flutter web app served by nginx on a declared container port.",
459
+ label="Flutter Web App",
460
+ description="Flutter browser app served as a public route.",
432
461
  files=_template_files(
433
462
  "dart-flutter",
434
463
  WEB_FOCUS,
@@ -449,8 +478,8 @@ TEMPLATES: Mapping[tuple[str, str], CreateTemplate] = {
449
478
  ("dart-flutter", AGENT_FOCUS): CreateTemplate(
450
479
  language_id="dart-flutter",
451
480
  focus_id=AGENT_FOCUS,
452
- label="Dart backend agent",
453
- description="Headless Dart RoomClient service.",
481
+ label="Dart Agent Toolkit",
482
+ description="Headless Dart service that exposes custom tools to agents.",
454
483
  files=_template_files(
455
484
  "dart-flutter",
456
485
  AGENT_FOCUS,
@@ -499,8 +528,20 @@ FOCUS_ALIASES = {
499
528
  "backend": AGENT_FOCUS,
500
529
  "backend-agent": AGENT_FOCUS,
501
530
  "backend_agent": AGENT_FOCUS,
531
+ "agent-toolkit": AGENT_FOCUS,
532
+ "agent_toolkit": AGENT_FOCUS,
533
+ "room-agent": AGENT_FOCUS,
534
+ "room_agent": AGENT_FOCUS,
535
+ "anthropic-chat": ANTHROPIC_CHATBOT_FOCUS,
536
+ "anthropic-chatbot": ANTHROPIC_CHATBOT_FOCUS,
502
537
  "chat": CHATBOT_FOCUS,
503
538
  "chatbot": CHATBOT_FOCUS,
539
+ "openai-chat": CHATBOT_FOCUS,
540
+ "openai-chatbot": CHATBOT_FOCUS,
541
+ "chatbot-anthropic": ANTHROPIC_CHATBOT_FOCUS,
542
+ "chatbot_anthropic": ANTHROPIC_CHATBOT_FOCUS,
543
+ "agent-ui": CHATBOT_UI_FOCUS,
544
+ "agent_ui": CHATBOT_UI_FOCUS,
504
545
  "chat-ui": CHATBOT_UI_FOCUS,
505
546
  "chat_ui": CHATBOT_UI_FOCUS,
506
547
  "chatbot-ui": CHATBOT_UI_FOCUS,
@@ -508,6 +549,8 @@ FOCUS_ALIASES = {
508
549
  "roomclient": AGENT_FOCUS,
509
550
  "room-client": AGENT_FOCUS,
510
551
  "web": WEB_FOCUS,
552
+ "web-app": WEB_FOCUS,
553
+ "web_app": WEB_FOCUS,
511
554
  "webserver": WEB_FOCUS,
512
555
  "web-server": WEB_FOCUS,
513
556
  "web_server": WEB_FOCUS,
@@ -689,10 +732,10 @@ def _run_create_tui(
689
732
  return result.selected_language_id, result.selected_focus_id
690
733
 
691
734
 
692
- def _run_existing_project_tui() -> ExistingProjectSelection | None:
735
+ def _run_existing_project_tui(*, root: Path) -> ExistingProjectSelection | None:
693
736
  from meshagent.cli.tui.create import run_existing_project_create_tui
694
737
 
695
- result = asyncio.run(run_existing_project_create_tui())
738
+ result = asyncio.run(run_existing_project_create_tui(root=root))
696
739
  if result.status != "completed" or result.action is None:
697
740
  return None
698
741
  return ExistingProjectSelection(
@@ -736,15 +779,88 @@ def _write_template(root: Path, template: CreateTemplate) -> None:
736
779
  _write_file(root / name, template_name)
737
780
 
738
781
 
739
- def _print_created_report(*, template: CreateTemplate) -> None:
782
+ def _next_step_sections(
783
+ steps: tuple[str, ...],
784
+ ) -> tuple[tuple[str, tuple[str, ...]], ...]:
785
+ section_specs = (
786
+ ("Install dependencies", ("install",)),
787
+ ("Run locally", ("dev",)),
788
+ ("Deploy", ("deploy",)),
789
+ )
790
+ sections: list[tuple[str, tuple[str, ...]]] = []
791
+ matched_steps: set[str] = set()
792
+ for title, keywords in section_specs:
793
+ section_steps = tuple(
794
+ step for step in steps if any(keyword in step for keyword in keywords)
795
+ )
796
+ if section_steps:
797
+ sections.append((title, section_steps))
798
+ matched_steps.update(section_steps)
799
+
800
+ other_steps = tuple(step for step in steps if step not in matched_steps)
801
+ if other_steps:
802
+ sections.append(("Other", other_steps))
803
+ return tuple(sections)
804
+
805
+
806
+ def _print_next_steps(
807
+ steps: tuple[str, ...],
808
+ *,
809
+ enter_project_root: Path | None = None,
810
+ ) -> None:
811
+ click.secho("Next steps:", fg="cyan", bold=True)
812
+ if enter_project_root is not None:
813
+ click.secho(f" cd {shlex.quote(str(enter_project_root))}", fg="green")
814
+ for index, (title, section_steps) in enumerate(_next_step_sections(steps), start=1):
815
+ if index > 1:
816
+ click.echo("")
817
+ click.secho(f" {index}. {title}", fg="blue", bold=True)
818
+ for step in section_steps:
819
+ click.secho(f" {step}", fg="green")
820
+
821
+
822
+ def _paired_agent_deploy_command(template: CreateTemplate) -> str | None:
823
+ if template.focus_id != AGENT_FOCUS:
824
+ return None
825
+ toolkit_name = AGENT_TOOLKIT_NAMES.get(template.language_id)
826
+ agent_name = AGENT_PROCESS_NAMES.get(template.language_id)
827
+ if toolkit_name is None or agent_name is None:
828
+ return None
829
+ rule = f"Use the {toolkit_name} toolkit to answer ping, status, and echo requests."
830
+ return (
831
+ "meshagent process deploy "
832
+ "--room <room> "
833
+ f"--agent-name {agent_name} "
834
+ f"--require-toolkit {toolkit_name} "
835
+ f"--rule {shlex.quote(rule)}"
836
+ )
837
+
838
+
839
+ def _print_agent_toolkit_guidance(template: CreateTemplate) -> None:
840
+ command = _paired_agent_deploy_command(template)
841
+ if command is None:
842
+ return
843
+ click.echo("")
844
+ click.secho(
845
+ "To install an agent in your room that uses this tool run:",
846
+ fg="cyan",
847
+ bold=True,
848
+ )
849
+ click.secho(f" {command}", fg="green")
850
+
851
+
852
+ def _print_created_report(
853
+ *,
854
+ template: CreateTemplate,
855
+ enter_project_root: Path | None = None,
856
+ ) -> None:
740
857
  click.echo("")
741
858
  click.echo(f"Created a minimal deployable {template.label} project:")
742
859
  for name in template.files:
743
860
  click.echo(f" {name}")
744
861
  click.echo("")
745
- click.echo("Next steps:")
746
- for step in template.next_steps:
747
- click.echo(f" {step}")
862
+ _print_next_steps(template.next_steps, enter_project_root=enter_project_root)
863
+ _print_agent_toolkit_guidance(template)
748
864
 
749
865
 
750
866
  @click.command(
@@ -766,8 +882,9 @@ def _print_created_report(*, template: CreateTemplate) -> None:
766
882
  type=str,
767
883
  default=None,
768
884
  help=(
769
- "Project focus for non-interactive use. Supported: webserver, backend-agent."
770
- " TypeScript also supports chatbot and chatbot-ui."
885
+ "Project focus for non-interactive use. Use stable IDs: webserver "
886
+ "(Web App), backend-agent (Agent Toolkit), chatbot (OpenAI Chatbot), "
887
+ "chatbot-anthropic (Anthropic Chatbot), or chatbot-ui (Agent UI)."
771
888
  ),
772
889
  )
773
890
  @click.option(
@@ -796,6 +913,7 @@ def create_command(
796
913
 
797
914
  click.echo("meshagent create")
798
915
  click.echo(f"Project: {root}")
916
+ enter_project_root: Path | None = None
799
917
 
800
918
  is_interactive_stdio = _stdio_is_interactive()
801
919
  if interactive is True and not is_interactive_stdio:
@@ -806,7 +924,7 @@ def create_command(
806
924
 
807
925
  if _has_existing_project_content(root):
808
926
  if interactive is not False and is_interactive_stdio:
809
- existing_project_selection = _run_existing_project_tui()
927
+ existing_project_selection = _run_existing_project_tui(root=root)
810
928
  if existing_project_selection is None:
811
929
  click.echo("Create canceled.")
812
930
  return
@@ -820,6 +938,7 @@ def create_command(
820
938
  existing_project_selection.subfolder_name,
821
939
  )
822
940
  root.mkdir(parents=True, exist_ok=False)
941
+ enter_project_root = root
823
942
  click.echo(f"New project: {root}")
824
943
  else:
825
944
  click.echo("")
@@ -851,4 +970,4 @@ def create_command(
851
970
 
852
971
  template = _resolve_template(language_id, focus_id)
853
972
  _write_template(root, template)
854
- _print_created_report(template=template)
973
+ _print_created_report(template=template, enter_project_root=enter_project_root)