glaip-sdk 0.0.3__py3-none-any.whl → 0.0.5__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 +5 -5
- glaip_sdk/branding.py +146 -0
- glaip_sdk/cli/__init__.py +1 -1
- glaip_sdk/cli/agent_config.py +82 -0
- glaip_sdk/cli/commands/__init__.py +3 -3
- glaip_sdk/cli/commands/agents.py +786 -271
- glaip_sdk/cli/commands/configure.py +19 -19
- glaip_sdk/cli/commands/mcps.py +151 -141
- glaip_sdk/cli/commands/models.py +1 -1
- glaip_sdk/cli/commands/tools.py +252 -178
- glaip_sdk/cli/display.py +244 -0
- glaip_sdk/cli/io.py +106 -0
- glaip_sdk/cli/main.py +27 -20
- glaip_sdk/cli/resolution.py +59 -0
- glaip_sdk/cli/utils.py +372 -213
- glaip_sdk/cli/validators.py +235 -0
- glaip_sdk/client/__init__.py +3 -224
- glaip_sdk/client/agents.py +632 -171
- glaip_sdk/client/base.py +66 -4
- glaip_sdk/client/main.py +226 -0
- glaip_sdk/client/mcps.py +143 -18
- glaip_sdk/client/tools.py +327 -104
- glaip_sdk/config/constants.py +10 -1
- glaip_sdk/models.py +43 -3
- glaip_sdk/rich_components.py +29 -0
- glaip_sdk/utils/__init__.py +18 -171
- glaip_sdk/utils/agent_config.py +181 -0
- glaip_sdk/utils/client_utils.py +159 -79
- glaip_sdk/utils/display.py +100 -0
- glaip_sdk/utils/general.py +94 -0
- glaip_sdk/utils/import_export.py +140 -0
- glaip_sdk/utils/rendering/formatting.py +6 -1
- glaip_sdk/utils/rendering/renderer/__init__.py +67 -8
- glaip_sdk/utils/rendering/renderer/base.py +340 -247
- glaip_sdk/utils/rendering/renderer/debug.py +3 -2
- glaip_sdk/utils/rendering/renderer/panels.py +11 -10
- glaip_sdk/utils/rendering/steps.py +1 -1
- glaip_sdk/utils/resource_refs.py +192 -0
- glaip_sdk/utils/rich_utils.py +29 -0
- glaip_sdk/utils/serialization.py +285 -0
- glaip_sdk/utils/validation.py +273 -0
- {glaip_sdk-0.0.3.dist-info → glaip_sdk-0.0.5.dist-info}/METADATA +6 -5
- glaip_sdk-0.0.5.dist-info/RECORD +55 -0
- glaip_sdk/cli/commands/init.py +0 -177
- glaip_sdk-0.0.3.dist-info/RECORD +0 -40
- {glaip_sdk-0.0.3.dist-info → glaip_sdk-0.0.5.dist-info}/WHEEL +0 -0
- {glaip_sdk-0.0.3.dist-info → glaip_sdk-0.0.5.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"""Rich display utilities for enhanced output.
|
|
2
|
+
|
|
3
|
+
Authors:
|
|
4
|
+
Raymond Christopher (raymond.christopher@gdplabs.id)
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from glaip_sdk.utils.rich_utils import RICH_AVAILABLE
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def print_agent_output(output: str, title: str = "Agent Output") -> None:
|
|
11
|
+
"""Print agent output with rich formatting.
|
|
12
|
+
|
|
13
|
+
Args:
|
|
14
|
+
output: The agent's response text
|
|
15
|
+
title: Title for the output panel
|
|
16
|
+
"""
|
|
17
|
+
if RICH_AVAILABLE:
|
|
18
|
+
# Lazy import Rich components
|
|
19
|
+
from rich.console import Console
|
|
20
|
+
from rich.text import Text
|
|
21
|
+
|
|
22
|
+
from glaip_sdk.rich_components import AIPPanel
|
|
23
|
+
|
|
24
|
+
console = Console()
|
|
25
|
+
panel = AIPPanel(
|
|
26
|
+
Text(output, style="green"),
|
|
27
|
+
title=title,
|
|
28
|
+
border_style="green",
|
|
29
|
+
)
|
|
30
|
+
console.print(panel)
|
|
31
|
+
else:
|
|
32
|
+
print(f"\n=== {title} ===")
|
|
33
|
+
print(output)
|
|
34
|
+
print("=" * (len(title) + 8))
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def print_agent_created(agent, title: str = "🤖 Agent Created") -> None:
|
|
38
|
+
"""Print agent creation success with rich formatting.
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
agent: The created agent object
|
|
42
|
+
title: Title for the output panel
|
|
43
|
+
"""
|
|
44
|
+
if RICH_AVAILABLE:
|
|
45
|
+
# Lazy import Rich components
|
|
46
|
+
from rich.console import Console
|
|
47
|
+
|
|
48
|
+
from glaip_sdk.rich_components import AIPPanel
|
|
49
|
+
|
|
50
|
+
console = Console()
|
|
51
|
+
panel = AIPPanel(
|
|
52
|
+
f"[green]✅ Agent '{agent.name}' created successfully![/green]\n\n"
|
|
53
|
+
f"ID: {agent.id}\n"
|
|
54
|
+
f"Model: {getattr(agent, 'model', 'N/A')}\n"
|
|
55
|
+
f"Type: {getattr(agent, 'type', 'config')}\n"
|
|
56
|
+
f"Framework: {getattr(agent, 'framework', 'langchain')}\n"
|
|
57
|
+
f"Version: {getattr(agent, 'version', '1.0')}",
|
|
58
|
+
title=title,
|
|
59
|
+
border_style="green",
|
|
60
|
+
)
|
|
61
|
+
console.print(panel)
|
|
62
|
+
else:
|
|
63
|
+
print(f"✅ Agent '{agent.name}' created successfully!")
|
|
64
|
+
print(f"ID: {agent.id}")
|
|
65
|
+
print(f"Model: {getattr(agent, 'model', 'N/A')}")
|
|
66
|
+
print(f"Type: {getattr(agent, 'type', 'config')}")
|
|
67
|
+
print(f"Framework: {getattr(agent, 'framework', 'langchain')}")
|
|
68
|
+
print(f"Version: {getattr(agent, 'version', '1.0')}")
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def print_agent_updated(agent) -> None:
|
|
72
|
+
"""Print agent update success with rich formatting.
|
|
73
|
+
|
|
74
|
+
Args:
|
|
75
|
+
agent: The updated agent object
|
|
76
|
+
"""
|
|
77
|
+
if RICH_AVAILABLE:
|
|
78
|
+
# Lazy import Rich components
|
|
79
|
+
from rich.console import Console
|
|
80
|
+
|
|
81
|
+
console = Console()
|
|
82
|
+
console.print(f"[green]✅ Agent '{agent.name}' updated successfully[/green]")
|
|
83
|
+
else:
|
|
84
|
+
print(f"✅ Agent '{agent.name}' updated successfully")
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def print_agent_deleted(agent_id: str) -> None:
|
|
88
|
+
"""Print agent deletion success with rich formatting.
|
|
89
|
+
|
|
90
|
+
Args:
|
|
91
|
+
agent_id: The deleted agent's ID
|
|
92
|
+
"""
|
|
93
|
+
if RICH_AVAILABLE:
|
|
94
|
+
# Lazy import Rich components
|
|
95
|
+
from rich.console import Console
|
|
96
|
+
|
|
97
|
+
console = Console()
|
|
98
|
+
console.print(f"[green]✅ Agent deleted successfully (ID: {agent_id})[/green]")
|
|
99
|
+
else:
|
|
100
|
+
print(f"✅ Agent deleted successfully (ID: {agent_id})")
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"""General utility functions for AIP SDK.
|
|
2
|
+
|
|
3
|
+
Authors:
|
|
4
|
+
Raymond Christopher (raymond.christopher@gdplabs.id)
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import re
|
|
8
|
+
from datetime import datetime
|
|
9
|
+
from uuid import UUID
|
|
10
|
+
|
|
11
|
+
import click
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def is_uuid(value: str) -> bool:
|
|
15
|
+
"""Check if a string is a valid UUID.
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
value: String to check
|
|
19
|
+
|
|
20
|
+
Returns:
|
|
21
|
+
True if value is a valid UUID, False otherwise
|
|
22
|
+
"""
|
|
23
|
+
try:
|
|
24
|
+
UUID(value)
|
|
25
|
+
return True
|
|
26
|
+
except (ValueError, TypeError):
|
|
27
|
+
return False
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def sanitize_name(name: str) -> str:
|
|
31
|
+
"""Sanitize a name for resource creation.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
name: Raw name input
|
|
35
|
+
|
|
36
|
+
Returns:
|
|
37
|
+
Sanitized name suitable for resource creation
|
|
38
|
+
"""
|
|
39
|
+
# Remove special characters and normalize
|
|
40
|
+
sanitized = re.sub(r"[^a-zA-Z0-9\-_]", "-", name.strip())
|
|
41
|
+
sanitized = re.sub(r"-+", "-", sanitized) # Collapse multiple dashes
|
|
42
|
+
return sanitized.lower().strip("-")
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def format_file_size(size_bytes: int) -> str:
|
|
46
|
+
"""Format file size in human readable format.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
size_bytes: Size in bytes
|
|
50
|
+
|
|
51
|
+
Returns:
|
|
52
|
+
Human readable size string (e.g., "1.5 MB")
|
|
53
|
+
"""
|
|
54
|
+
for unit in ["B", "KB", "MB", "GB"]:
|
|
55
|
+
if size_bytes < 1024.0:
|
|
56
|
+
return f"{size_bytes:.1f} {unit}"
|
|
57
|
+
size_bytes /= 1024.0
|
|
58
|
+
return f"{size_bytes:.1f} TB"
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def format_datetime(dt):
|
|
62
|
+
"""Format datetime object to readable string.
|
|
63
|
+
|
|
64
|
+
Args:
|
|
65
|
+
dt: Datetime object or string to format
|
|
66
|
+
|
|
67
|
+
Returns:
|
|
68
|
+
Formatted datetime string or "N/A" if None
|
|
69
|
+
"""
|
|
70
|
+
if isinstance(dt, datetime):
|
|
71
|
+
return dt.strftime("%Y-%m-%d %H:%M:%S UTC")
|
|
72
|
+
elif dt is None:
|
|
73
|
+
return "N/A"
|
|
74
|
+
return str(dt)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def progress_bar(iterable, description: str = "Processing"):
|
|
78
|
+
"""Simple progress bar using click.
|
|
79
|
+
|
|
80
|
+
Args:
|
|
81
|
+
iterable: Iterable to process
|
|
82
|
+
description: Progress description
|
|
83
|
+
|
|
84
|
+
Yields:
|
|
85
|
+
Items from iterable with progress display
|
|
86
|
+
"""
|
|
87
|
+
try:
|
|
88
|
+
with click.progressbar(iterable, label=description) as bar:
|
|
89
|
+
for item in bar:
|
|
90
|
+
yield item
|
|
91
|
+
except ImportError:
|
|
92
|
+
# Fallback if click not available
|
|
93
|
+
for item in iterable:
|
|
94
|
+
yield item
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"""Import/export utilities for schema transforms and data merging.
|
|
2
|
+
|
|
3
|
+
This module provides functions for converting between export and import formats,
|
|
4
|
+
merging imported data with CLI arguments, and handling relationship flattening.
|
|
5
|
+
|
|
6
|
+
Authors:
|
|
7
|
+
Raymond Christopher (raymond.christopher@gdplabs.id)
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def extract_ids_from_export(items: list[Any]) -> list[str]:
|
|
14
|
+
"""Extract IDs from export format (list of dicts with id/name fields).
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
items: List of items (dicts with id/name or strings)
|
|
18
|
+
|
|
19
|
+
Returns:
|
|
20
|
+
List of extracted IDs (only items with actual IDs)
|
|
21
|
+
|
|
22
|
+
Examples:
|
|
23
|
+
extract_ids_from_export([{"id": "123", "name": "tool"}]) -> ["123"]
|
|
24
|
+
extract_ids_from_export(["123", "456"]) -> ["123", "456"]
|
|
25
|
+
extract_ids_from_export([{"name": "tool"}, "123"]) -> ["123"] # Skip items without ID
|
|
26
|
+
"""
|
|
27
|
+
if not items:
|
|
28
|
+
return []
|
|
29
|
+
|
|
30
|
+
ids = []
|
|
31
|
+
for item in items:
|
|
32
|
+
if isinstance(item, str):
|
|
33
|
+
ids.append(item)
|
|
34
|
+
elif hasattr(item, "id"):
|
|
35
|
+
ids.append(str(item.id))
|
|
36
|
+
elif isinstance(item, dict) and "id" in item:
|
|
37
|
+
ids.append(str(item["id"]))
|
|
38
|
+
# Skip items without ID (don't convert to string)
|
|
39
|
+
|
|
40
|
+
return ids
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def convert_export_to_import_format(data: dict[str, Any]) -> dict[str, Any]:
|
|
44
|
+
"""Convert export format to import-compatible format (extract IDs from objects).
|
|
45
|
+
|
|
46
|
+
Args:
|
|
47
|
+
data: Export format data with full objects
|
|
48
|
+
|
|
49
|
+
Returns:
|
|
50
|
+
Import format data with extracted IDs
|
|
51
|
+
|
|
52
|
+
Notes:
|
|
53
|
+
- Converts tools/agents from dict objects to ID lists
|
|
54
|
+
- Preserves all other data unchanged
|
|
55
|
+
"""
|
|
56
|
+
import_data = data.copy()
|
|
57
|
+
|
|
58
|
+
# Convert tools from dicts to IDs
|
|
59
|
+
if "tools" in import_data and isinstance(import_data["tools"], list):
|
|
60
|
+
import_data["tools"] = extract_ids_from_export(import_data["tools"])
|
|
61
|
+
|
|
62
|
+
# Convert agents from dicts to IDs
|
|
63
|
+
if "agents" in import_data and isinstance(import_data["agents"], list):
|
|
64
|
+
import_data["agents"] = extract_ids_from_export(import_data["agents"])
|
|
65
|
+
|
|
66
|
+
return import_data
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def merge_import_with_cli_args(
|
|
70
|
+
import_data: dict[str, Any],
|
|
71
|
+
cli_args: dict[str, Any],
|
|
72
|
+
array_fields: list[str] = None,
|
|
73
|
+
) -> dict[str, Any]:
|
|
74
|
+
"""Merge imported data with CLI arguments, preferring CLI args.
|
|
75
|
+
|
|
76
|
+
Args:
|
|
77
|
+
import_data: Data loaded from import file
|
|
78
|
+
cli_args: Arguments passed via CLI
|
|
79
|
+
array_fields: Fields that should be combined (merged) rather than replaced
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
Merged data dictionary
|
|
83
|
+
|
|
84
|
+
Notes:
|
|
85
|
+
- CLI arguments take precedence over imported data
|
|
86
|
+
- Array fields (tools, agents) are combined rather than replaced
|
|
87
|
+
- Empty arrays/lists are treated as None (no override)
|
|
88
|
+
"""
|
|
89
|
+
if array_fields is None:
|
|
90
|
+
array_fields = ["tools", "agents"]
|
|
91
|
+
|
|
92
|
+
merged = {}
|
|
93
|
+
|
|
94
|
+
for key, cli_value in cli_args.items():
|
|
95
|
+
if cli_value is not None and (
|
|
96
|
+
not isinstance(cli_value, list | tuple) or len(cli_value) > 0
|
|
97
|
+
):
|
|
98
|
+
# CLI value takes precedence (for non-empty values)
|
|
99
|
+
if key in array_fields and key in import_data:
|
|
100
|
+
# For array fields, combine CLI and imported values
|
|
101
|
+
import_value = import_data[key]
|
|
102
|
+
if isinstance(import_value, list):
|
|
103
|
+
merged[key] = list(cli_value) + import_value
|
|
104
|
+
else:
|
|
105
|
+
merged[key] = cli_value
|
|
106
|
+
else:
|
|
107
|
+
merged[key] = cli_value
|
|
108
|
+
elif key in import_data:
|
|
109
|
+
# Use imported value if no CLI value
|
|
110
|
+
merged[key] = import_data[key]
|
|
111
|
+
|
|
112
|
+
# Add any import-only fields
|
|
113
|
+
for key, import_value in import_data.items():
|
|
114
|
+
if key not in merged:
|
|
115
|
+
merged[key] = import_value
|
|
116
|
+
|
|
117
|
+
return merged
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def flatten_relationships_for_import(
|
|
121
|
+
data: dict[str, Any], fields: tuple[str, ...] = ("tools", "agents")
|
|
122
|
+
) -> dict[str, Any]:
|
|
123
|
+
"""Flatten relationship fields for import format.
|
|
124
|
+
|
|
125
|
+
This is an alias for convert_export_to_import_format with configurable fields.
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
data: Export format data with full objects
|
|
129
|
+
fields: Tuple of field names to flatten to IDs
|
|
130
|
+
|
|
131
|
+
Returns:
|
|
132
|
+
Import format data with specified fields flattened to IDs
|
|
133
|
+
"""
|
|
134
|
+
import_data = data.copy()
|
|
135
|
+
|
|
136
|
+
for field in fields:
|
|
137
|
+
if field in import_data and isinstance(import_data[field], list):
|
|
138
|
+
import_data[field] = extract_ids_from_export(import_data[field])
|
|
139
|
+
|
|
140
|
+
return import_data
|
|
@@ -108,7 +108,7 @@ def pretty_args(args: dict | None, max_len: int = DEFAULT_ARGS_MAX_LEN) -> str:
|
|
|
108
108
|
try:
|
|
109
109
|
import json
|
|
110
110
|
|
|
111
|
-
args_str = json.dumps(masked_args, ensure_ascii=False)
|
|
111
|
+
args_str = json.dumps(masked_args, ensure_ascii=False, separators=(",", ":"))
|
|
112
112
|
return _truncate_string(args_str, max_len)
|
|
113
113
|
except (TypeError, ValueError, Exception):
|
|
114
114
|
# Fallback to string representation if JSON serialization fails
|
|
@@ -124,6 +124,11 @@ def pretty_out(output: any, max_len: int = DEFAULT_ARGS_MAX_LEN) -> str:
|
|
|
124
124
|
if isinstance(output, str):
|
|
125
125
|
# Mask secrets in string output
|
|
126
126
|
masked_output = mask_secrets_in_string(output)
|
|
127
|
+
|
|
128
|
+
# Remove LaTeX commands (common math expressions)
|
|
129
|
+
masked_output = re.sub(r"\\[a-zA-Z]+\{[^}]*\}", "", masked_output)
|
|
130
|
+
masked_output = re.sub(r"\\[a-zA-Z]+", "", masked_output)
|
|
131
|
+
|
|
127
132
|
# Strip leading/trailing whitespace but preserve internal spacing
|
|
128
133
|
masked_output = masked_output.strip()
|
|
129
134
|
# Replace newlines with spaces to preserve formatting
|
|
@@ -5,21 +5,78 @@ with clean separation of concerns between configuration, console handling,
|
|
|
5
5
|
debug output, panel rendering, progress tracking, and event routing.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
from .console import
|
|
11
|
-
|
|
12
|
-
from .
|
|
8
|
+
import io
|
|
9
|
+
|
|
10
|
+
from rich.console import Console
|
|
11
|
+
|
|
12
|
+
from glaip_sdk.rich_components import AIPPanel
|
|
13
|
+
from glaip_sdk.utils.rendering.renderer.base import RichStreamRenderer
|
|
14
|
+
from glaip_sdk.utils.rendering.renderer.config import RendererConfig
|
|
15
|
+
from glaip_sdk.utils.rendering.renderer.console import CapturingConsole
|
|
16
|
+
from glaip_sdk.utils.rendering.renderer.debug import render_debug_event
|
|
17
|
+
from glaip_sdk.utils.rendering.renderer.panels import (
|
|
13
18
|
create_context_panel,
|
|
14
19
|
create_final_panel,
|
|
15
20
|
create_main_panel,
|
|
16
21
|
create_tool_panel,
|
|
17
22
|
)
|
|
18
|
-
from .progress import (
|
|
23
|
+
from glaip_sdk.utils.rendering.renderer.progress import (
|
|
19
24
|
format_tool_title,
|
|
20
25
|
is_delegation_tool,
|
|
21
26
|
)
|
|
22
|
-
from .stream import StreamProcessor
|
|
27
|
+
from glaip_sdk.utils.rendering.renderer.stream import StreamProcessor
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def make_silent_renderer() -> RichStreamRenderer:
|
|
31
|
+
"""Create a renderer that suppresses all terminal output.
|
|
32
|
+
|
|
33
|
+
Uses an in-memory console and disables live updates/panels.
|
|
34
|
+
"""
|
|
35
|
+
cfg = RendererConfig(
|
|
36
|
+
live=False,
|
|
37
|
+
persist_live=False,
|
|
38
|
+
show_delegate_tool_panels=False,
|
|
39
|
+
render_thinking=False,
|
|
40
|
+
)
|
|
41
|
+
return RichStreamRenderer(
|
|
42
|
+
console=Console(file=io.StringIO(), force_terminal=False), cfg=cfg
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def make_minimal_renderer() -> RichStreamRenderer:
|
|
47
|
+
"""Create a minimal renderer.
|
|
48
|
+
|
|
49
|
+
Prints a compact header and the user request panel, but no live updates or tool panels.
|
|
50
|
+
"""
|
|
51
|
+
cfg = RendererConfig(
|
|
52
|
+
live=False,
|
|
53
|
+
persist_live=False,
|
|
54
|
+
show_delegate_tool_panels=False,
|
|
55
|
+
render_thinking=False,
|
|
56
|
+
)
|
|
57
|
+
return RichStreamRenderer(console=Console(), cfg=cfg)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def print_panel(
|
|
61
|
+
content: str,
|
|
62
|
+
*,
|
|
63
|
+
title: str | None = None,
|
|
64
|
+
border_style: str = "blue",
|
|
65
|
+
padding: tuple[int, int] = (1, 2),
|
|
66
|
+
console: Console | None = None,
|
|
67
|
+
) -> None:
|
|
68
|
+
"""Print boxed content using Rich without exposing Console/Panel at call site.
|
|
69
|
+
|
|
70
|
+
Args:
|
|
71
|
+
content: The text to display inside the panel.
|
|
72
|
+
title: Optional title for the panel.
|
|
73
|
+
border_style: Rich style string for the border color.
|
|
74
|
+
padding: (vertical, horizontal) padding inside the panel.
|
|
75
|
+
console: Optional Rich Console to print to; created if not provided.
|
|
76
|
+
"""
|
|
77
|
+
c = console or Console()
|
|
78
|
+
c.print(AIPPanel(content, title=title, border_style=border_style, padding=padding))
|
|
79
|
+
|
|
23
80
|
|
|
24
81
|
__all__ = [
|
|
25
82
|
# Main classes
|
|
@@ -27,7 +84,9 @@ __all__ = [
|
|
|
27
84
|
"RendererConfig",
|
|
28
85
|
"CapturingConsole",
|
|
29
86
|
"StreamProcessor",
|
|
30
|
-
|
|
87
|
+
"make_silent_renderer",
|
|
88
|
+
"make_minimal_renderer",
|
|
89
|
+
"print_panel",
|
|
31
90
|
"render_debug_event",
|
|
32
91
|
"create_main_panel",
|
|
33
92
|
"create_tool_panel",
|