glaip-sdk 0.0.3__py3-none-any.whl → 0.0.4__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.
@@ -11,10 +11,12 @@ from pathlib import Path
11
11
  import click
12
12
  import yaml
13
13
  from rich.console import Console
14
- from rich.panel import Panel
15
14
  from rich.table import Table
15
+ from rich.text import Text
16
16
 
17
17
  from glaip_sdk import Client
18
+ from glaip_sdk._version import __version__ as _SDK_VERSION
19
+ from glaip_sdk.branding import AIPBranding
18
20
 
19
21
  console = Console()
20
22
 
@@ -79,7 +81,7 @@ def list_config():
79
81
  table.add_row(key, str(value))
80
82
 
81
83
  console.print(table)
82
- console.print(f"\n📁 Config file: {CONFIG_FILE}")
84
+ console.print(Text(f"\n📁 Config file: {CONFIG_FILE}"))
83
85
 
84
86
 
85
87
  @config_group.command("set")
@@ -102,9 +104,9 @@ def set_config(key, value):
102
104
 
103
105
  if key == "api_key":
104
106
  masked_value = "***" + value[-4:] if len(value) > 4 else "***"
105
- console.print(f"✅ Set {key} = {masked_value}")
107
+ console.print(Text(f"✅ Set {key} = {masked_value}"))
106
108
  else:
107
- console.print(f"✅ Set {key} = {value}")
109
+ console.print(Text(f"✅ Set {key} = {value}"))
108
110
 
109
111
 
110
112
  @config_group.command("get")
@@ -115,7 +117,7 @@ def get_config(key):
115
117
  config = load_config()
116
118
 
117
119
  if key not in config:
118
- console.print(f"[yellow]Configuration key '{key}' not found.[/yellow]")
120
+ console.print(Text(f"[yellow]Configuration key '{key}' not found.[/yellow]"))
119
121
  raise click.ClickException(f"Configuration key not found: {key}")
120
122
 
121
123
  value = config[key]
@@ -136,13 +138,13 @@ def unset_config(key):
136
138
  config = load_config()
137
139
 
138
140
  if key not in config:
139
- console.print(f"[yellow]Configuration key '{key}' not found.[/yellow]")
141
+ console.print(Text(f"[yellow]Configuration key '{key}' not found.[/yellow]"))
140
142
  return
141
143
 
142
144
  del config[key]
143
145
  save_config(config)
144
146
 
145
- console.print(f"✅ Removed {key} from configuration")
147
+ console.print(Text(f"✅ Removed {key} from configuration"))
146
148
 
147
149
 
148
150
  @config_group.command("reset")
@@ -168,13 +170,11 @@ def reset_config(force):
168
170
 
169
171
  def _configure_interactive():
170
172
  """Shared configuration logic for both configure commands."""
