meshagent-cli 0.36.1__tar.gz → 0.36.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.
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/PKG-INFO +13 -13
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/auth_async.py +3 -2
- meshagent_cli-0.36.2/meshagent/cli/auth_async_test.py +16 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/cli.py +1 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/room.py +6 -0
- meshagent_cli-0.36.2/meshagent/cli/room_connect.py +119 -0
- meshagent_cli-0.36.2/meshagent/cli/room_connect_test.py +151 -0
- meshagent_cli-0.36.2/meshagent/cli/version.py +1 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent_cli.egg-info/PKG-INFO +13 -13
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent_cli.egg-info/SOURCES.txt +3 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent_cli.egg-info/requires.txt +12 -12
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/pyproject.toml +12 -12
- meshagent_cli-0.36.1/meshagent/cli/version.py +0 -1
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/README.md +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/__init__.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/agent.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/api_keys.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/api_keys_test.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/async_typer.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/async_typer_test.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/auth.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/call.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/chatbot.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/cli_mcp.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/cli_secrets.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/cli_test.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/codex.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/common_options.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/containers.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/containers_test.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/database.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/developer.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/developer_test.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/helper.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/helper_test.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/helpers.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/host.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/image.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/image_test.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/mailbot.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/mailboxes.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/meeting_transcriber.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/memory.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/memory_test.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/messaging.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/multi.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/oauth2.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/oci_archive.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/oci_archive_test.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/participant_token.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/port.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/port_test.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/process.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/process_test.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/projects.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/queue.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/queue_test.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/room_services.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/rooms.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/root_commands.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/routes.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/scheduled_tasks.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/scheduled_tasks_test.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/services.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/services_test.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/sessions.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/sessions_test.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/storage.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/storage_test.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/sync.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/sync_test.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/task_runner.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/test.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/tui/__init__.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/tui/setup.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/tui/setup_splash_frames.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/tui/setup_test.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/voicebot.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/webhook.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/webserver.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/webserver_test.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent/cli/worker.py +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent_cli.egg-info/dependency_links.txt +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent_cli.egg-info/entry_points.txt +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/meshagent_cli.egg-info/top_level.txt +0 -0
- {meshagent_cli-0.36.1 → meshagent_cli-0.36.2}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: meshagent-cli
|
|
3
|
-
Version: 0.36.
|
|
3
|
+
Version: 0.36.2
|
|
4
4
|
Summary: CLI for Meshagent
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
Project-URL: Documentation, https://docs.meshagent.com
|
|
@@ -20,21 +20,21 @@ Requires-Dist: rich~=14.3.0
|
|
|
20
20
|
Requires-Dist: textual<2.0,>=0.50
|
|
21
21
|
Requires-Dist: prompt-toolkit~=3.0.52
|
|
22
22
|
Provides-Extra: all
|
|
23
|
-
Requires-Dist: meshagent-agents[all]~=0.36.
|
|
24
|
-
Requires-Dist: meshagent-api[all]~=0.36.
|
|
25
|
-
Requires-Dist: meshagent-computers~=0.36.
|
|
26
|
-
Requires-Dist: meshagent-openai~=0.36.
|
|
27
|
-
Requires-Dist: meshagent-anthropic~=0.36.
|
|
28
|
-
Requires-Dist: meshagent-codex~=0.36.
|
|
29
|
-
Requires-Dist: meshagent-mcp~=0.36.
|
|
30
|
-
Requires-Dist: meshagent-tools~=0.36.
|
|
23
|
+
Requires-Dist: meshagent-agents[all]~=0.36.2; extra == "all"
|
|
24
|
+
Requires-Dist: meshagent-api[all]~=0.36.2; extra == "all"
|
|
25
|
+
Requires-Dist: meshagent-computers~=0.36.2; extra == "all"
|
|
26
|
+
Requires-Dist: meshagent-openai~=0.36.2; extra == "all"
|
|
27
|
+
Requires-Dist: meshagent-anthropic~=0.36.2; extra == "all"
|
|
28
|
+
Requires-Dist: meshagent-codex~=0.36.2; extra == "all"
|
|
29
|
+
Requires-Dist: meshagent-mcp~=0.36.2; extra == "all"
|
|
30
|
+
Requires-Dist: meshagent-tools~=0.36.2; extra == "all"
|
|
31
31
|
Requires-Dist: supabase-auth~=2.28.0; extra == "all"
|
|
32
32
|
Requires-Dist: prompt-toolkit~=3.0.52; extra == "all"
|
|
33
33
|
Provides-Extra: mcp-service
|
|
34
|
-
Requires-Dist: meshagent-agents[all]~=0.36.
|
|
35
|
-
Requires-Dist: meshagent-api~=0.36.
|
|
36
|
-
Requires-Dist: meshagent-mcp~=0.36.
|
|
37
|
-
Requires-Dist: meshagent-tools~=0.36.
|
|
34
|
+
Requires-Dist: meshagent-agents[all]~=0.36.2; extra == "mcp-service"
|
|
35
|
+
Requires-Dist: meshagent-api~=0.36.2; extra == "mcp-service"
|
|
36
|
+
Requires-Dist: meshagent-mcp~=0.36.2; extra == "mcp-service"
|
|
37
|
+
Requires-Dist: meshagent-tools~=0.36.2; extra == "mcp-service"
|
|
38
38
|
Requires-Dist: supabase-auth~=2.28.0; extra == "mcp-service"
|
|
39
39
|
|
|
40
40
|
# [Meshagent](https://www.meshagent.com)
|
|
@@ -11,6 +11,7 @@ from pathlib import Path
|
|
|
11
11
|
from typing import Awaitable, Callable, Optional
|
|
12
12
|
from urllib.parse import urlencode
|
|
13
13
|
from aiohttp import web, ClientSession
|
|
14
|
+
from meshagent.api.oauth_scopes import FULL_OAUTH_SCOPE
|
|
14
15
|
|
|
15
16
|
# -----------------------------------------------------------------------------
|
|
16
17
|
# Config
|
|
@@ -24,7 +25,7 @@ REDIRECT_URL = f"http://localhost:{REDIRECT_PORT}/callback"
|
|
|
24
25
|
# - MESHAGENT_API_URL (required): e.g., https://api.meshagent.com
|
|
25
26
|
# - MESHAGENT_OAUTH_CLIENT_ID (required)
|
|
26
27
|
# - MESHAGENT_OAUTH_CLIENT_SECRET (optional; only if your server requires it)
|
|
27
|
-
# - MESHAGENT_OAUTH_SCOPES (optional; defaults to
|
|
28
|
+
# - MESHAGENT_OAUTH_SCOPES (optional; defaults to the full official scope set)
|
|
28
29
|
|
|
29
30
|
# -----------------------------------------------------------------------------
|
|
30
31
|
# Helpers
|
|
@@ -80,7 +81,7 @@ def _client_secret() -> str | None:
|
|
|
80
81
|
|
|
81
82
|
|
|
82
83
|
def _scopes() -> str:
|
|
83
|
-
return os.getenv("MESHAGENT_OAUTH_SCOPES",
|
|
84
|
+
return os.getenv("MESHAGENT_OAUTH_SCOPES", FULL_OAUTH_SCOPE)
|
|
84
85
|
|
|
85
86
|
|
|
86
87
|
def _save(tokens: dict):
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from meshagent.api.oauth_scopes import FULL_OAUTH_SCOPE
|
|
2
|
+
from meshagent.cli import auth_async
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def test_scopes_defaults_to_full_official_scope_set(
|
|
6
|
+
monkeypatch,
|
|
7
|
+
) -> None:
|
|
8
|
+
monkeypatch.delenv("MESHAGENT_OAUTH_SCOPES", raising=False)
|
|
9
|
+
|
|
10
|
+
assert auth_async._scopes() == FULL_OAUTH_SCOPE
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def test_scopes_prefers_environment_override(monkeypatch) -> None:
|
|
14
|
+
monkeypatch.setenv("MESHAGENT_OAUTH_SCOPES", "admin")
|
|
15
|
+
|
|
16
|
+
assert auth_async._scopes() == "admin"
|
|
@@ -76,3 +76,9 @@ app.add_lazy_command(
|
|
|
76
76
|
module="meshagent.cli.sync",
|
|
77
77
|
help="Inspect and update mesh documents in a room",
|
|
78
78
|
)
|
|
79
|
+
app.add_lazy_command(
|
|
80
|
+
name="connect",
|
|
81
|
+
module="meshagent.cli.room_connect",
|
|
82
|
+
attribute="connect_command",
|
|
83
|
+
help="Connect to a room and run a local command with room auth env",
|
|
84
|
+
)
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
import os
|
|
5
|
+
import subprocess
|
|
6
|
+
from typing import Sequence
|
|
7
|
+
|
|
8
|
+
import click
|
|
9
|
+
from rich import print
|
|
10
|
+
|
|
11
|
+
from meshagent.api.helpers import meshagent_base_url
|
|
12
|
+
from meshagent.cli import async_typer
|
|
13
|
+
from meshagent.cli.helper import get_client, resolve_project_id, resolve_room
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass(frozen=True)
|
|
17
|
+
class _ConnectedRoomEnv:
|
|
18
|
+
api_url: str
|
|
19
|
+
room_name: str
|
|
20
|
+
room_url: str
|
|
21
|
+
token: str
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _normalize_room_url(*, room_url: str) -> str:
|
|
25
|
+
normalized = room_url.strip().rstrip("/")
|
|
26
|
+
if normalized.startswith("wss:"):
|
|
27
|
+
return "https:" + normalized.removeprefix("wss:")
|
|
28
|
+
if normalized.startswith("ws:"):
|
|
29
|
+
return "http:" + normalized.removeprefix("ws:")
|
|
30
|
+
return normalized
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
async def _connect_room_env(
|
|
34
|
+
*,
|
|
35
|
+
project_id: str | None,
|
|
36
|
+
room: str | None,
|
|
37
|
+
) -> _ConnectedRoomEnv:
|
|
38
|
+
account_client = await get_client()
|
|
39
|
+
try:
|
|
40
|
+
resolved_project_id = await resolve_project_id(project_id=project_id)
|
|
41
|
+
resolved_room = resolve_room(room)
|
|
42
|
+
if resolved_room is None:
|
|
43
|
+
print("[red]--room is required (or set MESHAGENT_ROOM).[/red]")
|
|
44
|
+
raise click.exceptions.Exit(1)
|
|
45
|
+
|
|
46
|
+
connection = await account_client.connect_room(
|
|
47
|
+
project_id=resolved_project_id,
|
|
48
|
+
room=resolved_room,
|
|
49
|
+
)
|
|
50
|
+
return _ConnectedRoomEnv(
|
|
51
|
+
api_url=os.getenv("MESHAGENT_API_URL") or meshagent_base_url(),
|
|
52
|
+
room_name=connection.room_name,
|
|
53
|
+
room_url=_normalize_room_url(room_url=connection.room_url),
|
|
54
|
+
token=connection.jwt,
|
|
55
|
+
)
|
|
56
|
+
finally:
|
|
57
|
+
await account_client.close()
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _run_connected_command(
|
|
61
|
+
*,
|
|
62
|
+
command: Sequence[str],
|
|
63
|
+
room_env: _ConnectedRoomEnv,
|
|
64
|
+
) -> int:
|
|
65
|
+
child_env = os.environ.copy()
|
|
66
|
+
child_env["MESHAGENT_API_URL"] = room_env.api_url
|
|
67
|
+
child_env["MESHAGENT_TOKEN"] = room_env.token
|
|
68
|
+
child_env["MESHAGENT_ROOM"] = room_env.room_name
|
|
69
|
+
child_env["OPENAI_BASE_URL"] = f"{room_env.room_url}/openai/v1"
|
|
70
|
+
child_env["ANTHROPIC_BASE_URL"] = f"{room_env.room_url}/anthropic"
|
|
71
|
+
child_env["OPENAI_API_KEY"] = room_env.token
|
|
72
|
+
child_env["ANTHROPIC_API_KEY"] = room_env.token
|
|
73
|
+
|
|
74
|
+
try:
|
|
75
|
+
result = subprocess.run(
|
|
76
|
+
list(command),
|
|
77
|
+
check=False,
|
|
78
|
+
env=child_env,
|
|
79
|
+
)
|
|
80
|
+
except OSError as exc:
|
|
81
|
+
error_message = exc.strerror or str(exc)
|
|
82
|
+
raise click.ClickException(
|
|
83
|
+
f"Failed to start {command[0]}: {error_message}"
|
|
84
|
+
) from exc
|
|
85
|
+
|
|
86
|
+
return result.returncode
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
@click.command(
|
|
90
|
+
"connect",
|
|
91
|
+
help=(
|
|
92
|
+
"Connect to a room and run a local command with "
|
|
93
|
+
"MESHAGENT_API_URL, MESHAGENT_TOKEN, and MESHAGENT_ROOM set. "
|
|
94
|
+
"Use -- before the local command."
|
|
95
|
+
),
|
|
96
|
+
)
|
|
97
|
+
@click.option(
|
|
98
|
+
"--project-id",
|
|
99
|
+
help="A MeshAgent project id. If empty, the activated project will be used.",
|
|
100
|
+
)
|
|
101
|
+
@click.option("--room", help="Room name")
|
|
102
|
+
@click.argument("command", nargs=-1, type=click.UNPROCESSED)
|
|
103
|
+
def connect_command(
|
|
104
|
+
project_id: str | None,
|
|
105
|
+
room: str | None,
|
|
106
|
+
command: tuple[str, ...],
|
|
107
|
+
) -> None:
|
|
108
|
+
if len(command) == 0:
|
|
109
|
+
raise click.UsageError(
|
|
110
|
+
"Pass the local command after --, for example: "
|
|
111
|
+
"meshagent room connect -- python script.py"
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
room_env = async_typer._run_coroutine_sync(
|
|
115
|
+
_connect_room_env(project_id=project_id, room=room)
|
|
116
|
+
)
|
|
117
|
+
raise click.exceptions.Exit(
|
|
118
|
+
_run_connected_command(command=command, room_env=room_env)
|
|
119
|
+
)
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
from types import SimpleNamespace
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
from click.testing import CliRunner
|
|
5
|
+
|
|
6
|
+
from meshagent.cli import room_connect
|
|
7
|
+
from meshagent.cli import cli as root_cli
|
|
8
|
+
from meshagent.cli.async_typer import get_command
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class _FakeAccountClient:
|
|
12
|
+
def __init__(self) -> None:
|
|
13
|
+
self.base_url = "https://api.example.meshagent.test"
|
|
14
|
+
self.closed = False
|
|
15
|
+
self.connect_calls: list[dict[str, str]] = []
|
|
16
|
+
|
|
17
|
+
async def connect_room(self, *, project_id: str, room: str) -> SimpleNamespace:
|
|
18
|
+
self.connect_calls.append({"project_id": project_id, "room": room})
|
|
19
|
+
return SimpleNamespace(
|
|
20
|
+
jwt="room-jwt",
|
|
21
|
+
room_name="connected-room",
|
|
22
|
+
room_url="wss://room-proxy.meshagent.test/rooms/connected-room",
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
async def close(self) -> None:
|
|
26
|
+
self.closed = True
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def test_room_connect_runs_command_with_connected_room_env(
|
|
30
|
+
monkeypatch: pytest.MonkeyPatch,
|
|
31
|
+
) -> None:
|
|
32
|
+
account_client = _FakeAccountClient()
|
|
33
|
+
captured_run: dict[str, object] = {}
|
|
34
|
+
|
|
35
|
+
async def _fake_get_client() -> _FakeAccountClient:
|
|
36
|
+
return account_client
|
|
37
|
+
|
|
38
|
+
async def _fake_resolve_project_id(*, project_id: str | None) -> str:
|
|
39
|
+
assert project_id == "project-input"
|
|
40
|
+
return "project-1"
|
|
41
|
+
|
|
42
|
+
def _fake_resolve_room(room: str | None) -> str | None:
|
|
43
|
+
assert room == "room-input"
|
|
44
|
+
return room
|
|
45
|
+
|
|
46
|
+
def _fake_run(command, *, check: bool, env: dict[str, str]):
|
|
47
|
+
captured_run["command"] = command
|
|
48
|
+
captured_run["check"] = check
|
|
49
|
+
captured_run["env"] = env
|
|
50
|
+
return SimpleNamespace(returncode=23)
|
|
51
|
+
|
|
52
|
+
monkeypatch.setattr(room_connect, "get_client", _fake_get_client)
|
|
53
|
+
monkeypatch.setattr(room_connect, "resolve_project_id", _fake_resolve_project_id)
|
|
54
|
+
monkeypatch.setattr(room_connect, "resolve_room", _fake_resolve_room)
|
|
55
|
+
monkeypatch.setattr(room_connect.subprocess, "run", _fake_run)
|
|
56
|
+
monkeypatch.setattr(
|
|
57
|
+
room_connect,
|
|
58
|
+
"meshagent_base_url",
|
|
59
|
+
lambda: "https://default.meshagent.test",
|
|
60
|
+
)
|
|
61
|
+
monkeypatch.setenv("UNCHANGED_ENV", "keep-me")
|
|
62
|
+
monkeypatch.setenv("MESHAGENT_API_URL", "https://env.meshagent.test")
|
|
63
|
+
|
|
64
|
+
result = CliRunner().invoke(
|
|
65
|
+
get_command(root_cli.app),
|
|
66
|
+
[
|
|
67
|
+
"room",
|
|
68
|
+
"connect",
|
|
69
|
+
"--project-id",
|
|
70
|
+
"project-input",
|
|
71
|
+
"--room",
|
|
72
|
+
"room-input",
|
|
73
|
+
"--",
|
|
74
|
+
"python",
|
|
75
|
+
"-c",
|
|
76
|
+
"print('hello')",
|
|
77
|
+
],
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
assert result.exit_code == 23
|
|
81
|
+
assert account_client.connect_calls == [
|
|
82
|
+
{"project_id": "project-1", "room": "room-input"}
|
|
83
|
+
]
|
|
84
|
+
assert account_client.closed is True
|
|
85
|
+
assert captured_run["command"] == ["python", "-c", "print('hello')"]
|
|
86
|
+
assert captured_run["check"] is False
|
|
87
|
+
captured_env = captured_run["env"]
|
|
88
|
+
assert isinstance(captured_env, dict)
|
|
89
|
+
assert captured_env["UNCHANGED_ENV"] == "keep-me"
|
|
90
|
+
assert captured_env["MESHAGENT_API_URL"] == "https://env.meshagent.test"
|
|
91
|
+
assert captured_env["MESHAGENT_TOKEN"] == "room-jwt"
|
|
92
|
+
assert captured_env["MESHAGENT_ROOM"] == "connected-room"
|
|
93
|
+
assert (
|
|
94
|
+
captured_env["OPENAI_BASE_URL"]
|
|
95
|
+
== "https://room-proxy.meshagent.test/rooms/connected-room/openai/v1"
|
|
96
|
+
)
|
|
97
|
+
assert (
|
|
98
|
+
captured_env["ANTHROPIC_BASE_URL"]
|
|
99
|
+
== "https://room-proxy.meshagent.test/rooms/connected-room/anthropic"
|
|
100
|
+
)
|
|
101
|
+
assert captured_env["OPENAI_API_KEY"] == "room-jwt"
|
|
102
|
+
assert captured_env["ANTHROPIC_API_KEY"] == "room-jwt"
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
@pytest.mark.asyncio
|
|
106
|
+
async def test_room_connect_uses_default_api_url_when_env_is_unset(
|
|
107
|
+
monkeypatch: pytest.MonkeyPatch,
|
|
108
|
+
) -> None:
|
|
109
|
+
account_client = _FakeAccountClient()
|
|
110
|
+
|
|
111
|
+
async def _fake_get_client() -> _FakeAccountClient:
|
|
112
|
+
return account_client
|
|
113
|
+
|
|
114
|
+
async def _fake_resolve_project_id(*, project_id: str | None) -> str:
|
|
115
|
+
assert project_id == "project-input"
|
|
116
|
+
return "project-1"
|
|
117
|
+
|
|
118
|
+
def _fake_resolve_room(room: str | None) -> str | None:
|
|
119
|
+
assert room == "room-input"
|
|
120
|
+
return room
|
|
121
|
+
|
|
122
|
+
monkeypatch.setattr(room_connect, "get_client", _fake_get_client)
|
|
123
|
+
monkeypatch.setattr(room_connect, "resolve_project_id", _fake_resolve_project_id)
|
|
124
|
+
monkeypatch.setattr(room_connect, "resolve_room", _fake_resolve_room)
|
|
125
|
+
monkeypatch.setattr(
|
|
126
|
+
room_connect,
|
|
127
|
+
"meshagent_base_url",
|
|
128
|
+
lambda: "https://default.meshagent.test",
|
|
129
|
+
)
|
|
130
|
+
monkeypatch.delenv("MESHAGENT_API_URL", raising=False)
|
|
131
|
+
|
|
132
|
+
room_env = await room_connect._connect_room_env(
|
|
133
|
+
project_id="project-input",
|
|
134
|
+
room="room-input",
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
assert room_env.api_url == "https://default.meshagent.test"
|
|
138
|
+
assert room_env.room_name == "connected-room"
|
|
139
|
+
assert room_env.room_url == "https://room-proxy.meshagent.test/rooms/connected-room"
|
|
140
|
+
assert room_env.token == "room-jwt"
|
|
141
|
+
assert account_client.closed is True
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def test_room_connect_requires_command_after_separator() -> None:
|
|
145
|
+
result = CliRunner().invoke(
|
|
146
|
+
get_command(root_cli.app),
|
|
147
|
+
["room", "connect", "--"],
|
|
148
|
+
)
|
|
149
|
+
|
|
150
|
+
assert result.exit_code == 2
|
|
151
|
+
assert "Pass the local command after --" in result.output
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.36.2"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: meshagent-cli
|
|
3
|
-
Version: 0.36.
|
|
3
|
+
Version: 0.36.2
|
|
4
4
|
Summary: CLI for Meshagent
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
Project-URL: Documentation, https://docs.meshagent.com
|
|
@@ -20,21 +20,21 @@ Requires-Dist: rich~=14.3.0
|
|
|
20
20
|
Requires-Dist: textual<2.0,>=0.50
|
|
21
21
|
Requires-Dist: prompt-toolkit~=3.0.52
|
|
22
22
|
Provides-Extra: all
|
|
23
|
-
Requires-Dist: meshagent-agents[all]~=0.36.
|
|
24
|
-
Requires-Dist: meshagent-api[all]~=0.36.
|
|
25
|
-
Requires-Dist: meshagent-computers~=0.36.
|
|
26
|
-
Requires-Dist: meshagent-openai~=0.36.
|
|
27
|
-
Requires-Dist: meshagent-anthropic~=0.36.
|
|
28
|
-
Requires-Dist: meshagent-codex~=0.36.
|
|
29
|
-
Requires-Dist: meshagent-mcp~=0.36.
|
|
30
|
-
Requires-Dist: meshagent-tools~=0.36.
|
|
23
|
+
Requires-Dist: meshagent-agents[all]~=0.36.2; extra == "all"
|
|
24
|
+
Requires-Dist: meshagent-api[all]~=0.36.2; extra == "all"
|
|
25
|
+
Requires-Dist: meshagent-computers~=0.36.2; extra == "all"
|
|
26
|
+
Requires-Dist: meshagent-openai~=0.36.2; extra == "all"
|
|
27
|
+
Requires-Dist: meshagent-anthropic~=0.36.2; extra == "all"
|
|
28
|
+
Requires-Dist: meshagent-codex~=0.36.2; extra == "all"
|
|
29
|
+
Requires-Dist: meshagent-mcp~=0.36.2; extra == "all"
|
|
30
|
+
Requires-Dist: meshagent-tools~=0.36.2; extra == "all"
|
|
31
31
|
Requires-Dist: supabase-auth~=2.28.0; extra == "all"
|
|
32
32
|
Requires-Dist: prompt-toolkit~=3.0.52; extra == "all"
|
|
33
33
|
Provides-Extra: mcp-service
|
|
34
|
-
Requires-Dist: meshagent-agents[all]~=0.36.
|
|
35
|
-
Requires-Dist: meshagent-api~=0.36.
|
|
36
|
-
Requires-Dist: meshagent-mcp~=0.36.
|
|
37
|
-
Requires-Dist: meshagent-tools~=0.36.
|
|
34
|
+
Requires-Dist: meshagent-agents[all]~=0.36.2; extra == "mcp-service"
|
|
35
|
+
Requires-Dist: meshagent-api~=0.36.2; extra == "mcp-service"
|
|
36
|
+
Requires-Dist: meshagent-mcp~=0.36.2; extra == "mcp-service"
|
|
37
|
+
Requires-Dist: meshagent-tools~=0.36.2; extra == "mcp-service"
|
|
38
38
|
Requires-Dist: supabase-auth~=2.28.0; extra == "mcp-service"
|
|
39
39
|
|
|
40
40
|
# [Meshagent](https://www.meshagent.com)
|
|
@@ -8,6 +8,7 @@ meshagent/cli/async_typer.py
|
|
|
8
8
|
meshagent/cli/async_typer_test.py
|
|
9
9
|
meshagent/cli/auth.py
|
|
10
10
|
meshagent/cli/auth_async.py
|
|
11
|
+
meshagent/cli/auth_async_test.py
|
|
11
12
|
meshagent/cli/call.py
|
|
12
13
|
meshagent/cli/chatbot.py
|
|
13
14
|
meshagent/cli/cli.py
|
|
@@ -46,6 +47,8 @@ meshagent/cli/projects.py
|
|
|
46
47
|
meshagent/cli/queue.py
|
|
47
48
|
meshagent/cli/queue_test.py
|
|
48
49
|
meshagent/cli/room.py
|
|
50
|
+
meshagent/cli/room_connect.py
|
|
51
|
+
meshagent/cli/room_connect_test.py
|
|
49
52
|
meshagent/cli/room_services.py
|
|
50
53
|
meshagent/cli/rooms.py
|
|
51
54
|
meshagent/cli/root_commands.py
|
|
@@ -11,20 +11,20 @@ textual<2.0,>=0.50
|
|
|
11
11
|
prompt-toolkit~=3.0.52
|
|
12
12
|
|
|
13
13
|
[all]
|
|
14
|
-
meshagent-agents[all]~=0.36.
|
|
15
|
-
meshagent-api[all]~=0.36.
|
|
16
|
-
meshagent-computers~=0.36.
|
|
17
|
-
meshagent-openai~=0.36.
|
|
18
|
-
meshagent-anthropic~=0.36.
|
|
19
|
-
meshagent-codex~=0.36.
|
|
20
|
-
meshagent-mcp~=0.36.
|
|
21
|
-
meshagent-tools~=0.36.
|
|
14
|
+
meshagent-agents[all]~=0.36.2
|
|
15
|
+
meshagent-api[all]~=0.36.2
|
|
16
|
+
meshagent-computers~=0.36.2
|
|
17
|
+
meshagent-openai~=0.36.2
|
|
18
|
+
meshagent-anthropic~=0.36.2
|
|
19
|
+
meshagent-codex~=0.36.2
|
|
20
|
+
meshagent-mcp~=0.36.2
|
|
21
|
+
meshagent-tools~=0.36.2
|
|
22
22
|
supabase-auth~=2.28.0
|
|
23
23
|
prompt-toolkit~=3.0.52
|
|
24
24
|
|
|
25
25
|
[mcp-service]
|
|
26
|
-
meshagent-agents[all]~=0.36.
|
|
27
|
-
meshagent-api~=0.36.
|
|
28
|
-
meshagent-mcp~=0.36.
|
|
29
|
-
meshagent-tools~=0.36.
|
|
26
|
+
meshagent-agents[all]~=0.36.2
|
|
27
|
+
meshagent-api~=0.36.2
|
|
28
|
+
meshagent-mcp~=0.36.2
|
|
29
|
+
meshagent-tools~=0.36.2
|
|
30
30
|
supabase-auth~=2.28.0
|
|
@@ -27,23 +27,23 @@ dynamic = ["version", "readme"]
|
|
|
27
27
|
[project.optional-dependencies]
|
|
28
28
|
|
|
29
29
|
all = [
|
|
30
|
-
"meshagent-agents[all]~=0.36.
|
|
31
|
-
"meshagent-api[all]~=0.36.
|
|
32
|
-
"meshagent-computers~=0.36.
|
|
33
|
-
"meshagent-openai~=0.36.
|
|
34
|
-
"meshagent-anthropic~=0.36.
|
|
35
|
-
"meshagent-codex~=0.36.
|
|
36
|
-
"meshagent-mcp~=0.36.
|
|
37
|
-
"meshagent-tools~=0.36.
|
|
30
|
+
"meshagent-agents[all]~=0.36.2",
|
|
31
|
+
"meshagent-api[all]~=0.36.2",
|
|
32
|
+
"meshagent-computers~=0.36.2",
|
|
33
|
+
"meshagent-openai~=0.36.2",
|
|
34
|
+
"meshagent-anthropic~=0.36.2",
|
|
35
|
+
"meshagent-codex~=0.36.2",
|
|
36
|
+
"meshagent-mcp~=0.36.2",
|
|
37
|
+
"meshagent-tools~=0.36.2",
|
|
38
38
|
"supabase-auth~=2.28.0",
|
|
39
39
|
"prompt-toolkit~=3.0.52"
|
|
40
40
|
]
|
|
41
41
|
|
|
42
42
|
mcp-service = [
|
|
43
|
-
"meshagent-agents[all]~=0.36.
|
|
44
|
-
"meshagent-api~=0.36.
|
|
45
|
-
"meshagent-mcp~=0.36.
|
|
46
|
-
"meshagent-tools~=0.36.
|
|
43
|
+
"meshagent-agents[all]~=0.36.2",
|
|
44
|
+
"meshagent-api~=0.36.2",
|
|
45
|
+
"meshagent-mcp~=0.36.2",
|
|
46
|
+
"meshagent-tools~=0.36.2",
|
|
47
47
|
"supabase-auth~=2.28.0"
|
|
48
48
|
]
|
|
49
49
|
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.36.1"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|