glaip-sdk 0.0.1b5__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.
- glaip_sdk/__init__.py +12 -0
- glaip_sdk/cli/__init__.py +9 -0
- glaip_sdk/cli/commands/__init__.py +5 -0
- glaip_sdk/cli/commands/agents.py +415 -0
- glaip_sdk/cli/commands/configure.py +316 -0
- glaip_sdk/cli/commands/init.py +168 -0
- glaip_sdk/cli/commands/mcps.py +473 -0
- glaip_sdk/cli/commands/models.py +52 -0
- glaip_sdk/cli/commands/tools.py +309 -0
- glaip_sdk/cli/config.py +592 -0
- glaip_sdk/cli/main.py +298 -0
- glaip_sdk/cli/utils.py +733 -0
- glaip_sdk/client/__init__.py +179 -0
- glaip_sdk/client/agents.py +441 -0
- glaip_sdk/client/base.py +223 -0
- glaip_sdk/client/mcps.py +94 -0
- glaip_sdk/client/tools.py +193 -0
- glaip_sdk/client/validators.py +166 -0
- glaip_sdk/config/constants.py +28 -0
- glaip_sdk/exceptions.py +93 -0
- glaip_sdk/models.py +190 -0
- glaip_sdk/utils/__init__.py +95 -0
- glaip_sdk/utils/run_renderer.py +1009 -0
- glaip_sdk/utils.py +167 -0
- glaip_sdk-0.0.1b5.dist-info/METADATA +633 -0
- glaip_sdk-0.0.1b5.dist-info/RECORD +28 -0
- glaip_sdk-0.0.1b5.dist-info/WHEEL +4 -0
- glaip_sdk-0.0.1b5.dist-info/entry_points.txt +2 -0
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
"""Configuration management commands.
|
|
2
|
+
|
|
3
|
+
Authors:
|
|
4
|
+
Raymond Christopher (raymond.christopher@gdplabs.id)
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import getpass
|
|
8
|
+
import os
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
import click
|
|
12
|
+
import yaml
|
|
13
|
+
from rich.console import Console
|
|
14
|
+
from rich.panel import Panel
|
|
15
|
+
from rich.table import Table
|
|
16
|
+
|
|
17
|
+
console = Console()
|
|
18
|
+
|
|
19
|
+
CONFIG_DIR = Path.home() / ".aip"
|
|
20
|
+
CONFIG_FILE = CONFIG_DIR / "config.yaml"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def load_config():
|
|
24
|
+
"""Load configuration from file."""
|
|
25
|
+
if not CONFIG_FILE.exists():
|
|
26
|
+
return {}
|
|
27
|
+
|
|
28
|
+
with open(CONFIG_FILE) as f:
|
|
29
|
+
return yaml.safe_load(f) or {}
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def save_config(config):
|
|
33
|
+
"""Save configuration to file."""
|
|
34
|
+
CONFIG_DIR.mkdir(exist_ok=True)
|
|
35
|
+
|
|
36
|
+
with open(CONFIG_FILE, "w") as f:
|
|
37
|
+
yaml.dump(config, f, default_flow_style=False)
|
|
38
|
+
|
|
39
|
+
# Set secure file permissions
|
|
40
|
+
try:
|
|
41
|
+
os.chmod(CONFIG_FILE, 0o600)
|
|
42
|
+
except Exception:
|
|
43
|
+
pass # Best effort
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@click.group()
|
|
47
|
+
def config_group():
|
|
48
|
+
"""Configuration management operations."""
|
|
49
|
+
pass
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@config_group.command()
|
|
53
|
+
def configure():
|
|
54
|
+
"""Configure AIP CLI credentials and settings interactively."""
|
|
55
|
+
|
|
56
|
+
console.print(
|
|
57
|
+
Panel(
|
|
58
|
+
"[bold cyan]AIP Configuration[/bold cyan]\nConfigure your AIP CLI settings.",
|
|
59
|
+
title="š§ Configuration Setup",
|
|
60
|
+
border_style="cyan",
|
|
61
|
+
)
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
# Load existing config
|
|
65
|
+
config = load_config()
|
|
66
|
+
|
|
67
|
+
console.print("\n[bold]Enter your AIP configuration:[/bold]")
|
|
68
|
+
console.print("(Leave blank to keep current values)")
|
|
69
|
+
console.print("ā" * 50)
|
|
70
|
+
|
|
71
|
+
# API URL
|
|
72
|
+
current_url = config.get("api_url", "")
|
|
73
|
+
console.print(
|
|
74
|
+
f"\n[cyan]AIP API URL[/cyan] {f'(current: {current_url})' if current_url else ''}:"
|
|
75
|
+
)
|
|
76
|
+
new_url = input("> ").strip()
|
|
77
|
+
if new_url:
|
|
78
|
+
config["api_url"] = new_url
|
|
79
|
+
elif not current_url:
|
|
80
|
+
config["api_url"] = "https://your-aip-instance.com"
|
|
81
|
+
|
|
82
|
+
# API Key
|
|
83
|
+
current_key_masked = (
|
|
84
|
+
"***" + config.get("api_key", "")[-4:] if config.get("api_key") else ""
|
|
85
|
+
)
|
|
86
|
+
console.print(
|
|
87
|
+
f"\n[cyan]AIP API Key[/cyan] {f'(current: {current_key_masked})' if current_key_masked else ''}:"
|
|
88
|
+
)
|
|
89
|
+
new_key = getpass.getpass("> ")
|
|
90
|
+
if new_key:
|
|
91
|
+
config["api_key"] = new_key
|
|
92
|
+
|
|
93
|
+
# Save configuration
|
|
94
|
+
save_config(config)
|
|
95
|
+
|
|
96
|
+
console.print(f"\nā
Configuration saved to: {CONFIG_FILE}")
|
|
97
|
+
|
|
98
|
+
# Test the new configuration
|
|
99
|
+
console.print("\nš Testing connection...")
|
|
100
|
+
try:
|
|
101
|
+
from glaip_sdk import Client
|
|
102
|
+
|
|
103
|
+
# Create client with new config
|
|
104
|
+
client = Client(api_url=config["api_url"], api_key=config["api_key"])
|
|
105
|
+
|
|
106
|
+
# Try to list resources to test connection
|
|
107
|
+
try:
|
|
108
|
+
agents = client.list_agents()
|
|
109
|
+
console.print(f"ā
Connection successful! Found {len(agents)} agents")
|
|
110
|
+
except Exception as e:
|
|
111
|
+
console.print(f"ā ļø Connection established but API call failed: {e}")
|
|
112
|
+
console.print(
|
|
113
|
+
" You may need to check your API permissions or network access"
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
client.close()
|
|
117
|
+
|
|
118
|
+
except Exception as e:
|
|
119
|
+
console.print(f"ā Connection failed: {e}")
|
|
120
|
+
console.print(" Please check your API URL and key")
|
|
121
|
+
console.print(" You can run 'aip status' later to test again")
|
|
122
|
+
|
|
123
|
+
console.print("\nš” You can now use AIP CLI commands!")
|
|
124
|
+
console.print(" ⢠Run 'aip status' to check connection")
|
|
125
|
+
console.print(" ⢠Run 'aip agents list' to see your agents")
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
@config_group.command("list")
|
|
129
|
+
def list_config():
|
|
130
|
+
"""List current configuration."""
|
|
131
|
+
|
|
132
|
+
config = load_config()
|
|
133
|
+
|
|
134
|
+
if not config:
|
|
135
|
+
console.print(
|
|
136
|
+
"[yellow]No configuration found. Run 'aip config configure' to set up.[/yellow]"
|
|
137
|
+
)
|
|
138
|
+
return
|
|
139
|
+
|
|
140
|
+
table = Table(title="š§ AIP Configuration")
|
|
141
|
+
table.add_column("Setting", style="cyan", width=20)
|
|
142
|
+
table.add_column("Value", style="green")
|
|
143
|
+
|
|
144
|
+
for key, value in config.items():
|
|
145
|
+
if key == "api_key" and value:
|
|
146
|
+
# Mask the API key
|
|
147
|
+
masked_value = "***" + value[-4:] if len(value) > 4 else "***"
|
|
148
|
+
table.add_row(key, masked_value)
|
|
149
|
+
else:
|
|
150
|
+
table.add_row(key, str(value))
|
|
151
|
+
|
|
152
|
+
console.print(table)
|
|
153
|
+
console.print(f"\nš Config file: {CONFIG_FILE}")
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
@config_group.command("set")
|
|
157
|
+
@click.argument("key")
|
|
158
|
+
@click.argument("value")
|
|
159
|
+
def set_config(key, value):
|
|
160
|
+
"""Set a configuration value."""
|
|
161
|
+
|
|
162
|
+
valid_keys = ["api_url", "api_key"]
|
|
163
|
+
|
|
164
|
+
if key not in valid_keys:
|
|
165
|
+
console.print(
|
|
166
|
+
f"[red]Error: Invalid key '{key}'. Valid keys are: {', '.join(valid_keys)}[/red]"
|
|
167
|
+
)
|
|
168
|
+
raise click.ClickException(f"Invalid configuration key: {key}")
|
|
169
|
+
|
|
170
|
+
config = load_config()
|
|
171
|
+
config[key] = value
|
|
172
|
+
save_config(config)
|
|
173
|
+
|
|
174
|
+
if key == "api_key":
|
|
175
|
+
masked_value = "***" + value[-4:] if len(value) > 4 else "***"
|
|
176
|
+
console.print(f"ā
Set {key} = {masked_value}")
|
|
177
|
+
else:
|
|
178
|
+
console.print(f"ā
Set {key} = {value}")
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
@config_group.command("get")
|
|
182
|
+
@click.argument("key")
|
|
183
|
+
def get_config(key):
|
|
184
|
+
"""Get a configuration value."""
|
|
185
|
+
|
|
186
|
+
config = load_config()
|
|
187
|
+
|
|
188
|
+
if key not in config:
|
|
189
|
+
console.print(f"[yellow]Configuration key '{key}' not found.[/yellow]")
|
|
190
|
+
raise click.ClickException(f"Configuration key not found: {key}")
|
|
191
|
+
|
|
192
|
+
value = config[key]
|
|
193
|
+
|
|
194
|
+
if key == "api_key":
|
|
195
|
+
# Mask the API key for display
|
|
196
|
+
masked_value = "***" + value[-4:] if len(value) > 4 else "***"
|
|
197
|
+
console.print(masked_value)
|
|
198
|
+
else:
|
|
199
|
+
console.print(value)
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
@config_group.command("unset")
|
|
203
|
+
@click.argument("key")
|
|
204
|
+
def unset_config(key):
|
|
205
|
+
"""Remove a configuration value."""
|
|
206
|
+
|
|
207
|
+
config = load_config()
|
|
208
|
+
|
|
209
|
+
if key not in config:
|
|
210
|
+
console.print(f"[yellow]Configuration key '{key}' not found.[/yellow]")
|
|
211
|
+
return
|
|
212
|
+
|
|
213
|
+
del config[key]
|
|
214
|
+
save_config(config)
|
|
215
|
+
|
|
216
|
+
console.print(f"ā
Removed {key} from configuration")
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
@config_group.command("reset")
|
|
220
|
+
@click.option("--force", is_flag=True, help="Skip confirmation prompt")
|
|
221
|
+
def reset_config(force):
|
|
222
|
+
"""Reset all configuration to defaults."""
|
|
223
|
+
|
|
224
|
+
if not force:
|
|
225
|
+
console.print("[yellow]This will remove all AIP configuration.[/yellow]")
|
|
226
|
+
confirm = input("Are you sure? (y/N): ").strip().lower()
|
|
227
|
+
if confirm not in ["y", "yes"]:
|
|
228
|
+
console.print("Cancelled.")
|
|
229
|
+
return
|
|
230
|
+
|
|
231
|
+
if CONFIG_FILE.exists():
|
|
232
|
+
CONFIG_FILE.unlink()
|
|
233
|
+
console.print(
|
|
234
|
+
"ā
Configuration reset. Run 'aip config configure' to set up again."
|
|
235
|
+
)
|
|
236
|
+
else:
|
|
237
|
+
console.print("[yellow]No configuration found to reset.[/yellow]")
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
# Note: The config command group should be registered in main.py
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
@click.command()
|
|
244
|
+
def configure_command():
|
|
245
|
+
"""Configure AIP CLI credentials and settings interactively."""
|
|
246
|
+
|
|
247
|
+
console.print(
|
|
248
|
+
Panel(
|
|
249
|
+
"[bold cyan]AIP Configuration[/bold cyan]\nConfigure your AIP CLI settings.",
|
|
250
|
+
title="š§ Configuration Setup",
|
|
251
|
+
border_style="cyan",
|
|
252
|
+
)
|
|
253
|
+
)
|
|
254
|
+
|
|
255
|
+
# Load existing config
|
|
256
|
+
config = load_config()
|
|
257
|
+
|
|
258
|
+
console.print("\n[bold]Enter your AIP configuration:[/bold]")
|
|
259
|
+
console.print("(Leave blank to keep current values)")
|
|
260
|
+
console.print("ā" * 50)
|
|
261
|
+
|
|
262
|
+
# API URL
|
|
263
|
+
current_url = config.get("api_url", "")
|
|
264
|
+
console.print(
|
|
265
|
+
f"\n[cyan]AIP API URL[/cyan] {f'(current: {current_url})' if current_url else ''}:"
|
|
266
|
+
)
|
|
267
|
+
new_url = input("> ").strip()
|
|
268
|
+
if new_url:
|
|
269
|
+
config["api_url"] = new_url
|
|
270
|
+
elif not current_url:
|
|
271
|
+
config["api_url"] = "https://your-aip-instance.com"
|
|
272
|
+
|
|
273
|
+
# API Key
|
|
274
|
+
current_key_masked = (
|
|
275
|
+
"***" + config.get("api_key", "")[-4:] if config.get("api_key") else ""
|
|
276
|
+
)
|
|
277
|
+
console.print(
|
|
278
|
+
f"\n[cyan]AIP API Key[/cyan] {f'(current: {current_key_masked})' if current_key_masked else ''}:"
|
|
279
|
+
)
|
|
280
|
+
new_key = getpass.getpass("> ")
|
|
281
|
+
if new_key:
|
|
282
|
+
config["api_key"] = new_key
|
|
283
|
+
|
|
284
|
+
# Save configuration
|
|
285
|
+
save_config(config)
|
|
286
|
+
|
|
287
|
+
console.print(f"\nā
Configuration saved to: {CONFIG_FILE}")
|
|
288
|
+
|
|
289
|
+
# Test the new configuration
|
|
290
|
+
console.print("\nš Testing connection...")
|
|
291
|
+
try:
|
|
292
|
+
from glaip_sdk import Client
|
|
293
|
+
|
|
294
|
+
# Create client with new config
|
|
295
|
+
client = Client(api_url=config["api_url"], api_key=config["api_key"])
|
|
296
|
+
|
|
297
|
+
# Try to list resources to test connection
|
|
298
|
+
try:
|
|
299
|
+
agents = client.list_agents()
|
|
300
|
+
console.print(f"ā
Connection successful! Found {len(agents)} agents")
|
|
301
|
+
except Exception as e:
|
|
302
|
+
console.print(f"ā ļø Connection established but API call failed: {e}")
|
|
303
|
+
console.print(
|
|
304
|
+
" You may need to check your API permissions or network access"
|
|
305
|
+
)
|
|
306
|
+
|
|
307
|
+
client.close()
|
|
308
|
+
|
|
309
|
+
except Exception as e:
|
|
310
|
+
console.print(f"ā Connection failed: {e}")
|
|
311
|
+
console.print(" Please check your API URL and key")
|
|
312
|
+
console.print(" You can run 'aip status' later to test again")
|
|
313
|
+
|
|
314
|
+
console.print("\nš” You can now use AIP CLI commands!")
|
|
315
|
+
console.print(" ⢠Run 'aip status' to check connection")
|
|
316
|
+
console.print(" ⢠Run 'aip agents list' to see your agents")
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"""CLI initialization command.
|
|
2
|
+
|
|
3
|
+
Authors:
|
|
4
|
+
Raymond Christopher (raymond.christopher@gdplabs.id)
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import getpass
|
|
8
|
+
import os
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
import click
|
|
12
|
+
import yaml
|
|
13
|
+
from rich.console import Console
|
|
14
|
+
from rich.panel import Panel
|
|
15
|
+
|
|
16
|
+
console = Console()
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@click.command()
|
|
20
|
+
@click.option("--no-scaffold", is_flag=True, help="Skip creating sample agent and tool")
|
|
21
|
+
@click.option("--no-demo", is_flag=True, help="Don't launch interactive demo")
|
|
22
|
+
def init_command(no_scaffold, no_demo):
|
|
23
|
+
"""Initialize AIP project configuration."""
|
|
24
|
+
|
|
25
|
+
console.print(
|
|
26
|
+
Panel(
|
|
27
|
+
"[bold cyan]Welcome to AIP![/bold cyan]\nLet's set up your project.",
|
|
28
|
+
title="š AIP Initialization",
|
|
29
|
+
border_style="cyan",
|
|
30
|
+
)
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
# Get configuration with better formatting
|
|
34
|
+
console.print("\n[bold]Step 1:[/bold] API Configuration")
|
|
35
|
+
console.print("ā" * 50)
|
|
36
|
+
|
|
37
|
+
# Use built-in input for better control
|
|
38
|
+
console.print(
|
|
39
|
+
"\n[cyan]AIP API URL[/cyan] (default: https://your-aip-instance.com):"
|
|
40
|
+
)
|
|
41
|
+
api_url = input("> ").strip()
|
|
42
|
+
if not api_url:
|
|
43
|
+
api_url = "https://your-aip-instance.com"
|
|
44
|
+
|
|
45
|
+
console.print() # Add spacing
|
|
46
|
+
console.print("[cyan]AIP API Key[/cyan]:")
|
|
47
|
+
api_key = getpass.getpass("> ")
|
|
48
|
+
|
|
49
|
+
# Project configuration removed - not needed for AIP CLI
|
|
50
|
+
|
|
51
|
+
# Create config directory
|
|
52
|
+
config_dir = Path.home() / ".aip"
|
|
53
|
+
config_dir.mkdir(exist_ok=True)
|
|
54
|
+
|
|
55
|
+
# Save configuration
|
|
56
|
+
config = {"api_url": api_url, "api_key": api_key}
|
|
57
|
+
|
|
58
|
+
config_file = config_dir / "config.yaml"
|
|
59
|
+
with open(config_file, "w") as f:
|
|
60
|
+
yaml.dump(config, f, default_flow_style=False)
|
|
61
|
+
|
|
62
|
+
# Set secure file permissions (0600) - best effort on all platforms
|
|
63
|
+
try:
|
|
64
|
+
os.chmod(config_file, 0o600)
|
|
65
|
+
except Exception:
|
|
66
|
+
# Best effort - may fail on Windows or other non-POSIX systems
|
|
67
|
+
pass
|
|
68
|
+
|
|
69
|
+
console.print(f"\nā
Configuration saved to: {config_file}")
|
|
70
|
+
|
|
71
|
+
# Create sample agent and tool if requested
|
|
72
|
+
if not no_scaffold:
|
|
73
|
+
console.print("\n[bold]Step 2:[/bold] Sample Resources")
|
|
74
|
+
console.print("ā" * 50)
|
|
75
|
+
|
|
76
|
+
console.print("\n[cyan]Create sample agent & tool?[/cyan] (Y/n):")
|
|
77
|
+
create_sample_resources = input("> ").strip().lower()
|
|
78
|
+
if create_sample_resources in ["", "y", "yes"]:
|
|
79
|
+
try:
|
|
80
|
+
from glaip_sdk import Client
|
|
81
|
+
|
|
82
|
+
# Set environment variables
|
|
83
|
+
os.environ["AIP_API_URL"] = api_url
|
|
84
|
+
os.environ["AIP_API_KEY"] = api_key
|
|
85
|
+
|
|
86
|
+
client = Client()
|
|
87
|
+
|
|
88
|
+
# Create sample agent
|
|
89
|
+
agent = client.create_agent(
|
|
90
|
+
name="hello-world",
|
|
91
|
+
instruction="You are a helpful AI assistant that says hello",
|
|
92
|
+
)
|
|
93
|
+
console.print(f"ā
Created sample agent: {agent.name} (id: {agent.id})")
|
|
94
|
+
|
|
95
|
+
# Create sample tool
|
|
96
|
+
tool_content = '''def hello_tool(name="World"):
|
|
97
|
+
"""A simple hello tool."""
|
|
98
|
+
return f"Hello, {name}!"
|
|
99
|
+
'''
|
|
100
|
+
with open("greeting_tool.py", "w") as f:
|
|
101
|
+
f.write(tool_content)
|
|
102
|
+
|
|
103
|
+
tool = client.create_tool("greeting_tool.py", framework="langchain")
|
|
104
|
+
console.print(f"ā
Created sample tool: {tool.name} (id: {tool.id})")
|
|
105
|
+
|
|
106
|
+
except Exception as e:
|
|
107
|
+
console.print(f"ā ļø Warning: Could not create sample resources: {e}")
|
|
108
|
+
|
|
109
|
+
# Launch interactive demo if requested
|
|
110
|
+
if not no_demo:
|
|
111
|
+
console.print("\n[bold]Step 3:[/bold] Interactive Demo")
|
|
112
|
+
console.print("ā" * 50)
|
|
113
|
+
|
|
114
|
+
console.print("\n[cyan]Start an interactive demo now?[/cyan] (Y/n):")
|
|
115
|
+
launch_demo = input("> ").strip().lower()
|
|
116
|
+
if launch_demo in ["", "y", "yes"]:
|
|
117
|
+
launch_interactive_demo()
|
|
118
|
+
|
|
119
|
+
console.print("\nš [bold green]AIP initialization complete![/bold green]")
|
|
120
|
+
console.print(f"š Configuration: {config_file}")
|
|
121
|
+
console.print("š” Next steps:")
|
|
122
|
+
console.print(" ⢠Run 'aip agents list' to see your agents")
|
|
123
|
+
console.print(" ⢠Run 'aip tools list' to see your tools")
|
|
124
|
+
console.print(" ⢠Run 'aip status' to check connection")
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def launch_interactive_demo():
|
|
128
|
+
"""Launch interactive demo with sample agent."""
|
|
129
|
+
try:
|
|
130
|
+
from glaip_sdk import Client
|
|
131
|
+
|
|
132
|
+
console.print(
|
|
133
|
+
Panel(
|
|
134
|
+
"[bold green]Interactive Demo[/bold green]\nType to talk to hello-world. Ctrl+C to exit.",
|
|
135
|
+
title="š® Demo Mode",
|
|
136
|
+
border_style="green",
|
|
137
|
+
)
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
client = Client()
|
|
141
|
+
agents = client.find_agents(name="hello-world")
|
|
142
|
+
if not agents:
|
|
143
|
+
console.print("ā Sample agent not found")
|
|
144
|
+
return
|
|
145
|
+
|
|
146
|
+
agent = agents[0] # Use the first (and should be only) agent
|
|
147
|
+
|
|
148
|
+
while True:
|
|
149
|
+
try:
|
|
150
|
+
console.print("\n> ", end="")
|
|
151
|
+
user_input = input().strip()
|
|
152
|
+
if user_input.lower() in ["exit", "quit", "bye"]:
|
|
153
|
+
break
|
|
154
|
+
|
|
155
|
+
response = agent.run(user_input)
|
|
156
|
+
console.print(f"š¤ {response}")
|
|
157
|
+
|
|
158
|
+
except KeyboardInterrupt:
|
|
159
|
+
break
|
|
160
|
+
except Exception as e:
|
|
161
|
+
console.print(f"ā Error: {e}")
|
|
162
|
+
|
|
163
|
+
except Exception as e:
|
|
164
|
+
console.print(f"ā ļø Could not launch demo: {e}")
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
# Note: The init command should be registered in main.py, not here
|
|
168
|
+
# This prevents circular imports
|