171
- console.print(
172
- Panel(
173
- "[bold cyan]AIP Configuration[/bold cyan]\nConfigure your AIP CLI settings.",
174
- title="🔧 Configuration Setup",
175
- border_style="cyan",
176
- )
173
+ # Display AIP welcome banner
174
+ branding = AIPBranding.create_from_sdk(
175
+ sdk_version=_SDK_VERSION, package_name="glaip-sdk"
177
176
  )
177
+ branding.display_welcome_panel(title="🔧 AIP Configuration")
178
178
 
179
179
  # Load existing config
180
180
  config = load_config()
@@ -208,7 +208,7 @@ def _configure_interactive():
208
208
  # Save configuration
209
209
  save_config(config)
210
210
 
211
- console.print(f"\n✅ Configuration saved to: {CONFIG_FILE}")
211
+ console.print(Text(f"\n✅ Configuration saved to: {CONFIG_FILE}"))
212
212
 
213
213
  # Test the new configuration
214
214
  console.print("\n🔌 Testing connection...")
@@ -219,9 +219,9 @@ def _configure_interactive():
219
219
  # Try to list resources to test connection
220
220
  try:
221
221
  agents = client.list_agents()
222
- console.print(f"✅ Connection successful! Found {len(agents)} agents")
222
+ console.print(Text(f"✅ Connection successful! Found {len(agents)} agents"))
223
223
  except Exception as e:
224
- console.print(f"⚠️ Connection established but API call failed: {e}")
224
+ console.print(Text(f"⚠️ Connection established but API call failed: {e}"))
225
225
  console.print(
226
226
  " You may need to check your API permissions or network access"
227
227
  )
@@ -229,7 +229,7 @@ def _configure_interactive():
229
229
  client.close()
230
230
 
231
231
  except Exception as e:
232
- console.print(f"❌ Connection failed: {e}")
232
+ console.print(Text(f"❌ Connection failed: {e}"))
233
233
  console.print(" Please check your API URL and key")
234
234
  console.print(" You can run 'aip status' later to test again")
235
235
 
@@ -11,32 +11,28 @@ from pathlib import Path
11
11
  import click
12
12
  import yaml
13
13
  from rich.console import Console
14
- from rich.panel import Panel
14
+ from rich.text import Text
15
15
 
16
16
  from glaip_sdk import Client
17
+ from glaip_sdk._version import __version__ as _SDK_VERSION
18
+ from glaip_sdk.branding import AIPBranding
17
19
 
18
20
  console = Console()
19
21
 
20
22
 
21
23
  @click.command()
22
- @click.option("--no-scaffold", is_flag=True, help="Skip creating sample agent and tool")
23
- @click.option("--no-demo", is_flag=True, help="Don't launch interactive demo")
24
- def init_command(no_scaffold, no_demo):
24
+ def init_command():
25
25
  """Initialize AIP project configuration."""
26
-
27
- console.print(
28
- Panel(
29
- "[bold cyan]Welcome to AIP![/bold cyan]\nLet's set up your project.",
30
- title="🚀 AIP Initialization",
31
- border_style="cyan",
32
- )
26
+ # Display AIP welcome banner
27
+ branding = AIPBranding.create_from_sdk(
28
+ sdk_version=_SDK_VERSION, package_name="glaip-sdk"
33
29
  )
30
+ branding.display_welcome_panel(title="🚀 AIP Initialization")
34
31
 
35
- # Get configuration with better formatting
36
- console.print("\n[bold]Step 1:[/bold] API Configuration")
32
+ # Get configuration
33
+ console.print("\n[bold]API Configuration[/bold]")
37
34
  console.print("─" * 50)
38
35
 
39
- # Use built-in input for better control
40
36
  console.print(
41
37
  "\n[cyan]AIP API URL[/cyan] (default: https://your-aip-instance.com):"
42
38
  )
@@ -44,134 +40,54 @@ def init_command(no_scaffold, no_demo):
44
40
  if not api_url:
45
41
  api_url = "https://your-aip-instance.com"
46
42
 
47
- console.print() # Add spacing
48
- console.print("[cyan]AIP API Key[/cyan]:")
43
+ console.print("\n[cyan]AIP API Key[/cyan]:")
49
44
  api_key = getpass.getpass("> ")
50
45
 
51
- # Project configuration removed - not needed for AIP CLI
52
-
53
46
  # Create config directory
54
47
  config_dir = Path.home() / ".aip"
55
48
  try:
56
49
  config_dir.mkdir(exist_ok=True)
57
50
  except Exception as e:
58
- console.print(f"⚠️ Warning: Could not create config directory: {e}")
51
+ console.print(Text(f"⚠️ Warning: Could not create config directory: {e}"))
59
52
  return
60
53
 
61
54
  # Save configuration
62
55
  config = {"api_url": api_url, "api_key": api_key}
63
-
64
56
  config_file = config_dir / "config.yaml"
65
57
  try:
66
58
  with open(config_file, "w") as f:
67
59
  yaml.dump(config, f, default_flow_style=False)
68
60
  except Exception as e:
69
- console.print(f"⚠️ Warning: Could not save configuration: {e}")
61
+ console.print(Text(f"⚠️ Warning: Could not save configuration: {e}"))
70
62
  return
71
63
 
72
64
  # Set secure file permissions (0600) - best effort on all platforms
73
65
  try:
74
66
  os.chmod(config_file, 0o600)
75
67
  except Exception:
76
- # Best effort - may fail on Windows or other non-POSIX systems
77
- pass
78
-
79
- console.print(f"\n✅ Configuration saved to: {config_file}")
80
-
81
- # Create sample agent and tool if requested
82
- if not no_scaffold:
83
- console.print("\n[bold]Step 2:[/bold] Sample Resources")
84
- console.print("─" * 50)
85
-
86
- console.print("\n[cyan]Create sample agent & tool?[/cyan] (Y/n):")
87
- create_sample_resources = input("> ").strip().lower()
88
- if create_sample_resources in ["", "y", "yes"]:
89
- try:
90
- # Set environment variables
91
- os.environ["AIP_API_URL"] = api_url
92
- os.environ["AIP_API_KEY"] = api_key
93
-
94
- client = Client()
95
-
96
- # Create sample agent
97
- agent = client.create_agent(
98
- name="hello-world",
99
- instruction="You are a helpful AI assistant that says hello",
100
- )
101
- console.print(f"✅ Created sample agent: {agent.name} (id: {agent.id})")
102
-
103
- # Create sample tool
104
- tool_content = '''def hello_tool(name="World"):
105
- """A simple hello tool."""
106
- return f"Hello, {name}!"
107
- '''
108
- with open("greeting_tool.py", "w") as f:
109
- f.write(tool_content)
110
-
111
- tool = client.create_tool("greeting_tool.py", framework="langchain")
112
- console.print(f"✅ Created sample tool: {tool.name} (id: {tool.id})")
113
-
114
- except Exception as e:
115
- console.print(f"⚠️ Warning: Could not create sample resources: {e}")
116
-
117
- # Launch interactive demo if requested
118
- if not no_demo:
119
- console.print("\n[bold]Step 3:[/bold] Interactive Demo")
120
- console.print("─" * 50)
121
-
122
- console.print("\n[cyan]Start an interactive demo now?[/cyan] (Y/n):")
123
- launch_demo = input("> ").strip().lower()
124
- if launch_demo in ["", "y", "yes"]:
125
- launch_interactive_demo()
126
-
127
- console.print("\n🎉 [bold green]AIP initialization complete![/bold green]")
128
- console.print(f"📁 Configuration: {config_file}")
129
- console.print("💡 Next steps:")
130
- console.print(" • Run 'aip agents list' to see your agents")
131
- console.print(" • Run 'aip tools list' to see your tools")
132
- console.print(" • Run 'aip status' to check connection")
68
+ pass # Ignore permission errors
133
69
 
70
+ console.print(Text(f"\n✅ Configuration saved to: {config_file}"))
134
71
 
135
- def launch_interactive_demo():
136
- """Launch interactive demo with sample agent."""
72
+ # Test the new configuration
73
+ console.print("\n🔌 Testing connection...")
137
74
  try:
138
- console.print(
139
- Panel(
140
- "[bold green]Interactive Demo[/bold green]\nType to talk to hello-world. Ctrl+C to exit.",
141
- title="🎮 Demo Mode",
142
- border_style="green",
143
- )
144
- )
75
+ # Set environment variables
76
+ os.environ["AIP_API_URL"] = api_url
77
+ os.environ["AIP_API_KEY"] = api_key
145
78
 
146
79
  client = Client()
147
- agents = client.find_agents(name="hello-world")
148
- if not agents:
149
- console.print("❌ Sample agent not found")
150
- return
151
-
152
- agent = agents[0] # Use the first (and should be only) agent
153
-
154
- while True:
155
- try:
156
- console.print("\n> ", end="")
157
- user_input = input().strip()
158
- if user_input.lower() in ["exit", "quit", "bye"]:
159
- break
160
-
161
- if not user_input: # Skip empty inputs
162
- continue
163
-
164
- response = agent.run(user_input)
165
- console.print(f"🤖 {response}")
166
-
167
- except KeyboardInterrupt:
168
- break
169
- except Exception as e:
170
- console.print(f"❌ Error: {e}")
171
-
80
+ agents = client.list_agents()
81
+ console.print(Text(f"✅ Connection successful! Found {len(agents)} agents"))
172
82
  except Exception as e:
173
- console.print(f"⚠️ Could not launch demo: {e}")
174
-
83
+ console.print(Text(f"⚠️ Connection established but API call failed: {e}"))
84
+ console.print(
85
+ Text(" You may need to check your API permissions or network access")
86
+ )
175
87
 
176
- # Note: The init command should be registered in main.py, not here
177
- # This prevents circular imports
88
+ console.print("\n🎉 [bold green]AIP initialization complete![/bold green]")
89
+ console.print(f"📁 Configuration: {config_file}")
90
+ console.print("💡 Next steps:")
91
+ console.print(" • Run 'aip agents list' to see your agents")
92
+ console.print(" • Run 'aip tools list' to see your tools")
93
+ console.print(" • Run 'aip status' to check connection")
@@ -10,6 +10,7 @@ import click
10
10
  from rich.console import Console
11
11
  from rich.panel import Panel
12
12
  from rich.table import Table
13
+ from rich.text import Text
13
14
 
14
15
  from ..utils import (
15
16
  coerce_to_row,
@@ -125,7 +126,7 @@ def create(ctx, name, transport, description, config):
125
126
  if view == "json":
126
127
  click.echo(json.dumps({"error": str(e)}, indent=2))
127
128
  else:
128
- console.print(f"[red]Error creating MCP: {e}[/red]")
129
+ console.print(Text(f"[red]Error creating MCP: {e}[/red]"))
129
130
  raise click.ClickException(str(e))
130
131
 
131
132
 
@@ -251,7 +252,7 @@ def tools_from_config(ctx, config_file):
251
252
  )
252
253
  console.print(table)
253
254
  else:
254
- console.print("[yellow]No tools found in MCP config[/yellow]")
255
+ console.print(Text("[yellow]No tools found in MCP config[/yellow]"))
255
256
 
256
257
  except Exception as e:
257
258
  raise click.ClickException(str(e))
@@ -278,7 +279,9 @@ def test_connection(ctx, config_file):
278
279
  view = (ctx.obj or {}).get("view", "rich")
279
280
  if view != "json":
280
281
  console.print(
281
- f"[yellow]Testing MCP connection with config from {config_file}...[/yellow]"
282
+ Text(
283
+ f"[yellow]Testing MCP connection with config from {config_file}...[/yellow]"
284
+ )
282
285
  )
283
286
 
284
287
  # Test connection using config
@@ -338,7 +341,7 @@ def update(ctx, mcp_ref, name, description, config):
338
341
  click.echo(json.dumps(updated_mcp.model_dump(), indent=2))
339
342
  else:
340
343
  console.print(
341
- f"[green]✅ MCP '{updated_mcp.name}' updated successfully[/green]"
344
+ Text(f"[green]✅ MCP '{updated_mcp.name}' updated successfully[/green]")
342
345
  )
343
346
 
344
347
  except Exception as e:
@@ -346,7 +349,7 @@ def update(ctx, mcp_ref, name, description, config):
346
349
  if view == "json":
347
350
  click.echo(json.dumps({"error": str(e)}, indent=2))
348
351
  else:
349
- console.print(f"[red]Error updating MCP: {e}[/red]")
352
+ console.print(Text(f"[red]Error updating MCP: {e}[/red]"))
350
353
  raise click.ClickException(str(e))
351
354
 
352
355
 
@@ -369,7 +372,7 @@ def delete(ctx, mcp_ref, yes):
369
372
  ):
370
373
  view = (ctx.obj or {}).get("view", "rich")
371
374
  if view != "json":
372
- console.print("Deletion cancelled.")
375
+ console.print(Text("Deletion cancelled."))
373
376
  return
374
377
 
375
378
  client.mcps.delete_mcp(mcp.id)
@@ -382,12 +385,14 @@ def delete(ctx, mcp_ref, yes):
382
385
  )
