glaip-sdk 0.0.8__py3-none-any.whl → 0.0.9__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/cli/commands/mcps.py +61 -15
- glaip_sdk/cli/commands/models.py +12 -2
- glaip_sdk/cli/commands/tools.py +69 -13
- glaip_sdk/cli/main.py +10 -7
- glaip_sdk/cli/utils.py +61 -17
- glaip_sdk/utils/rendering/renderer/base.py +1 -1
- glaip_sdk/utils/rendering/renderer/panels.py +21 -7
- {glaip_sdk-0.0.8.dist-info → glaip_sdk-0.0.9.dist-info}/METADATA +2 -2
- {glaip_sdk-0.0.8.dist-info → glaip_sdk-0.0.9.dist-info}/RECORD +11 -11
- {glaip_sdk-0.0.8.dist-info → glaip_sdk-0.0.9.dist-info}/WHEEL +0 -0
- {glaip_sdk-0.0.8.dist-info → glaip_sdk-0.0.9.dist-info}/entry_points.txt +0 -0
glaip_sdk/cli/commands/mcps.py
CHANGED
|
@@ -36,6 +36,7 @@ from glaip_sdk.cli.utils import (
|
|
|
36
36
|
output_flags,
|
|
37
37
|
output_list,
|
|
38
38
|
output_result,
|
|
39
|
+
spinner_context,
|
|
39
40
|
)
|
|
40
41
|
from glaip_sdk.rich_components import AIPPanel
|
|
41
42
|
from glaip_sdk.utils import format_datetime
|
|
@@ -72,7 +73,12 @@ def list_mcps(ctx: Any) -> None:
|
|
|
72
73
|
"""List all MCPs."""
|
|
73
74
|
try:
|
|
74
75
|
client = get_client(ctx)
|
|
75
|
-
|
|
76
|
+
with spinner_context(
|
|
77
|
+
ctx,
|
|
78
|
+
"[bold blue]Fetching MCPs…[/bold blue]",
|
|
79
|
+
console_override=console,
|
|
80
|
+
):
|
|
81
|
+
mcps = client.mcps.list_mcps()
|
|
76
82
|
|
|
77
83
|
# Define table columns: (data_key, header, style, width)
|
|
78
84
|
columns = [
|
|
@@ -123,13 +129,18 @@ def create(
|
|
|
123
129
|
except json.JSONDecodeError:
|
|
124
130
|
raise click.ClickException("Invalid JSON in --config")
|
|
125
131
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
132
|
+
with spinner_context(
|
|
133
|
+
ctx,
|
|
134
|
+
"[bold blue]Creating MCP…[/bold blue]",
|
|
135
|
+
console_override=console,
|
|
136
|
+
):
|
|
137
|
+
mcp = client.mcps.create_mcp(
|
|
138
|
+
name=name,
|
|
139
|
+
type="server", # MCPs are always server type
|
|
140
|
+
transport=transport,
|
|
141
|
+
description=description,
|
|
142
|
+
config=mcp_config,
|
|
143
|
+
)
|
|
133
144
|
|
|
134
145
|
# Handle JSON output
|
|
135
146
|
handle_json_output(ctx, mcp.model_dump())
|
|
@@ -183,7 +194,12 @@ def get(ctx: Any, mcp_ref: str, export: str | None) -> None:
|
|
|
183
194
|
|
|
184
195
|
# Always export comprehensive data - re-fetch MCP with full details if needed
|
|
185
196
|
try:
|
|
186
|
-
|
|
197
|
+
with spinner_context(
|
|
198
|
+
ctx,
|
|
199
|
+
"[bold blue]Fetching complete MCP details…[/bold blue]",
|
|
200
|
+
console_override=console,
|
|
201
|
+
):
|
|
202
|
+
mcp = client.mcps.get_mcp_by_id(mcp.id)
|
|
187
203
|
except Exception as e:
|
|
188
204
|
console.print(
|
|
189
205
|
Text(f"[yellow]⚠️ Could not fetch full MCP details: {e}[/yellow]")
|
|
@@ -192,7 +208,12 @@ def get(ctx: Any, mcp_ref: str, export: str | None) -> None:
|
|
|
192
208
|
Text("[yellow]⚠️ Proceeding with available data[/yellow]")
|
|
193
209
|
)
|
|
194
210
|
|
|
195
|
-
|
|
211
|
+
with spinner_context(
|
|
212
|
+
ctx,
|
|
213
|
+
"[bold blue]Exporting MCP configuration…[/bold blue]",
|
|
214
|
+
console_override=console,
|
|
215
|
+
):
|
|
216
|
+
export_resource_to_file(mcp, export_path, detected_format)
|
|
196
217
|
console.print(
|
|
197
218
|
Text(
|
|
198
219
|
f"[green]✅ Complete MCP configuration exported to: {export_path} (format: {detected_format})[/green]"
|
|
@@ -200,7 +221,12 @@ def get(ctx: Any, mcp_ref: str, export: str | None) -> None:
|
|
|
200
221
|
)
|
|
201
222
|
|
|
202
223
|
# Try to fetch raw API data first to preserve ALL fields
|
|
203
|
-
|
|
224
|
+
with spinner_context(
|
|
225
|
+
ctx,
|
|
226
|
+
"[bold blue]Fetching detailed MCP data…[/bold blue]",
|
|
227
|
+
console_override=console,
|
|
228
|
+
):
|
|
229
|
+
raw_mcp_data = fetch_raw_resource_details(client, mcp, "mcps")
|
|
204
230
|
|
|
205
231
|
if raw_mcp_data:
|
|
206
232
|
# Use raw API data - this preserves ALL fields
|
|
@@ -257,7 +283,12 @@ def list_tools(ctx: Any, mcp_ref: str) -> None:
|
|
|
257
283
|
mcp = _resolve_mcp(ctx, client, mcp_ref)
|
|
258
284
|
|
|
259
285
|
# Get tools from MCP
|
|
260
|
-
|
|
286
|
+
with spinner_context(
|
|
287
|
+
ctx,
|
|
288
|
+
"[bold blue]Fetching MCP tools…[/bold blue]",
|
|
289
|
+
console_override=console,
|
|
290
|
+
):
|
|
291
|
+
tools = client.mcps.get_mcp_tools(mcp.id)
|
|
261
292
|
|
|
262
293
|
# Define table columns: (data_key, header, style, width)
|
|
263
294
|
columns = [
|
|
@@ -311,7 +342,12 @@ def connect(ctx: Any, config_file: str) -> None:
|
|
|
311
342
|
)
|
|
312
343
|
|
|
313
344
|
# Test connection using config
|
|
314
|
-
|
|
345
|
+
with spinner_context(
|
|
346
|
+
ctx,
|
|
347
|
+
"[bold blue]Connecting to MCP…[/bold blue]",
|
|
348
|
+
console_override=console,
|
|
349
|
+
):
|
|
350
|
+
result = client.mcps.test_mcp_connection_from_config(config)
|
|
315
351
|
|
|
316
352
|
view = get_ctx_value(ctx, "view", "rich")
|
|
317
353
|
if view == "json":
|
|
@@ -366,7 +402,12 @@ def update(
|
|
|
366
402
|
raise click.ClickException("No update fields specified")
|
|
367
403
|
|
|
368
404
|
# Update MCP (automatically chooses PUT or PATCH based on provided fields)
|
|
369
|
-
|
|
405
|
+
with spinner_context(
|
|
406
|
+
ctx,
|
|
407
|
+
"[bold blue]Updating MCP…[/bold blue]",
|
|
408
|
+
console_override=console,
|
|
409
|
+
):
|
|
410
|
+
updated_mcp = client.mcps.update_mcp(mcp.id, **update_data)
|
|
370
411
|
|
|
371
412
|
handle_json_output(ctx, updated_mcp.model_dump())
|
|
372
413
|
handle_rich_output(ctx, display_update_success("MCP", updated_mcp.name))
|
|
@@ -395,7 +436,12 @@ def delete(ctx: Any, mcp_ref: str, yes: bool) -> None:
|
|
|
395
436
|
if not yes and not display_confirmation_prompt("MCP", mcp.name):
|
|
396
437
|
return
|
|
397
438
|
|
|
398
|
-
|
|
439
|
+
with spinner_context(
|
|
440
|
+
ctx,
|
|
441
|
+
"[bold blue]Deleting MCP…[/bold blue]",
|
|
442
|
+
console_override=console,
|
|
443
|
+
):
|
|
444
|
+
client.mcps.delete_mcp(mcp.id)
|
|
399
445
|
|
|
400
446
|
handle_json_output(
|
|
401
447
|
ctx,
|
glaip_sdk/cli/commands/models.py
CHANGED
|
@@ -9,7 +9,12 @@ from typing import Any
|
|
|
9
9
|
import click
|
|
10
10
|
from rich.console import Console
|
|
11
11
|
|
|
12
|
-
from glaip_sdk.cli.utils import
|
|
12
|
+
from glaip_sdk.cli.utils import (
|
|
13
|
+
get_client,
|
|
14
|
+
output_flags,
|
|
15
|
+
output_list,
|
|
16
|
+
spinner_context,
|
|
17
|
+
)
|
|
13
18
|
|
|
14
19
|
console = Console()
|
|
15
20
|
|
|
@@ -27,7 +32,12 @@ def list_models(ctx: Any) -> None:
|
|
|
27
32
|
"""List available language models."""
|
|
28
33
|
try:
|
|
29
34
|
client = get_client(ctx)
|
|
30
|
-
|
|
35
|
+
with spinner_context(
|
|
36
|
+
ctx,
|
|
37
|
+
"[bold blue]Fetching language models…[/bold blue]",
|
|
38
|
+
console_override=console,
|
|
39
|
+
):
|
|
40
|
+
models = client.list_language_models()
|
|
31
41
|
|
|
32
42
|
# Define table columns: (data_key, header, style, width)
|
|
33
43
|
columns = [
|
glaip_sdk/cli/commands/tools.py
CHANGED
|
@@ -40,6 +40,7 @@ from glaip_sdk.cli.utils import (
|
|
|
40
40
|
output_flags,
|
|
41
41
|
output_list,
|
|
42
42
|
output_result,
|
|
43
|
+
spinner_context,
|
|
43
44
|
)
|
|
44
45
|
from glaip_sdk.utils import format_datetime
|
|
45
46
|
from glaip_sdk.utils.import_export import merge_import_with_cli_args
|
|
@@ -193,7 +194,12 @@ def list_tools(ctx: Any, tool_type: str | None) -> None:
|
|
|
193
194
|
"""List all tools."""
|
|
194
195
|
try:
|
|
195
196
|
client = get_client(ctx)
|
|
196
|
-
|
|
197
|
+
with spinner_context(
|
|
198
|
+
ctx,
|
|
199
|
+
"[bold blue]Fetching tools…[/bold blue]",
|
|
200
|
+
console_override=console,
|
|
201
|
+
):
|
|
202
|
+
tools = client.list_tools(tool_type=tool_type)
|
|
197
203
|
|
|
198
204
|
# Define table columns: (data_key, header, style, width)
|
|
199
205
|
columns = [
|
|
@@ -276,7 +282,12 @@ def create(
|
|
|
276
282
|
_validate_creation_parameters(file, import_file)
|
|
277
283
|
|
|
278
284
|
# Create tool from file (either direct file or import file)
|
|
279
|
-
|
|
285
|
+
with spinner_context(
|
|
286
|
+
ctx,
|
|
287
|
+
"[bold blue]Creating tool…[/bold blue]",
|
|
288
|
+
console_override=console,
|
|
289
|
+
):
|
|
290
|
+
tool = _create_tool_from_file(client, file, name, description, tags)
|
|
280
291
|
|
|
281
292
|
# Handle JSON output
|
|
282
293
|
handle_json_output(ctx, tool.model_dump())
|
|
@@ -333,7 +344,12 @@ def get(ctx: Any, tool_ref: str, select: int | None, export: str | None) -> None
|
|
|
333
344
|
|
|
334
345
|
# Always export comprehensive data - re-fetch tool with full details if needed
|
|
335
346
|
try:
|
|
336
|
-
|
|
347
|
+
with spinner_context(
|
|
348
|
+
ctx,
|
|
349
|
+
"[bold blue]Fetching complete tool details…[/bold blue]",
|
|
350
|
+
console_override=console,
|
|
351
|
+
):
|
|
352
|
+
tool = client.get_tool_by_id(tool.id)
|
|
337
353
|
except Exception as e:
|
|
338
354
|
console.print(
|
|
339
355
|
Text(f"[yellow]⚠️ Could not fetch full tool details: {e}[/yellow]")
|
|
@@ -342,7 +358,12 @@ def get(ctx: Any, tool_ref: str, select: int | None, export: str | None) -> None
|
|
|
342
358
|
Text("[yellow]⚠️ Proceeding with available data[/yellow]")
|
|
343
359
|
)
|
|
344
360
|
|
|
345
|
-
|
|
361
|
+
with spinner_context(
|
|
362
|
+
ctx,
|
|
363
|
+
"[bold blue]Exporting tool configuration…[/bold blue]",
|
|
364
|
+
console_override=console,
|
|
365
|
+
):
|
|
366
|
+
export_resource_to_file(tool, export_path, detected_format)
|
|
346
367
|
console.print(
|
|
347
368
|
Text(
|
|
348
369
|
f"[green]✅ Complete tool configuration exported to: {export_path} (format: {detected_format})[/green]"
|
|
@@ -350,7 +371,12 @@ def get(ctx: Any, tool_ref: str, select: int | None, export: str | None) -> None
|
|
|
350
371
|
)
|
|
351
372
|
|
|
352
373
|
# Try to fetch raw API data first to preserve ALL fields
|
|
353
|
-
|
|
374
|
+
with spinner_context(
|
|
375
|
+
ctx,
|
|
376
|
+
"[bold blue]Fetching detailed tool data…[/bold blue]",
|
|
377
|
+
console_override=console,
|
|
378
|
+
):
|
|
379
|
+
raw_tool_data = fetch_raw_resource_details(client, tool, "tools")
|
|
354
380
|
|
|
355
381
|
if raw_tool_data:
|
|
356
382
|
# Use raw API data - this preserves ALL fields
|
|
@@ -418,7 +444,12 @@ def update(
|
|
|
418
444
|
|
|
419
445
|
# Get tool by ID (no ambiguity handling needed)
|
|
420
446
|
try:
|
|
421
|
-
|
|
447
|
+
with spinner_context(
|
|
448
|
+
ctx,
|
|
449
|
+
"[bold blue]Fetching tool…[/bold blue]",
|
|
450
|
+
console_override=console,
|
|
451
|
+
):
|
|
452
|
+
tool = client.get_tool_by_id(tool_id)
|
|
422
453
|
except Exception as e:
|
|
423
454
|
raise click.ClickException(f"Tool with ID '{tool_id}' not found: {e}")
|
|
424
455
|
|
|
@@ -435,9 +466,14 @@ def update(
|
|
|
435
466
|
raise click.ClickException(
|
|
436
467
|
f"File updates are only supported for custom tools. Tool '{tool.name}' is of type '{tool.tool_type}'."
|
|
437
468
|
)
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
469
|
+
with spinner_context(
|
|
470
|
+
ctx,
|
|
471
|
+
"[bold blue]Uploading new tool code…[/bold blue]",
|
|
472
|
+
console_override=console,
|
|
473
|
+
):
|
|
474
|
+
updated_tool = client.tools.update_tool_via_file(
|
|
475
|
+
tool.id, file, framework=tool.framework
|
|
476
|
+
)
|
|
441
477
|
handle_rich_output(
|
|
442
478
|
ctx, Text(f"[green]✓[/green] Tool code updated from {file}")
|
|
443
479
|
)
|
|
@@ -447,7 +483,12 @@ def update(
|
|
|
447
483
|
raise click.ClickException(
|
|
448
484
|
f"Metadata updates are only supported for native tools. Tool '{tool.name}' is of type '{tool.tool_type}'."
|
|
449
485
|
)
|
|
450
|
-
|
|
486
|
+
with spinner_context(
|
|
487
|
+
ctx,
|
|
488
|
+
"[bold blue]Updating tool metadata…[/bold blue]",
|
|
489
|
+
console_override=console,
|
|
490
|
+
):
|
|
491
|
+
updated_tool = tool.update(**update_data)
|
|
451
492
|
handle_rich_output(ctx, Text("[green]✓[/green] Tool metadata updated"))
|
|
452
493
|
else:
|
|
453
494
|
handle_rich_output(ctx, Text("[yellow]No updates specified[/yellow]"))
|
|
@@ -475,7 +516,12 @@ def delete(ctx: Any, tool_id: str, yes: bool) -> None:
|
|
|
475
516
|
|
|
476
517
|
# Get tool by ID (no ambiguity handling needed)
|
|
477
518
|
try:
|
|
478
|
-
|
|
519
|
+
with spinner_context(
|
|
520
|
+
ctx,
|
|
521
|
+
"[bold blue]Fetching tool…[/bold blue]",
|
|
522
|
+
console_override=console,
|
|
523
|
+
):
|
|
524
|
+
tool = client.get_tool_by_id(tool_id)
|
|
479
525
|
except Exception as e:
|
|
480
526
|
raise click.ClickException(f"Tool with ID '{tool_id}' not found: {e}")
|
|
481
527
|
|
|
@@ -483,7 +529,12 @@ def delete(ctx: Any, tool_id: str, yes: bool) -> None:
|
|
|
483
529
|
if not yes and not display_confirmation_prompt("Tool", tool.name):
|
|
484
530
|
return
|
|
485
531
|
|
|
486
|
-
|
|
532
|
+
with spinner_context(
|
|
533
|
+
ctx,
|
|
534
|
+
"[bold blue]Deleting tool…[/bold blue]",
|
|
535
|
+
console_override=console,
|
|
536
|
+
):
|
|
537
|
+
tool.delete()
|
|
487
538
|
|
|
488
539
|
handle_json_output(
|
|
489
540
|
ctx,
|
|
@@ -509,7 +560,12 @@ def script(ctx: Any, tool_id: str) -> None:
|
|
|
509
560
|
"""Get tool script content."""
|
|
510
561
|
try:
|
|
511
562
|
client = get_client(ctx)
|
|
512
|
-
|
|
563
|
+
with spinner_context(
|
|
564
|
+
ctx,
|
|
565
|
+
"[bold blue]Fetching tool script…[/bold blue]",
|
|
566
|
+
console_override=console,
|
|
567
|
+
):
|
|
568
|
+
script_content = client.get_tool_script(tool_id)
|
|
513
569
|
|
|
514
570
|
if get_ctx_value(ctx, "view") == "json":
|
|
515
571
|
click.echo(json.dumps({"script": script_content}, indent=2))
|
glaip_sdk/cli/main.py
CHANGED
|
@@ -24,7 +24,7 @@ from glaip_sdk.cli.commands.configure import (
|
|
|
24
24
|
from glaip_sdk.cli.commands.mcps import mcps_group
|
|
25
25
|
from glaip_sdk.cli.commands.models import models_group
|
|
26
26
|
from glaip_sdk.cli.commands.tools import tools_group
|
|
27
|
-
from glaip_sdk.cli.utils import spinner_context
|
|
27
|
+
from glaip_sdk.cli.utils import spinner_context, update_spinner
|
|
28
28
|
from glaip_sdk.config.constants import (
|
|
29
29
|
DEFAULT_AGENT_RUN_TIMEOUT,
|
|
30
30
|
)
|
|
@@ -190,16 +190,19 @@ def status(ctx: Any) -> None:
|
|
|
190
190
|
console_override=console,
|
|
191
191
|
spinner_style="cyan",
|
|
192
192
|
) as status_indicator:
|
|
193
|
-
|
|
194
|
-
status_indicator
|
|
193
|
+
update_spinner(
|
|
194
|
+
status_indicator, "[bold blue]Fetching agents…[/bold blue]"
|
|
195
|
+
)
|
|
195
196
|
agents = client.list_agents()
|
|
196
197
|
|
|
197
|
-
|
|
198
|
-
status_indicator
|
|
198
|
+
update_spinner(
|
|
199
|
+
status_indicator, "[bold blue]Fetching tools…[/bold blue]"
|
|
200
|
+
)
|
|
199
201
|
tools = client.list_tools()
|
|
200
202
|
|
|
201
|
-
|
|
202
|
-
status_indicator
|
|
203
|
+
update_spinner(
|
|
204
|
+
status_indicator, "[bold blue]Fetching MCPs…[/bold blue]"
|
|
205
|
+
)
|
|
203
206
|
mcps = client.list_mcps()
|
|
204
207
|
|
|
205
208
|
# Create status table
|
glaip_sdk/cli/utils.py
CHANGED
|
@@ -275,7 +275,7 @@ def _stream_supports_tty(stream: Any) -> bool:
|
|
|
275
275
|
return False
|
|
276
276
|
|
|
277
277
|
|
|
278
|
-
def
|
|
278
|
+
def update_spinner(status_indicator: Any | None, message: str) -> None:
|
|
279
279
|
"""Update spinner text when a status indicator is active."""
|
|
280
280
|
|
|
281
281
|
if status_indicator is None:
|
|
@@ -287,7 +287,7 @@ def _spinner_update(status_indicator: Any | None, message: str) -> None:
|
|
|
287
287
|
pass
|
|
288
288
|
|
|
289
289
|
|
|
290
|
-
def
|
|
290
|
+
def stop_spinner(status_indicator: Any | None) -> None:
|
|
291
291
|
"""Stop an active spinner safely."""
|
|
292
292
|
|
|
293
293
|
if status_indicator is None:
|
|
@@ -299,6 +299,11 @@ def _spinner_stop(status_indicator: Any | None) -> None:
|
|
|
299
299
|
pass
|
|
300
300
|
|
|
301
301
|
|
|
302
|
+
# Backwards compatibility aliases for legacy callers
|
|
303
|
+
_spinner_update = update_spinner
|
|
304
|
+
_spinner_stop = stop_spinner
|
|
305
|
+
|
|
306
|
+
|
|
302
307
|
# ----------------------------- Client config ----------------------------- #
|
|
303
308
|
|
|
304
309
|
|
|
@@ -870,25 +875,64 @@ def _handle_empty_items(title: str) -> None:
|
|
|
870
875
|
console.print(Text(f"[yellow]No {title.lower()} found.[/yellow]"))
|
|
871
876
|
|
|
872
877
|
|
|
878
|
+
def _should_use_fuzzy_picker() -> bool:
|
|
879
|
+
"""Return True when the interactive fuzzy picker can be shown."""
|
|
880
|
+
|
|
881
|
+
return console.is_terminal and os.isatty(1)
|
|
882
|
+
|
|
883
|
+
|
|
884
|
+
def _try_fuzzy_pick(
|
|
885
|
+
rows: list[dict[str, Any]], columns: list[tuple], title: str
|
|
886
|
+
) -> dict[str, Any] | None:
|
|
887
|
+
"""Best-effort fuzzy selection; returns None if the picker fails."""
|
|
888
|
+
|
|
889
|
+
if not _should_use_fuzzy_picker():
|
|
890
|
+
return None
|
|
891
|
+
|
|
892
|
+
try:
|
|
893
|
+
return _fuzzy_pick(rows, columns, title)
|
|
894
|
+
except Exception:
|
|
895
|
+
logger.debug("Fuzzy picker failed; falling back to table output", exc_info=True)
|
|
896
|
+
return None
|
|
897
|
+
|
|
898
|
+
|
|
899
|
+
def _resource_tip_command(title: str) -> str:
|
|
900
|
+
"""Resolve the follow-up command hint for the given table title."""
|
|
901
|
+
|
|
902
|
+
title_lower = title.lower()
|
|
903
|
+
mapping = {
|
|
904
|
+
"agent": "aip agents get",
|
|
905
|
+
"tool": "aip tools get",
|
|
906
|
+
"mcp": "aip mcps get",
|
|
907
|
+
"model": "aip models list", # models only ship a list command
|
|
908
|
+
}
|
|
909
|
+
for keyword, command in mapping.items():
|
|
910
|
+
if keyword in title_lower:
|
|
911
|
+
return command
|
|
912
|
+
return "aip agents get"
|
|
913
|
+
|
|
914
|
+
|
|
915
|
+
def _print_selection_tip(title: str) -> None:
|
|
916
|
+
"""Print the contextual follow-up tip after a fuzzy selection."""
|
|
917
|
+
|
|
918
|
+
tip_cmd = _resource_tip_command(title)
|
|
919
|
+
console.print(Text(f"\n[dim]Tip: use `{tip_cmd} <ID>` for details[/dim]"))
|
|
920
|
+
|
|
921
|
+
|
|
873
922
|
def _handle_fuzzy_pick_selection(
|
|
874
923
|
rows: list[dict[str, Any]], columns: list[tuple], title: str
|
|
875
924
|
) -> bool:
|
|
876
925
|
"""Handle fuzzy picker selection, returns True if selection was made."""
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
table.add_row(*[str(picked.get(key, "N/A")) for key, _, _, _ in columns])
|
|
888
|
-
console.print(table)
|
|
889
|
-
console.print(Text("\n[dim]Tip: use `aip agents get <ID>` for details[/dim]"))
|
|
890
|
-
return True
|
|
891
|
-
return False
|
|
926
|
+
|
|
927
|
+
picked = _try_fuzzy_pick(rows, columns, title)
|
|
928
|
+
if picked is None:
|
|
929
|
+
return False
|
|
930
|
+
|
|
931
|
+
table = _create_table(columns, title)
|
|
932
|
+
table.add_row(*[str(picked.get(key, "N/A")) for key, _, _, _ in columns])
|
|
933
|
+
console.print(table)
|
|
934
|
+
_print_selection_tip(title)
|
|
935
|
+
return True
|
|
892
936
|
|
|
893
937
|
|
|
894
938
|
def _handle_table_output(
|
|
@@ -6,12 +6,25 @@ Authors:
|
|
|
6
6
|
|
|
7
7
|
from __future__ import annotations
|
|
8
8
|
|
|
9
|
+
from rich.align import Align
|
|
9
10
|
from rich.markdown import Markdown
|
|
11
|
+
from rich.spinner import Spinner
|
|
10
12
|
from rich.text import Text
|
|
11
13
|
|
|
12
14
|
from glaip_sdk.rich_components import AIPPanel
|
|
13
15
|
|
|
14
16
|
|
|
17
|
+
def _spinner_renderable(message: str = "Processing...") -> Align:
|
|
18
|
+
"""Build a Rich spinner renderable for loading placeholders."""
|
|
19
|
+
|
|
20
|
+
spinner = Spinner(
|
|
21
|
+
"dots",
|
|
22
|
+
text=Text(f" {message}", style="dim"),
|
|
23
|
+
style="cyan",
|
|
24
|
+
)
|
|
25
|
+
return Align.left(spinner)
|
|
26
|
+
|
|
27
|
+
|
|
15
28
|
def create_main_panel(content: str, title: str, theme: str = "dark") -> AIPPanel:
|
|
16
29
|
"""Create a main content panel.
|
|
17
30
|
|
|
@@ -30,10 +43,8 @@ def create_main_panel(content: str, title: str, theme: str = "dark") -> AIPPanel
|
|
|
30
43
|
border_style="green",
|
|
31
44
|
)
|
|
32
45
|
else:
|
|
33
|
-
# Placeholder panel
|
|
34
|
-
placeholder = Text("Processing...", style="dim")
|
|
35
46
|
return AIPPanel(
|
|
36
|
-
|
|
47
|
+
_spinner_renderable(),
|
|
37
48
|
title=title,
|
|
38
49
|
border_style="green",
|
|
39
50
|
)
|
|
@@ -61,11 +72,14 @@ def create_tool_panel(
|
|
|
61
72
|
mark = "✓" if status == "finished" else "⟳"
|
|
62
73
|
border_style = "magenta" if is_delegation else "blue"
|
|
63
74
|
|
|
75
|
+
body_renderable = (
|
|
76
|
+
Markdown(content, code_theme=("monokai" if theme == "dark" else "github"))
|
|
77
|
+
if content
|
|
78
|
+
else _spinner_renderable()
|
|
79
|
+
)
|
|
80
|
+
|
|
64
81
|
return AIPPanel(
|
|
65
|
-
|
|
66
|
-
content or "Processing...",
|
|
67
|
-
code_theme=("monokai" if theme == "dark" else "github"),
|
|
68
|
-
),
|
|
82
|
+
body_renderable,
|
|
69
83
|
title=f"{title} {mark}",
|
|
70
84
|
border_style=border_style,
|
|
71
85
|
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: glaip-sdk
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.9
|
|
4
4
|
Summary: Python SDK for GL AIP (GDP Labs AI Agent Package) - Simplified CLI Design
|
|
5
5
|
License: MIT
|
|
6
6
|
Author: Raymond Christopher
|
|
@@ -11,7 +11,7 @@ Classifier: Programming Language :: Python :: 3
|
|
|
11
11
|
Classifier: Programming Language :: Python :: 3.10
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.11
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
-
Requires-Dist: click (>=8.2.0)
|
|
14
|
+
Requires-Dist: click (>=8.2.0,<8.3.0)
|
|
15
15
|
Requires-Dist: httpx (>=0.28.1)
|
|
16
16
|
Requires-Dist: pydantic (>=2.0.0)
|
|
17
17
|
Requires-Dist: python-dotenv (>=1.1.1,<2.0.0)
|
|
@@ -6,18 +6,18 @@ glaip_sdk/cli/agent_config.py,sha256=VHjebw68wAdhGUzYdPH8qz10oADZPRgUQcPW6F7iHIU
|
|
|
6
6
|
glaip_sdk/cli/commands/__init__.py,sha256=x0CZlZbZHoHvuzfoTWIyEch6WmNnbPzxajrox6riYp0,173
|
|
7
7
|
glaip_sdk/cli/commands/agents.py,sha256=1xGSoH6C9hSaGglXf4pnloqX5gJQIPsgHhkliiWQQcY,39988
|
|
8
8
|
glaip_sdk/cli/commands/configure.py,sha256=eRDzsaKV4fl2lJt8ieS4g2-xRnaa02eAAPW8xBf-tqA,7507
|
|
9
|
-
glaip_sdk/cli/commands/mcps.py,sha256=
|
|
10
|
-
glaip_sdk/cli/commands/models.py,sha256=
|
|
11
|
-
glaip_sdk/cli/commands/tools.py,sha256=
|
|
9
|
+
glaip_sdk/cli/commands/mcps.py,sha256=fRCRQMAnogT76lHUn_nuqkge_x75Fj023CDRgdoj0kQ,14343
|
|
10
|
+
glaip_sdk/cli/commands/models.py,sha256=Ra3-50BPScNs0Q-j4b7U4iK0hNooucEyVgHpQ11-pt8,1700
|
|
11
|
+
glaip_sdk/cli/commands/tools.py,sha256=MOM9Db3HGL1stF-WvL5cZXjw-iZo2qc-oyKQHy6VwIM,18690
|
|
12
12
|
glaip_sdk/cli/display.py,sha256=jE20swoRKzpYUmc0jgbeonaXKeE9x95hfjWAEdnBYRc,8727
|
|
13
13
|
glaip_sdk/cli/io.py,sha256=GPkw3pQMLBGoD5GH-KlbKpNRlVWFZOXHE17F7V3kQsI,3343
|
|
14
|
-
glaip_sdk/cli/main.py,sha256=
|
|
14
|
+
glaip_sdk/cli/main.py,sha256=uWuntvFl0hQSLfNa1rXb-J2zUK_msf3vrSbbrqBcEc4,12692
|
|
15
15
|
glaip_sdk/cli/resolution.py,sha256=BOw2NchReLKewAwBAZLWw_3_bI7u3tfzQEO7kQbIiGE,2067
|
|
16
16
|
glaip_sdk/cli/slash/__init__.py,sha256=Vdv6Y8bu-pA8dxDlyP4XrhudBPivztUozhLAz9vaLig,682
|
|
17
17
|
glaip_sdk/cli/slash/agent_session.py,sha256=JFIFBxB4xzigqHtpLGbl2fgg7RHNwy3e-kUMPMK9MdM,5006
|
|
18
18
|
glaip_sdk/cli/slash/prompt.py,sha256=QFWYgNt5AhBRYGGyUkH30ToZE7B6LS-eZGzoyibYrK8,6064
|
|
19
19
|
glaip_sdk/cli/slash/session.py,sha256=GtnnBqV79KtFJHeLfCKKnCXJ6SU1AmeXquPjy72T20E,24215
|
|
20
|
-
glaip_sdk/cli/utils.py,sha256=
|
|
20
|
+
glaip_sdk/cli/utils.py,sha256=S7aa4-v808BEZGvEhKn8N8HQr2slSpvV-TtWw3j15S8,41779
|
|
21
21
|
glaip_sdk/cli/validators.py,sha256=USbBgY86AwuDHO-Q_g8g7hu-ot4NgITBsWjTWIl62ms,5569
|
|
22
22
|
glaip_sdk/client/__init__.py,sha256=nYLXfBVTTWwKjP0e63iumPYO4k5FifwWaELQPaPIKIg,188
|
|
23
23
|
glaip_sdk/client/agents.py,sha256=FSKubF40wptMNIheC3_iawiX2CRbhTcNLFiz4qkPC6k,34659
|
|
@@ -40,11 +40,11 @@ glaip_sdk/utils/rendering/__init__.py,sha256=vXjwk5rPhhfPyD8S0DnV4GFFEtPJp4HCCg1
|
|
|
40
40
|
glaip_sdk/utils/rendering/formatting.py,sha256=_k8tkcobctmHvdygMljZF7-ALGXpD9-hHF1CNtM2KMU,7201
|
|
41
41
|
glaip_sdk/utils/rendering/models.py,sha256=SS34_00FaoGuSYn-viBkAtIbq7cJNwwPjpxnvyeUmxI,1567
|
|
42
42
|
glaip_sdk/utils/rendering/renderer/__init__.py,sha256=EXwVBmGkSYcype4ocAXo69Z1kXu0gpNXmhH5LW0_B7A,2939
|
|
43
|
-
glaip_sdk/utils/rendering/renderer/base.py,sha256=
|
|
43
|
+
glaip_sdk/utils/rendering/renderer/base.py,sha256=HfIeq-izi3WprbKX_qxNeQRrpernFtoCvgQqrIyVYSU,40950
|
|
44
44
|
glaip_sdk/utils/rendering/renderer/config.py,sha256=E4ER8TJJbqr1hcWjkwG7XROqLuccQy4EL99CbuLvSXE,783
|
|
45
45
|
glaip_sdk/utils/rendering/renderer/console.py,sha256=4cLOw4Q1fkHkApuj6dWW8eYpeYdcT0t2SO5MbVt5UTc,1844
|
|
46
46
|
glaip_sdk/utils/rendering/renderer/debug.py,sha256=FEYxAu4ZB0CjrJKevqQ2TKDgElA2cf6GqZXCNm12sNQ,3721
|
|
47
|
-
glaip_sdk/utils/rendering/renderer/panels.py,sha256=
|
|
47
|
+
glaip_sdk/utils/rendering/renderer/panels.py,sha256=05u6SjU53iP9VD0YHTNruzD7sO6qYCp-P5dTTSdSZmU,3364
|
|
48
48
|
glaip_sdk/utils/rendering/renderer/progress.py,sha256=i4HG_iNwtK4c3Gf2sviLCiOJ-5ydX4t-YE5dgtLOxNI,3438
|
|
49
49
|
glaip_sdk/utils/rendering/renderer/stream.py,sha256=1RP5TIV7tqg07X9gPN053XeabFGVT4jPplxaoPU0L38,8601
|
|
50
50
|
glaip_sdk/utils/rendering/steps.py,sha256=4zdeyKxMbUzCal4-yv8yf18144cs5wwXaxhe6mt2KiE,7307
|
|
@@ -53,7 +53,7 @@ glaip_sdk/utils/rich_utils.py,sha256=-Ij-1bIJvnVAi6DrfftchIlMcvOTjVmSE0Qqax0EY_s
|
|
|
53
53
|
glaip_sdk/utils/run_renderer.py,sha256=d_VMI6LbvHPUUeRmGqh5wK_lHqDEIAcym2iqpbtDad0,1365
|
|
54
54
|
glaip_sdk/utils/serialization.py,sha256=cUE6PxqTsfJuEEmsk_Li3QmaDavTIPotEA-BQ-v5exY,9043
|
|
55
55
|
glaip_sdk/utils/validation.py,sha256=QNORcdyvuliEs4EH2_mkDgmoyT9utgl7YNhaf45SEf8,6992
|
|
56
|
-
glaip_sdk-0.0.
|
|
57
|
-
glaip_sdk-0.0.
|
|
58
|
-
glaip_sdk-0.0.
|
|
59
|
-
glaip_sdk-0.0.
|
|
56
|
+
glaip_sdk-0.0.9.dist-info/METADATA,sha256=f2-GNqMR8cLgyQnA4f7TCPZv1ETZE4S8LSpQaPD6GrE,4949
|
|
57
|
+
glaip_sdk-0.0.9.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
58
|
+
glaip_sdk-0.0.9.dist-info/entry_points.txt,sha256=EGs8NO8J1fdFMWA3CsF7sKBEvtHb_fujdCoNPhfMouE,47
|
|
59
|
+
glaip_sdk-0.0.9.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|