akashcli 4.8.2__tar.gz → 4.8.4__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.
- {akashcli-4.8.2 → akashcli-4.8.4}/PKG-INFO +1 -1
- {akashcli-4.8.2 → akashcli-4.8.4}/akashcli/cli.py +271 -41
- {akashcli-4.8.2 → akashcli-4.8.4}/akashcli.egg-info/PKG-INFO +1 -1
- {akashcli-4.8.2 → akashcli-4.8.4}/pyproject.toml +1 -1
- {akashcli-4.8.2 → akashcli-4.8.4}/README.md +0 -0
- {akashcli-4.8.2 → akashcli-4.8.4}/akashcli/__init__.py +0 -0
- {akashcli-4.8.2 → akashcli-4.8.4}/akashcli/_net.py +0 -0
- {akashcli-4.8.2 → akashcli-4.8.4}/akashcli/auth.py +0 -0
- {akashcli-4.8.2 → akashcli-4.8.4}/akashcli/client.py +0 -0
- {akashcli-4.8.2 → akashcli-4.8.4}/akashcli/config.py +0 -0
- {akashcli-4.8.2 → akashcli-4.8.4}/akashcli/crypto.py +0 -0
- {akashcli-4.8.2 → akashcli-4.8.4}/akashcli/env_manager.py +0 -0
- {akashcli-4.8.2 → akashcli-4.8.4}/akashcli/exceptions.py +0 -0
- {akashcli-4.8.2 → akashcli-4.8.4}/akashcli/exec.py +0 -0
- {akashcli-4.8.2 → akashcli-4.8.4}/akashcli/integrity.py +0 -0
- {akashcli-4.8.2 → akashcli-4.8.4}/akashcli/logger.py +0 -0
- {akashcli-4.8.2 → akashcli-4.8.4}/akashcli/models.py +0 -0
- {akashcli-4.8.2 → akashcli-4.8.4}/akashcli/p2p.py +0 -0
- {akashcli-4.8.2 → akashcli-4.8.4}/akashcli/packages.py +0 -0
- {akashcli-4.8.2 → akashcli-4.8.4}/akashcli/relay.py +0 -0
- {akashcli-4.8.2 → akashcli-4.8.4}/akashcli/restore.py +0 -0
- {akashcli-4.8.2 → akashcli-4.8.4}/akashcli/snapshot_crypto.py +0 -0
- {akashcli-4.8.2 → akashcli-4.8.4}/akashcli/storage.py +0 -0
- {akashcli-4.8.2 → akashcli-4.8.4}/akashcli/terminal.py +0 -0
- {akashcli-4.8.2 → akashcli-4.8.4}/akashcli/updater.py +0 -0
- {akashcli-4.8.2 → akashcli-4.8.4}/akashcli/uploader.py +0 -0
- {akashcli-4.8.2 → akashcli-4.8.4}/akashcli/utils.py +0 -0
- {akashcli-4.8.2 → akashcli-4.8.4}/akashcli.egg-info/SOURCES.txt +0 -0
- {akashcli-4.8.2 → akashcli-4.8.4}/akashcli.egg-info/dependency_links.txt +0 -0
- {akashcli-4.8.2 → akashcli-4.8.4}/akashcli.egg-info/entry_points.txt +0 -0
- {akashcli-4.8.2 → akashcli-4.8.4}/akashcli.egg-info/requires.txt +0 -0
- {akashcli-4.8.2 → akashcli-4.8.4}/akashcli.egg-info/top_level.txt +0 -0
- {akashcli-4.8.2 → akashcli-4.8.4}/setup.cfg +0 -0
|
@@ -2774,43 +2774,131 @@ def _render_inspection_card(r: dict) -> None:
|
|
|
2774
2774
|
|
|
2775
2775
|
|
|
2776
2776
|
@agent_app.command("list")
|
|
2777
|
+
@agent_app.command("ls", hidden=True)
|
|
2778
|
+
@agent_app.command("ids", hidden=True)
|
|
2779
|
+
@agent_app.command("profiles", hidden=True)
|
|
2777
2780
|
def agent_list(raw: bool = typer.Option(False, "--json", help="Raw JSON output")):
|
|
2778
|
-
"""List all locally saved Agent Profile IDs and
|
|
2781
|
+
"""List all locally saved Agent & MCP Profile IDs, credentials, and launch commands."""
|
|
2779
2782
|
import json
|
|
2780
2783
|
from pathlib import Path
|
|
2784
|
+
|
|
2785
|
+
is_raw = bool(raw is True)
|
|
2781
2786
|
agents_file = Path.home() / ".akash" / "agents.json"
|
|
2782
2787
|
if not agents_file.exists():
|
|
2783
|
-
|
|
2788
|
+
_p()
|
|
2789
|
+
_info("No saved agent profiles found. Create one with: " + _cy("akash mcp create -n Dev -r @coder"))
|
|
2790
|
+
_p()
|
|
2784
2791
|
return
|
|
2785
2792
|
|
|
2786
2793
|
try:
|
|
2787
|
-
agents = json.loads(agents_file.read_text())
|
|
2794
|
+
agents = json.loads(agents_file.read_text(encoding="utf-8"))
|
|
2788
2795
|
except Exception:
|
|
2789
2796
|
agents = {}
|
|
2790
2797
|
|
|
2791
2798
|
if not agents:
|
|
2792
|
-
|
|
2799
|
+
_p()
|
|
2800
|
+
_info("No saved agent profiles found. Create one with: " + _cy("akash mcp create -n Dev -r @coder"))
|
|
2801
|
+
_p()
|
|
2793
2802
|
return
|
|
2794
2803
|
|
|
2795
|
-
if
|
|
2804
|
+
if is_raw:
|
|
2796
2805
|
print(json.dumps(agents, indent=2))
|
|
2797
2806
|
return
|
|
2798
2807
|
|
|
2808
|
+
default_pid = next(reversed(list(agents.keys())))
|
|
2809
|
+
|
|
2799
2810
|
_p()
|
|
2800
|
-
print(f" {_C}◈{_RS} {_W}
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2811
|
+
print(f" {_C}◈{_RS} {_W}Akash MCP Profiles & Agent IDs{_RS} {_dim(f'({len(agents)} configured)')}")
|
|
2812
|
+
print(f" {_GR}{'─'*76}{_RS}")
|
|
2813
|
+
|
|
2814
|
+
hdr_status = f"{'STATUS':<11}"
|
|
2815
|
+
hdr_id = f"{'ID':<8}"
|
|
2816
|
+
hdr_name = f"{'NAME':<16}"
|
|
2817
|
+
hdr_cid = f"{'CLIENT ID SUFFIX':<18}"
|
|
2818
|
+
hdr_scopes = "ROLE / SCOPES"
|
|
2819
|
+
print(f" {_DM}{hdr_status}{hdr_id}{hdr_name}{hdr_cid}{hdr_scopes}{_RS}")
|
|
2820
|
+
print(f" {_GR}{'─'*76}{_RS}")
|
|
2821
|
+
|
|
2822
|
+
import datetime
|
|
2823
|
+
now_utc = datetime.datetime.now(datetime.timezone.utc).replace(tzinfo=None)
|
|
2824
|
+
|
|
2825
|
+
last_suffix = ""
|
|
2826
|
+
expired_count = 0
|
|
2804
2827
|
for pid, data in agents.items():
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2828
|
+
is_default = (pid == default_pid)
|
|
2829
|
+
|
|
2830
|
+
# Check expiration status
|
|
2831
|
+
is_expired = False
|
|
2832
|
+
exp_val = data.get("expires_at")
|
|
2833
|
+
if exp_val:
|
|
2834
|
+
try:
|
|
2835
|
+
exp_dt = datetime.datetime.fromisoformat(exp_val.replace("Z", "+00:00")).replace(tzinfo=None)
|
|
2836
|
+
if exp_dt < now_utc:
|
|
2837
|
+
is_expired = True
|
|
2838
|
+
except Exception:
|
|
2839
|
+
pass
|
|
2840
|
+
|
|
2841
|
+
if is_expired:
|
|
2842
|
+
expired_count += 1
|
|
2843
|
+
status_txt = "✗ expired"
|
|
2844
|
+
status_color = _R
|
|
2845
|
+
elif is_default:
|
|
2846
|
+
status_txt = "● active"
|
|
2847
|
+
status_color = _G
|
|
2848
|
+
else:
|
|
2849
|
+
status_txt = "○ idle"
|
|
2850
|
+
status_color = _DM
|
|
2851
|
+
|
|
2852
|
+
name = data.get("name", "Agent")
|
|
2853
|
+
if len(name) > 14:
|
|
2854
|
+
name = name[:13] + "…"
|
|
2855
|
+
|
|
2856
|
+
cid = data.get("client_id", "")
|
|
2857
|
+
suffix = f"...{cid[-4:]}" if len(cid) >= 4 else cid
|
|
2858
|
+
if is_default:
|
|
2859
|
+
last_suffix = cid[-4:] if len(cid) >= 4 else cid
|
|
2860
|
+
|
|
2861
|
+
raw_scopes = data.get("scopes", "*")
|
|
2862
|
+
if raw_scopes == "*":
|
|
2863
|
+
scope_desc = "@full (All access)"
|
|
2864
|
+
elif "fs:no_delete" in raw_scopes and "workspace:write" in raw_scopes:
|
|
2865
|
+
scope_desc = "@coder (Safe Dev)"
|
|
2866
|
+
elif "workspace:write" in raw_scopes:
|
|
2867
|
+
scope_desc = "@editor (Code Edit)"
|
|
2868
|
+
elif "exec:read_only" in raw_scopes:
|
|
2869
|
+
scope_desc = "@viewer (Read-Only)"
|
|
2870
|
+
else:
|
|
2871
|
+
scope_desc = raw_scopes.split(",")[0] if raw_scopes else "custom"
|
|
2872
|
+
|
|
2873
|
+
# Safe alignment with ANSI colors
|
|
2874
|
+
c_status = f"{status_color}{status_txt}{_RS}" + " " * max(0, 11 - len(status_txt))
|
|
2875
|
+
c_id = f"{_ye(pid)}{_RS}" + " " * max(0, 8 - len(pid))
|
|
2876
|
+
c_name = f"{_W}{name}{_RS}" + " " * max(0, 16 - len(name))
|
|
2877
|
+
c_cid = f"{_cy(suffix)}{_RS}" + " " * max(0, 18 - len(suffix))
|
|
2878
|
+
c_scopes = f"{_dim(scope_desc)}"
|
|
2879
|
+
|
|
2880
|
+
print(f" {c_status}{c_id}{c_name}{c_cid}{c_scopes}")
|
|
2881
|
+
|
|
2882
|
+
print(f" {_GR}{'─'*76}{_RS}")
|
|
2883
|
+
if expired_count > 0:
|
|
2884
|
+
print(f" {_Y}⚡{_RS} {_W}{expired_count} profile(s) expired.{_RS} {_DM}Run {_cy('akash mcp renew <id>')} to extend or {_cy('akash mcp rm --expired')} to clean up.{_RS}\n")
|
|
2885
|
+
else:
|
|
2886
|
+
_p()
|
|
2887
|
+
print(f" {_W}Quick Launch:{_RS}")
|
|
2888
|
+
print(f" • Use default profile : {_C}akash mcp serve{_RS}")
|
|
2889
|
+
suffix_hint = f" {_dim('(or: --id ' + last_suffix + ')')}" if last_suffix else ""
|
|
2890
|
+
print(f" • Use specific ID : {_C}akash mcp serve --id {default_pid}{_RS}{suffix_hint}")
|
|
2891
|
+
print(f" • Clean idle profiles : {_C}akash mcp rm --all{_RS}")
|
|
2892
|
+
print(f" • Renew expiration : {_C}akash mcp renew {default_pid} --days 30{_RS}")
|
|
2893
|
+
print(f" • Create new profile : {_C}akash mcp create -n Dev -r @coder{_RS}")
|
|
2812
2894
|
_p()
|
|
2813
2895
|
|
|
2896
|
+
@mcp_app.callback(invoke_without_command=True)
|
|
2897
|
+
def mcp_callback(ctx: typer.Context):
|
|
2898
|
+
"""Model Context Protocol (MCP) server & AI agent tool bridge."""
|
|
2899
|
+
if ctx.invoked_subcommand is None:
|
|
2900
|
+
agent_list()
|
|
2901
|
+
|
|
2814
2902
|
|
|
2815
2903
|
|
|
2816
2904
|
def _resolve_agent_id(target_id: str) -> tuple[str, str, str]:
|
|
@@ -2941,6 +3029,12 @@ def agent_info(
|
|
|
2941
3029
|
status = d.get("status", "active") + " (live server)"
|
|
2942
3030
|
exp = d.get("expires_at", "unknown")[:19].replace("T", " ")
|
|
2943
3031
|
is_live = True
|
|
3032
|
+
if pid in all_a and d.get("expires_at"):
|
|
3033
|
+
all_a[pid]["expires_at"] = d.get("expires_at")
|
|
3034
|
+
try:
|
|
3035
|
+
agents_file.write_text(json.dumps(all_a, indent=2))
|
|
3036
|
+
except Exception:
|
|
3037
|
+
pass
|
|
2944
3038
|
elif r.status_code == 404:
|
|
2945
3039
|
status = "not found on server"
|
|
2946
3040
|
except Exception:
|
|
@@ -3015,42 +3109,175 @@ def agent_update(
|
|
|
3015
3109
|
else:
|
|
3016
3110
|
_err(f"Failed to update scopes: {res.text}")
|
|
3017
3111
|
|
|
3018
|
-
@agent_app.command("
|
|
3019
|
-
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3112
|
+
@agent_app.command("rm")
|
|
3113
|
+
@agent_app.command("remove", hidden=True)
|
|
3114
|
+
@agent_app.command("delete", hidden=True)
|
|
3115
|
+
@agent_app.command("revoke", hidden=True)
|
|
3116
|
+
def agent_remove(
|
|
3117
|
+
target: Optional[str] = typer.Argument(None, help="Profile ID (e.g. 88d7), Client ID suffix (e.g. ddff), or name"),
|
|
3118
|
+
all_idle: bool = typer.Option(False, "--all", "-a", help="Remove all idle profiles, keeping active default"),
|
|
3119
|
+
expired_only: bool = typer.Option(False, "--expired", "-e", help="Remove all expired profiles"),
|
|
3120
|
+
yes: bool = typer.Option(False, "--yes", "-y", "--force", "-f", help="Skip confirmation prompt"),
|
|
3121
|
+
url: Optional[str] = typer.Option(None, "--url", help="Override server URL"),
|
|
3023
3122
|
):
|
|
3024
|
-
"""
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3123
|
+
"""Remove / clean up one or more MCP profile IDs locally and on gateway."""
|
|
3124
|
+
import json, datetime
|
|
3125
|
+
from pathlib import Path
|
|
3126
|
+
agents_file = Path.home() / ".akash" / "agents.json"
|
|
3127
|
+
if not agents_file.exists():
|
|
3128
|
+
_info("No saved profiles to remove.")
|
|
3129
|
+
return
|
|
3130
|
+
|
|
3131
|
+
try:
|
|
3132
|
+
agents = json.loads(agents_file.read_text(encoding="utf-8"))
|
|
3133
|
+
except Exception:
|
|
3134
|
+
agents = {}
|
|
3135
|
+
|
|
3136
|
+
if not agents:
|
|
3137
|
+
_info("No saved profiles to remove.")
|
|
3138
|
+
return
|
|
3139
|
+
|
|
3140
|
+
default_pid = next(reversed(list(agents.keys())))
|
|
3141
|
+
now_utc = datetime.datetime.now(datetime.timezone.utc).replace(tzinfo=None)
|
|
3142
|
+
|
|
3143
|
+
targets_to_delete = []
|
|
3144
|
+
|
|
3145
|
+
if all_idle:
|
|
3146
|
+
for pid in list(agents.keys()):
|
|
3147
|
+
if pid != default_pid:
|
|
3148
|
+
targets_to_delete.append(pid)
|
|
3149
|
+
if not targets_to_delete:
|
|
3150
|
+
_info("No idle profiles to remove (only active profile exists).")
|
|
3151
|
+
return
|
|
3152
|
+
if not yes:
|
|
3153
|
+
try:
|
|
3154
|
+
sys.stdout.write(f" Remove {len(targets_to_delete)} idle profile(s)? [y/N]: ")
|
|
3155
|
+
sys.stdout.flush()
|
|
3156
|
+
ans = sys.stdin.readline().strip().lower()
|
|
3157
|
+
if ans not in ("y", "yes"):
|
|
3158
|
+
_info("Aborted.")
|
|
3159
|
+
return
|
|
3160
|
+
except (KeyboardInterrupt, EOFError):
|
|
3161
|
+
return
|
|
3162
|
+
|
|
3163
|
+
elif expired_only:
|
|
3164
|
+
for pid, d in list(agents.items()):
|
|
3165
|
+
exp_str = d.get("expires_at")
|
|
3166
|
+
if exp_str:
|
|
3167
|
+
try:
|
|
3168
|
+
exp_dt = datetime.datetime.fromisoformat(exp_str.replace("Z", "+00:00")).replace(tzinfo=None)
|
|
3169
|
+
if exp_dt < now_utc:
|
|
3170
|
+
targets_to_delete.append(pid)
|
|
3171
|
+
except Exception:
|
|
3172
|
+
pass
|
|
3173
|
+
if not targets_to_delete:
|
|
3174
|
+
_info("No expired profiles found to remove.")
|
|
3175
|
+
return
|
|
3176
|
+
|
|
3177
|
+
elif target:
|
|
3178
|
+
pid, cid, name = _resolve_agent_id(target)
|
|
3179
|
+
if pid not in agents:
|
|
3180
|
+
_err(f"Profile '{target}' not found in saved profiles.")
|
|
3181
|
+
raise typer.Exit(1)
|
|
3182
|
+
targets_to_delete.append(pid)
|
|
3183
|
+
|
|
3184
|
+
else:
|
|
3185
|
+
_err("Specify a Profile ID to remove (e.g. 'akash mcp rm 88d7'), or use '--all' / '--expired'.")
|
|
3186
|
+
_info(f"Run {_cy('akash mcp')} to view all IDs.")
|
|
3028
3187
|
raise typer.Exit(1)
|
|
3029
3188
|
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3189
|
+
_p()
|
|
3190
|
+
removed_count = 0
|
|
3191
|
+
for pid in targets_to_delete:
|
|
3192
|
+
d = agents.get(pid, {})
|
|
3193
|
+
name = d.get("name", "Agent")
|
|
3194
|
+
cid = d.get("client_id", "")
|
|
3195
|
+
suffix = cid[-4:] if len(cid) >= 4 else ""
|
|
3196
|
+
|
|
3197
|
+
# Best-effort remote revocation on gateway
|
|
3198
|
+
target_url = url or d.get("url")
|
|
3199
|
+
_, base = _resolve_client(target_url, require_key=False, silent=True)
|
|
3200
|
+
if cid and base:
|
|
3201
|
+
try:
|
|
3202
|
+
httpx.delete(f"{base}/api/agent/app/{cid}", timeout=3.0)
|
|
3203
|
+
except Exception:
|
|
3204
|
+
pass
|
|
3205
|
+
|
|
3206
|
+
if pid in agents:
|
|
3207
|
+
del agents[pid]
|
|
3208
|
+
removed_count += 1
|
|
3209
|
+
print(f" {_G}✓{_RS} Removed profile {_W}{name}{_RS} ({_ye(pid)}{_dim(' · ...' + suffix if suffix else '')})")
|
|
3210
|
+
|
|
3211
|
+
try:
|
|
3212
|
+
agents_file.write_text(json.dumps(agents, indent=2))
|
|
3213
|
+
except Exception:
|
|
3214
|
+
pass
|
|
3034
3215
|
|
|
3035
|
-
|
|
3036
|
-
|
|
3216
|
+
_p()
|
|
3217
|
+
_ok(f"Cleaned up {removed_count} MCP profile(s). {len(agents)} profile(s) remaining.")
|
|
3218
|
+
_p()
|
|
3037
3219
|
|
|
3038
|
-
|
|
3220
|
+
@agent_app.command("renew")
|
|
3221
|
+
def agent_renew(
|
|
3222
|
+
target: Optional[str] = typer.Argument(None, help="Profile ID, Client ID suffix, or name (defaults to active profile)"),
|
|
3223
|
+
days: int = typer.Option(7, "--days", "-d", help="Number of days to extend validity (default: 7)"),
|
|
3224
|
+
url: Optional[str] = typer.Option(None, "--url", help="Override server URL"),
|
|
3225
|
+
):
|
|
3226
|
+
"""Renew/extend the validity of an MCP profile / agent ID."""
|
|
3039
3227
|
import json
|
|
3040
3228
|
from pathlib import Path
|
|
3041
3229
|
agents_file = Path.home() / ".akash" / "agents.json"
|
|
3042
|
-
if agents_file.exists():
|
|
3230
|
+
if not agents_file.exists():
|
|
3231
|
+
_err("No saved profiles found.")
|
|
3232
|
+
raise typer.Exit(1)
|
|
3233
|
+
|
|
3234
|
+
try:
|
|
3235
|
+
agents = json.loads(agents_file.read_text(encoding="utf-8"))
|
|
3236
|
+
except Exception:
|
|
3237
|
+
agents = {}
|
|
3238
|
+
|
|
3239
|
+
if not agents:
|
|
3240
|
+
_err("No saved profiles found.")
|
|
3241
|
+
raise typer.Exit(1)
|
|
3242
|
+
|
|
3243
|
+
target_id = target
|
|
3244
|
+
if not target_id:
|
|
3245
|
+
target_id = next(reversed(list(agents.keys())))
|
|
3246
|
+
|
|
3247
|
+
pid, cid, name = _resolve_agent_id(target_id)
|
|
3248
|
+
cached = agents.get(pid, {})
|
|
3249
|
+
target_url = url or cached.get("url")
|
|
3250
|
+
_, base = _resolve_client(target_url, require_key=False, silent=True)
|
|
3251
|
+
|
|
3252
|
+
with _Spin(f"renewing MCP profile {pid} ({name}) for {days} days…"):
|
|
3043
3253
|
try:
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3254
|
+
res = httpx.patch(
|
|
3255
|
+
f"{base}/api/agent/app/{cid}",
|
|
3256
|
+
json={"renew": True, "ttl_days": days},
|
|
3257
|
+
timeout=8.0
|
|
3258
|
+
)
|
|
3259
|
+
except Exception as e:
|
|
3260
|
+
_err(f"Network error contacting gateway ({base}): {e}")
|
|
3261
|
+
raise typer.Exit(1)
|
|
3049
3262
|
|
|
3050
3263
|
if res.status_code == 200:
|
|
3051
|
-
|
|
3264
|
+
d = res.json()
|
|
3265
|
+
new_exp = d.get("expires_at", "")
|
|
3266
|
+
if pid in agents:
|
|
3267
|
+
agents[pid]["expires_at"] = new_exp
|
|
3268
|
+
try:
|
|
3269
|
+
agents_file.write_text(json.dumps(agents, indent=2))
|
|
3270
|
+
except Exception:
|
|
3271
|
+
pass
|
|
3272
|
+
_p()
|
|
3273
|
+
_ok(f"Successfully renewed profile {_ye(name)} ({_C}{pid}{_RS} · {_dim('...' + cid[-4:])}) for {_G}{days} days{_RS}!")
|
|
3274
|
+
if new_exp:
|
|
3275
|
+
exp_clean = new_exp[:19].replace("T", " ")
|
|
3276
|
+
print(f" {_DM}New Expiration : {_RS}{_cy(exp_clean)} UTC")
|
|
3277
|
+
_p()
|
|
3052
3278
|
else:
|
|
3053
|
-
|
|
3279
|
+
_err(f"Failed to renew profile on gateway: HTTP {res.status_code} - {res.text}")
|
|
3280
|
+
raise typer.Exit(1)
|
|
3054
3281
|
|
|
3055
3282
|
|
|
3056
3283
|
@agent_app.command("create")
|
|
@@ -3101,6 +3328,7 @@ def agent_create(
|
|
|
3101
3328
|
"client_secret": d["client_secret"],
|
|
3102
3329
|
"name": name,
|
|
3103
3330
|
"scopes": d.get("scopes", effective_scopes),
|
|
3331
|
+
"expires_at": d.get("expires_at"),
|
|
3104
3332
|
"url": base
|
|
3105
3333
|
}
|
|
3106
3334
|
agents_file.write_text(json.dumps(agents, indent=2))
|
|
@@ -3603,7 +3831,9 @@ def mcp_serve(
|
|
|
3603
3831
|
print(" " + _GR + "──────────────────────────────────────────────────" + _RS)
|
|
3604
3832
|
print(" " + _DM + "Workspace : " + _RS + _cy(str(Path.cwd())))
|
|
3605
3833
|
print(" " + _DM + "Gateway : " + _RS + _dim(base))
|
|
3606
|
-
|
|
3834
|
+
cid_suffix = f"...{cid[-4:]}" if cid and len(cid) >= 4 else ""
|
|
3835
|
+
suffix_tag = f" · client: {cid_suffix}" if cid_suffix else ""
|
|
3836
|
+
print(" " + _DM + "Profile : " + _RS + _ye(pname) + " " + _dim("(" + (profile_id or "custom") + suffix_tag + ")"))
|
|
3607
3837
|
print(" " + _GR + "──────────────────────────────────────────────────" + _RS)
|
|
3608
3838
|
print(" " + _DM + "Active Tools:" + _RS)
|
|
3609
3839
|
print(" • akash_exec_command " + _dim("(Safe terminal runner)"))
|
|
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
|