383
386
  )
384
387
  else:
385
- console.print(f"[green]✅ MCP '{mcp.name}' deleted successfully[/green]")
388
+ console.print(
389
+ Text(f"[green]✅ MCP '{mcp.name}' deleted successfully[/green]")
390
+ )
386
391
 
387
392
  except Exception as e:
388
393
  view = (ctx.obj or {}).get("view", "rich")
389
394
  if view == "json":
390
395
  click.echo(json.dumps({"error": str(e)}, indent=2))
391
396
  else:
392
- console.print(f"[red]Error deleting MCP: {e}[/red]")
397
+ console.print(Text(f"[red]Error deleting MCP: {e}[/red]"))
393
398
  raise click.ClickException(str(e))
@@ -10,6 +10,7 @@ import re
10
10
  import click
11
11
  from rich.console import Console
12
12
  from rich.panel import Panel
13
+ from rich.text import Text
13
14
 
14
15
  from ..utils import (
15
16
  coerce_to_row,
@@ -209,7 +210,7 @@ def create(ctx, file_arg, file, name, description, tags):
209
210
  if ctx.obj.get("view") == "json":
210
211
  click.echo(json.dumps({"error": str(e)}, indent=2))
211
212
  else:
212
- console.print(f"[red]Error creating tool: {e}[/red]")
213
+ console.print(Text(f"[red]Error creating tool: {e}[/red]"))
213
214
  raise click.ClickException(str(e))
214
215
 
215
216
 
@@ -276,15 +277,15 @@ def update(ctx, tool_id, file, description, tags):
276
277
  # Update code
277
278
  updated_tool = tool.update(file_path=file)
278
279
  if ctx.obj.get("view") != "json":
279
- console.print(f"[green]✓[/green] Tool code updated from {file}")
280
+ console.print(Text(f"[green]✓[/green] Tool code updated from {file}"))
280
281
  elif update_data:
281
282
  # Update metadata
282
283
  updated_tool = tool.update(**update_data)
283
284
  if ctx.obj.get("view") != "json":
284
- console.print("[green]✓[/green] Tool metadata updated")
285
+ console.print(Text("[green]✓[/green] Tool metadata updated"))
285
286
  else:
286
287
  if ctx.obj.get("view") != "json":
287
- console.print("[yellow]No updates specified[/yellow]")
288
+ console.print(Text("[yellow]No updates specified[/yellow]"))
288
289
  return
289
290
 
290
291
  if ctx.obj.get("view") == "json":
@@ -298,7 +299,7 @@ def update(ctx, tool_id, file, description, tags):
298
299
  if ctx.obj.get("view") == "json":
299
300
  click.echo(json.dumps({"error": str(e)}, indent=2))
300
301
  else:
301
- console.print(f"[red]Error updating tool: {e}[/red]")
302
+ console.print(Text(f"[red]Error updating tool: {e}[/red]"))
302
303
  raise click.ClickException(str(e))
303
304
 
304
305
 
@@ -323,7 +324,7 @@ def delete(ctx, tool_id, yes):
323
324
  f"Are you sure you want to delete tool '{tool.name}'?"
324
325
  ):
325
326
  if ctx.obj.get("view") != "json":
326
- console.print("Deletion cancelled.")
327
+ console.print(Text("Deletion cancelled."))
327
328
  return
328
329
 
329
330
  tool.delete()
@@ -336,13 +337,15 @@ def delete(ctx, tool_id, yes):
336
337
  )
337
338
  )
338
339
  else:
339
- console.print(f"[green]✅ Tool '{tool.name}' deleted successfully[/green]")
340
+ console.print(
341
+ Text(f"[green]✅ Tool '{tool.name}' deleted successfully[/green]")
342
+ )
340
343
 
341
344
  except Exception as e:
342
345
  if ctx.obj.get("view") == "json":
343
346
  click.echo(json.dumps({"error": str(e)}, indent=2))
344
347
  else:
345
- console.print(f"[red]Error deleting tool: {e}[/red]")
348
+ console.print(Text(f"[red]Error deleting tool: {e}[/red]"))
346
349
  raise click.ClickException(str(e))
347
350
 
348
351
 
@@ -441,5 +444,5 @@ def upload_update(ctx, tool_id, file, name, description, tags):
441
444
  if ctx.obj.get("view") == "json":
442
445
  click.echo(json.dumps({"error": str(e)}, indent=2))
443
446
  else:
444
- console.print(f"[red]Error updating tool: {e}[/red]")
447
+ console.print(Text(f"[red]Error updating tool: {e}[/red]"))
445
448
  raise click.ClickException(str(e))
glaip_sdk/cli/main.py CHANGED
@@ -15,6 +15,7 @@ from rich.table import Table
15
15
 
16
16
  from glaip_sdk import Client
17
17
  from glaip_sdk._version import __version__ as _SDK_VERSION
18
+ from glaip_sdk.branding import AIPBranding
18
19
  from glaip_sdk.cli.commands.agents import agents_group
19
20
  from glaip_sdk.cli.commands.configure import (
20
21
  config_group,
@@ -49,11 +50,12 @@ def main(ctx, api_url, api_key, timeout, view, no_tty):
49
50
  agents, tools, MCPs, and more.
50
51
 
51
52
  Examples:
53
+ aip version # Show detailed version info
52
54
  aip configure # Configure credentials
55
+ aip init # Initialize configuration
53
56
  aip agents list # List all agents
54
57
  aip tools create my_tool.py # Create a new tool
55
- aip agents run my-agent "Hello" # Run an agent
56
- aip init # Initialize configuration
58
+ aip agents run my-agent "Hello world" # Run an agent
57
59
  """
58
60
 
59
61
  # Store configuration in context
@@ -89,6 +91,12 @@ def status(ctx):
89
91
  try:
90
92
  console = Console()
91
93
 
94
+ # Display AIP status banner
95
+ branding = AIPBranding.create_from_sdk(
96
+ sdk_version=_SDK_VERSION, package_name="glaip-sdk"
97
+ )
98
+ branding.display_status_banner("ready")
99
+
92
100
  # Load config from file and merge with context
93
101
  file_config = load_config()
94
102
  context_config = ctx.obj or {}
@@ -195,7 +203,10 @@ def status(ctx):
195
203
  @main.command()
196
204
  def version():
197
205
  """Show version information."""
198
- click.echo(f"aip version {_SDK_VERSION}")
206
+ branding = AIPBranding.create_from_sdk(
207
+ sdk_version=_SDK_VERSION, package_name="glaip-sdk"
208
+ )
209
+ branding.display_version_panel()
199
210
 
200
211
 
201
212
  @main.command()