glaip-sdk 0.1.0__py3-none-any.whl → 0.1.2__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/_version.py +1 -3
- glaip_sdk/branding.py +2 -6
- glaip_sdk/cli/agent_config.py +2 -6
- glaip_sdk/cli/auth.py +11 -30
- glaip_sdk/cli/commands/agents.py +45 -107
- glaip_sdk/cli/commands/configure.py +12 -36
- glaip_sdk/cli/commands/mcps.py +26 -63
- glaip_sdk/cli/commands/models.py +2 -4
- glaip_sdk/cli/commands/tools.py +22 -35
- glaip_sdk/cli/commands/update.py +3 -8
- glaip_sdk/cli/config.py +1 -3
- glaip_sdk/cli/display.py +4 -12
- glaip_sdk/cli/io.py +8 -14
- glaip_sdk/cli/main.py +10 -30
- glaip_sdk/cli/mcp_validators.py +5 -15
- glaip_sdk/cli/pager.py +3 -9
- glaip_sdk/cli/parsers/json_input.py +11 -22
- glaip_sdk/cli/resolution.py +3 -9
- glaip_sdk/cli/rich_helpers.py +1 -3
- glaip_sdk/cli/slash/agent_session.py +5 -10
- glaip_sdk/cli/slash/prompt.py +3 -10
- glaip_sdk/cli/slash/session.py +46 -95
- glaip_sdk/cli/transcript/cache.py +6 -19
- glaip_sdk/cli/transcript/capture.py +6 -20
- glaip_sdk/cli/transcript/launcher.py +1 -3
- glaip_sdk/cli/transcript/viewer.py +11 -40
- glaip_sdk/cli/update_notifier.py +165 -21
- glaip_sdk/cli/utils.py +33 -84
- glaip_sdk/cli/validators.py +11 -12
- glaip_sdk/client/_agent_payloads.py +10 -30
- glaip_sdk/client/agents.py +33 -63
- glaip_sdk/client/base.py +77 -35
- glaip_sdk/client/mcps.py +1 -3
- glaip_sdk/client/run_rendering.py +6 -14
- glaip_sdk/client/tools.py +8 -24
- glaip_sdk/client/validators.py +20 -48
- glaip_sdk/exceptions.py +1 -3
- glaip_sdk/models.py +14 -33
- glaip_sdk/payload_schemas/agent.py +1 -3
- glaip_sdk/utils/agent_config.py +4 -14
- glaip_sdk/utils/client_utils.py +7 -21
- glaip_sdk/utils/display.py +2 -6
- glaip_sdk/utils/general.py +1 -3
- glaip_sdk/utils/import_export.py +3 -9
- glaip_sdk/utils/rendering/formatting.py +2 -5
- glaip_sdk/utils/rendering/models.py +2 -6
- glaip_sdk/utils/rendering/renderer/__init__.py +1 -3
- glaip_sdk/utils/rendering/renderer/base.py +63 -189
- glaip_sdk/utils/rendering/renderer/debug.py +4 -14
- glaip_sdk/utils/rendering/renderer/panels.py +1 -3
- glaip_sdk/utils/rendering/renderer/progress.py +3 -11
- glaip_sdk/utils/rendering/renderer/stream.py +7 -19
- glaip_sdk/utils/rendering/renderer/toggle.py +1 -3
- glaip_sdk/utils/rendering/step_tree_state.py +1 -3
- glaip_sdk/utils/rendering/steps.py +29 -83
- glaip_sdk/utils/resource_refs.py +4 -13
- glaip_sdk/utils/serialization.py +14 -46
- glaip_sdk/utils/validation.py +4 -4
- {glaip_sdk-0.1.0.dist-info → glaip_sdk-0.1.2.dist-info}/METADATA +1 -1
- glaip_sdk-0.1.2.dist-info/RECORD +82 -0
- glaip_sdk-0.1.0.dist-info/RECORD +0 -82
- {glaip_sdk-0.1.0.dist-info → glaip_sdk-0.1.2.dist-info}/WHEEL +0 -0
- {glaip_sdk-0.1.0.dist-info → glaip_sdk-0.1.2.dist-info}/entry_points.txt +0 -0
glaip_sdk/_version.py
CHANGED
|
@@ -47,9 +47,7 @@ def _try_get_dev_version() -> str | None:
|
|
|
47
47
|
return None
|
|
48
48
|
|
|
49
49
|
data = _toml.loads(pyproject.read_text(encoding="utf-8"))
|
|
50
|
-
ver = data.get("project", {}).get("version") or data.get("tool", {}).get(
|
|
51
|
-
"poetry", {}
|
|
52
|
-
).get("version")
|
|
50
|
+
ver = data.get("project", {}).get("version") or data.get("tool", {}).get("poetry", {}).get("version")
|
|
53
51
|
if isinstance(ver, str) and ver:
|
|
54
52
|
return ver
|
|
55
53
|
except Exception:
|
glaip_sdk/branding.py
CHANGED
|
@@ -104,9 +104,7 @@ GDP Labs AI Agents Package
|
|
|
104
104
|
@staticmethod
|
|
105
105
|
def _make_console() -> Console:
|
|
106
106
|
# Respect NO_COLOR/AIP_NO_COLOR environment variables
|
|
107
|
-
no_color_env = (
|
|
108
|
-
os.getenv("NO_COLOR") is not None or os.getenv("AIP_NO_COLOR") is not None
|
|
109
|
-
)
|
|
107
|
+
no_color_env = os.getenv("NO_COLOR") is not None or os.getenv("AIP_NO_COLOR") is not None
|
|
110
108
|
if no_color_env:
|
|
111
109
|
color_system = None
|
|
112
110
|
no_color = True
|
|
@@ -187,9 +185,7 @@ GDP Labs AI Agents Package
|
|
|
187
185
|
self.console.print(banner)
|
|
188
186
|
|
|
189
187
|
@classmethod
|
|
190
|
-
def create_from_sdk(
|
|
191
|
-
cls, sdk_version: str | None = None, package_name: str | None = None
|
|
192
|
-
) -> AIPBranding:
|
|
188
|
+
def create_from_sdk(cls, sdk_version: str | None = None, package_name: str | None = None) -> AIPBranding:
|
|
193
189
|
"""Create AIPBranding instance from SDK package information.
|
|
194
190
|
|
|
195
191
|
Args:
|
glaip_sdk/cli/agent_config.py
CHANGED
|
@@ -16,9 +16,7 @@ from glaip_sdk.utils.agent_config import (
|
|
|
16
16
|
from glaip_sdk.utils.import_export import merge_import_with_cli_args
|
|
17
17
|
|
|
18
18
|
|
|
19
|
-
def merge_agent_config_with_cli_args(
|
|
20
|
-
import_data: dict[str, Any], cli_args: dict[str, Any]
|
|
21
|
-
) -> dict[str, Any]:
|
|
19
|
+
def merge_agent_config_with_cli_args(import_data: dict[str, Any], cli_args: dict[str, Any]) -> dict[str, Any]:
|
|
22
20
|
"""Merge imported agent data with CLI arguments, preferring CLI args.
|
|
23
21
|
|
|
24
22
|
This is a CLI-specific wrapper that handles agent-specific merging logic.
|
|
@@ -35,9 +33,7 @@ def merge_agent_config_with_cli_args(
|
|
|
35
33
|
- Handles agent-specific fields like tools and agents arrays
|
|
36
34
|
- Preserves agent configuration structure
|
|
37
35
|
"""
|
|
38
|
-
return merge_import_with_cli_args(
|
|
39
|
-
import_data, cli_args, array_fields=["tools", "agents"]
|
|
40
|
-
)
|
|
36
|
+
return merge_import_with_cli_args(import_data, cli_args, array_fields=["tools", "agents"])
|
|
41
37
|
|
|
42
38
|
|
|
43
39
|
def resolve_agent_language_model_selection(
|
glaip_sdk/cli/auth.py
CHANGED
|
@@ -65,9 +65,7 @@ def prepare_authentication_export(
|
|
|
65
65
|
|
|
66
66
|
# Handle bearer-token authentication
|
|
67
67
|
if auth_type == "bearer-token":
|
|
68
|
-
return _prepare_bearer_token_auth(
|
|
69
|
-
auth, prompt_for_secrets, placeholder, console
|
|
70
|
-
)
|
|
68
|
+
return _prepare_bearer_token_auth(auth, prompt_for_secrets, placeholder, console)
|
|
71
69
|
|
|
72
70
|
# Handle api-key authentication
|
|
73
71
|
if auth_type == "api-key":
|
|
@@ -75,9 +73,7 @@ def prepare_authentication_export(
|
|
|
75
73
|
|
|
76
74
|
# Handle custom-header authentication
|
|
77
75
|
if auth_type == "custom-header":
|
|
78
|
-
return _prepare_custom_header_auth(
|
|
79
|
-
auth, prompt_for_secrets, placeholder, console
|
|
80
|
-
)
|
|
76
|
+
return _prepare_custom_header_auth(auth, prompt_for_secrets, placeholder, console)
|
|
81
77
|
|
|
82
78
|
# Unknown auth type - return as-is but strip helper metadata
|
|
83
79
|
result = auth.copy()
|
|
@@ -85,9 +81,7 @@ def prepare_authentication_export(
|
|
|
85
81
|
return result
|
|
86
82
|
|
|
87
83
|
|
|
88
|
-
def _get_token_value(
|
|
89
|
-
prompt_for_secrets: bool, placeholder: str, console: Console
|
|
90
|
-
) -> str:
|
|
84
|
+
def _get_token_value(prompt_for_secrets: bool, placeholder: str, console: Console) -> str:
|
|
91
85
|
"""Get bearer token value either by prompting or using a placeholder.
|
|
92
86
|
|
|
93
87
|
Args:
|
|
@@ -109,10 +103,7 @@ def _get_token_value(
|
|
|
109
103
|
)
|
|
110
104
|
|
|
111
105
|
if not click.get_text_stream("stdin").isatty():
|
|
112
|
-
console.print(
|
|
113
|
-
f"[{WARNING_STYLE}]⚠️ Non-interactive mode: "
|
|
114
|
-
"using placeholder for bearer token[/]"
|
|
115
|
-
)
|
|
106
|
+
console.print(f"[{WARNING_STYLE}]⚠️ Non-interactive mode: using placeholder for bearer token[/]")
|
|
116
107
|
return placeholder
|
|
117
108
|
|
|
118
109
|
|
|
@@ -220,16 +211,11 @@ def _get_api_key_value(
|
|
|
220
211
|
)
|
|
221
212
|
|
|
222
213
|
if not click.get_text_stream("stdin").isatty():
|
|
223
|
-
console.print(
|
|
224
|
-
f"[{WARNING_STYLE}]⚠️ Non-interactive mode: "
|
|
225
|
-
f"using placeholder for API key '{key_name}'[/]"
|
|
226
|
-
)
|
|
214
|
+
console.print(f"[{WARNING_STYLE}]⚠️ Non-interactive mode: using placeholder for API key '{key_name}'[/]")
|
|
227
215
|
return placeholder
|
|
228
216
|
|
|
229
217
|
|
|
230
|
-
def _build_api_key_headers(
|
|
231
|
-
auth: dict[str, Any], key_name: str | None, key_value: str
|
|
232
|
-
) -> dict[str, str]:
|
|
218
|
+
def _build_api_key_headers(auth: dict[str, Any], key_name: str | None, key_value: str) -> dict[str, str]:
|
|
233
219
|
"""Build headers for API key authentication.
|
|
234
220
|
|
|
235
221
|
Args:
|
|
@@ -270,9 +256,7 @@ def _prepare_api_key_auth(
|
|
|
270
256
|
|
|
271
257
|
# Capture or use placeholder for value
|
|
272
258
|
if not has_valid_value:
|
|
273
|
-
key_value = _get_api_key_value(
|
|
274
|
-
key_name, prompt_for_secrets, placeholder, console
|
|
275
|
-
)
|
|
259
|
+
key_value = _get_api_key_value(key_name, prompt_for_secrets, placeholder, console)
|
|
276
260
|
|
|
277
261
|
# Check if original had headers structure
|
|
278
262
|
if "headers" in auth or "header_keys" in auth:
|
|
@@ -317,9 +301,7 @@ def _prepare_custom_header_auth(
|
|
|
317
301
|
return {"type": "custom-header", "headers": headers}
|
|
318
302
|
|
|
319
303
|
|
|
320
|
-
def _extract_header_names(
|
|
321
|
-
existing_headers: Mapping[str, Any] | None, header_keys: Iterable[str] | None
|
|
322
|
-
) -> list[str]:
|
|
304
|
+
def _extract_header_names(existing_headers: Mapping[str, Any] | None, header_keys: Iterable[str] | None) -> list[str]:
|
|
323
305
|
"""Extract the list of header names to process.
|
|
324
306
|
|
|
325
307
|
Args:
|
|
@@ -376,9 +358,7 @@ def _prompt_or_placeholder(
|
|
|
376
358
|
)
|
|
377
359
|
|
|
378
360
|
if not click.get_text_stream("stdin").isatty():
|
|
379
|
-
console.print(
|
|
380
|
-
f"[{WARNING_STYLE}]⚠️ Non-interactive mode: using placeholder for header '{name}'[/]"
|
|
381
|
-
)
|
|
361
|
+
console.print(f"[{WARNING_STYLE}]⚠️ Non-interactive mode: using placeholder for header '{name}'[/]")
|
|
382
362
|
return placeholder
|
|
383
363
|
|
|
384
364
|
|
|
@@ -450,7 +430,8 @@ def _prompt_secret_with_placeholder(
|
|
|
450
430
|
tip = command_hint(tip_cli_command, tip_slash_command)
|
|
451
431
|
if tip:
|
|
452
432
|
console.print(
|
|
453
|
-
f"[{HINT_PREFIX_STYLE}]Tip:[/] use {format_command_hint(tip) or tip} later
|
|
433
|
+
f"[{HINT_PREFIX_STYLE}]Tip:[/] use {format_command_hint(tip) or tip} later "
|
|
434
|
+
"if you want to update these credentials."
|
|
454
435
|
)
|
|
455
436
|
|
|
456
437
|
attempts = 0
|
glaip_sdk/cli/commands/agents.py
CHANGED
|
@@ -247,9 +247,7 @@ def _resolve_resources_by_name(
|
|
|
247
247
|
if not matches:
|
|
248
248
|
raise click.ClickException(f"{label} not found: {ref}")
|
|
249
249
|
if len(matches) > 1:
|
|
250
|
-
raise click.ClickException(
|
|
251
|
-
f"Multiple {resource_type}s named '{ref}'. Use ID instead."
|
|
252
|
-
)
|
|
250
|
+
raise click.ClickException(f"Multiple {resource_type}s named '{ref}'. Use ID instead.")
|
|
253
251
|
out.append(str(matches[0].id))
|
|
254
252
|
return out
|
|
255
253
|
|
|
@@ -395,15 +393,9 @@ def _resolve_agent(
|
|
|
395
393
|
|
|
396
394
|
|
|
397
395
|
@agents_group.command(name="list")
|
|
398
|
-
@click.option(
|
|
399
|
-
|
|
400
|
-
)
|
|
401
|
-
@click.option(
|
|
402
|
-
"--type", "agent_type", help="Filter by agent type (config, code, a2a, langflow)"
|
|
403
|
-
)
|
|
404
|
-
@click.option(
|
|
405
|
-
"--framework", help="Filter by framework (langchain, langgraph, google_adk)"
|
|
406
|
-
)
|
|
396
|
+
@click.option("--simple", is_flag=True, help="Show simple table without interactive picker")
|
|
397
|
+
@click.option("--type", "agent_type", help="Filter by agent type (config, code, a2a, langflow)")
|
|
398
|
+
@click.option("--framework", help="Filter by framework (langchain, langgraph, google_adk)")
|
|
407
399
|
@click.option("--name", help="Filter by partial name match (case-insensitive)")
|
|
408
400
|
@click.option("--version", help="Filter by exact version match")
|
|
409
401
|
@click.option(
|
|
@@ -482,15 +474,12 @@ def list_agents(
|
|
|
482
474
|
f"{ICON_AGENT} Available Agents",
|
|
483
475
|
columns,
|
|
484
476
|
transform_agent,
|
|
485
|
-
skip_picker=simple
|
|
486
|
-
or any(
|
|
487
|
-
param is not None for param in (agent_type, framework, name, version)
|
|
488
|
-
),
|
|
477
|
+
skip_picker=simple or any(param is not None for param in (agent_type, framework, name, version)),
|
|
489
478
|
use_pager=False,
|
|
490
479
|
)
|
|
491
480
|
|
|
492
481
|
except Exception as e:
|
|
493
|
-
raise click.ClickException(str(e))
|
|
482
|
+
raise click.ClickException(str(e)) from e
|
|
494
483
|
|
|
495
484
|
|
|
496
485
|
@agents_group.command()
|
|
@@ -515,9 +504,7 @@ def get(ctx: Any, agent_ref: str, select: int | None, export: str | None) -> Non
|
|
|
515
504
|
client = get_client(ctx)
|
|
516
505
|
|
|
517
506
|
# Resolve agent with ambiguity handling - use questionary interface for traditional UX
|
|
518
|
-
agent = _resolve_agent(
|
|
519
|
-
ctx, client, agent_ref, select, interface_preference="questionary"
|
|
520
|
-
)
|
|
507
|
+
agent = _resolve_agent(ctx, client, agent_ref, select, interface_preference="questionary")
|
|
521
508
|
|
|
522
509
|
# Handle export option
|
|
523
510
|
if export:
|
|
@@ -536,22 +523,19 @@ def get(ctx: Any, agent_ref: str, select: int | None, export: str | None) -> Non
|
|
|
536
523
|
except Exception as e:
|
|
537
524
|
handle_rich_output(
|
|
538
525
|
ctx,
|
|
539
|
-
markup_text(
|
|
540
|
-
f"[{WARNING_STYLE}]⚠️ Could not fetch full agent details: {e}[/]"
|
|
541
|
-
),
|
|
526
|
+
markup_text(f"[{WARNING_STYLE}]⚠️ Could not fetch full agent details: {e}[/]"),
|
|
542
527
|
)
|
|
543
528
|
handle_rich_output(
|
|
544
529
|
ctx,
|
|
545
|
-
markup_text(
|
|
546
|
-
f"[{WARNING_STYLE}]⚠️ Proceeding with available data[/]"
|
|
547
|
-
),
|
|
530
|
+
markup_text(f"[{WARNING_STYLE}]⚠️ Proceeding with available data[/]"),
|
|
548
531
|
)
|
|
549
532
|
|
|
550
533
|
export_resource_to_file(agent, export_path, detected_format)
|
|
551
534
|
handle_rich_output(
|
|
552
535
|
ctx,
|
|
553
536
|
markup_text(
|
|
554
|
-
f"[{SUCCESS_STYLE}]✅ Complete agent configuration exported to: {export_path}
|
|
537
|
+
f"[{SUCCESS_STYLE}]✅ Complete agent configuration exported to: {export_path} "
|
|
538
|
+
f"(format: {detected_format})[/]"
|
|
555
539
|
),
|
|
556
540
|
)
|
|
557
541
|
|
|
@@ -562,7 +546,7 @@ def get(ctx: Any, agent_ref: str, select: int | None, export: str | None) -> Non
|
|
|
562
546
|
handle_rich_output(ctx, display_agent_run_suggestions(agent))
|
|
563
547
|
|
|
564
548
|
except Exception as e:
|
|
565
|
-
raise click.ClickException(str(e))
|
|
549
|
+
raise click.ClickException(str(e)) from e
|
|
566
550
|
|
|
567
551
|
|
|
568
552
|
def _validate_run_input(input_option: str | None, input_text: str | None) -> str:
|
|
@@ -570,9 +554,7 @@ def _validate_run_input(input_option: str | None, input_text: str | None) -> str
|
|
|
570
554
|
final_input_text = input_option if input_option else input_text
|
|
571
555
|
|
|
572
556
|
if not final_input_text:
|
|
573
|
-
raise click.ClickException(
|
|
574
|
-
"Input text is required. Use either positional argument or --input option."
|
|
575
|
-
)
|
|
557
|
+
raise click.ClickException("Input text is required. Use either positional argument or --input option.")
|
|
576
558
|
|
|
577
559
|
return final_input_text
|
|
578
560
|
|
|
@@ -584,8 +566,8 @@ def _parse_chat_history(chat_history: str | None) -> list[dict[str, Any]] | None
|
|
|
584
566
|
|
|
585
567
|
try:
|
|
586
568
|
return json.loads(chat_history)
|
|
587
|
-
except json.JSONDecodeError:
|
|
588
|
-
raise click.ClickException("Invalid JSON in chat history")
|
|
569
|
+
except json.JSONDecodeError as err:
|
|
570
|
+
raise click.ClickException("Invalid JSON in chat history") from err
|
|
589
571
|
|
|
590
572
|
|
|
591
573
|
def _setup_run_renderer(ctx: Any, save: str | None, verbose: bool) -> Any:
|
|
@@ -665,9 +647,7 @@ def _save_run_transcript(save: str | None, result: Any, working_console: Any) ->
|
|
|
665
647
|
if ext == "json":
|
|
666
648
|
save_data = {
|
|
667
649
|
"output": result or "",
|
|
668
|
-
"full_debug_output": getattr(
|
|
669
|
-
working_console, "get_captured_output", lambda: ""
|
|
670
|
-
)(),
|
|
650
|
+
"full_debug_output": getattr(working_console, "get_captured_output", lambda: "")(),
|
|
671
651
|
"timestamp": "captured during agent execution",
|
|
672
652
|
}
|
|
673
653
|
content = json.dumps(save_data, indent=2)
|
|
@@ -680,9 +660,7 @@ def _save_run_transcript(save: str | None, result: Any, working_console: Any) ->
|
|
|
680
660
|
|
|
681
661
|
with open(save, "w", encoding="utf-8") as f:
|
|
682
662
|
f.write(content)
|
|
683
|
-
print_markup(
|
|
684
|
-
f"[{SUCCESS_STYLE}]Full debug output saved to: {save}[/]", console=console
|
|
685
|
-
)
|
|
663
|
+
print_markup(f"[{SUCCESS_STYLE}]Full debug output saved to: {save}[/]", console=console)
|
|
686
664
|
|
|
687
665
|
|
|
688
666
|
@agents_group.command()
|
|
@@ -745,9 +723,7 @@ def run(
|
|
|
745
723
|
|
|
746
724
|
try:
|
|
747
725
|
client = get_client(ctx)
|
|
748
|
-
agent = _resolve_agent(
|
|
749
|
-
ctx, client, agent_ref, select, interface_preference="fuzzy"
|
|
750
|
-
)
|
|
726
|
+
agent = _resolve_agent(ctx, client, agent_ref, select, interface_preference="fuzzy")
|
|
751
727
|
|
|
752
728
|
parsed_chat_history = _parse_chat_history(chat_history)
|
|
753
729
|
renderer, working_console = _setup_run_renderer(ctx, save, verbose)
|
|
@@ -796,7 +772,7 @@ def run(
|
|
|
796
772
|
except AgentTimeoutError as e:
|
|
797
773
|
error_msg = str(e)
|
|
798
774
|
handle_json_output(ctx, error=Exception(error_msg))
|
|
799
|
-
raise click.ClickException(error_msg)
|
|
775
|
+
raise click.ClickException(error_msg) from e
|
|
800
776
|
except Exception as e:
|
|
801
777
|
_handle_command_exception(ctx, e)
|
|
802
778
|
|
|
@@ -885,16 +861,12 @@ def _extract_and_validate_fields(
|
|
|
885
861
|
if not name:
|
|
886
862
|
raise click.ClickException("Agent name is required (--name or --import)")
|
|
887
863
|
if not instruction:
|
|
888
|
-
raise click.ClickException(
|
|
889
|
-
"Agent instruction is required (--instruction or --import)"
|
|
890
|
-
)
|
|
864
|
+
raise click.ClickException("Agent instruction is required (--instruction or --import)")
|
|
891
865
|
|
|
892
866
|
return name, instruction, model, tools, agents, mcps, timeout
|
|
893
867
|
|
|
894
868
|
|
|
895
|
-
def _validate_and_coerce_fields(
|
|
896
|
-
name: str, instruction: str, timeout: Any
|
|
897
|
-
) -> tuple[str, str, Any]:
|
|
869
|
+
def _validate_and_coerce_fields(name: str, instruction: str, timeout: Any) -> tuple[str, str, Any]:
|
|
898
870
|
"""Validate and coerce field values."""
|
|
899
871
|
name = validate_agent_name(name)
|
|
900
872
|
instruction = validate_agent_instruction(instruction)
|
|
@@ -905,19 +877,11 @@ def _validate_and_coerce_fields(
|
|
|
905
877
|
return name, instruction, timeout
|
|
906
878
|
|
|
907
879
|
|
|
908
|
-
def _resolve_resources(
|
|
909
|
-
client: Any, tools: tuple, agents: tuple, mcps: tuple
|
|
910
|
-
) -> tuple[list, list, list]:
|
|
880
|
+
def _resolve_resources(client: Any, tools: tuple, agents: tuple, mcps: tuple) -> tuple[list, list, list]:
|
|
911
881
|
"""Resolve tool, agent, and MCP references."""
|
|
912
|
-
resolved_tools = _resolve_resources_by_name(
|
|
913
|
-
|
|
914
|
-
)
|
|
915
|
-
resolved_agents = _resolve_resources_by_name(
|
|
916
|
-
client, agents, "agent", client.find_agents, "Agent"
|
|
917
|
-
)
|
|
918
|
-
resolved_mcps = _resolve_resources_by_name(
|
|
919
|
-
client, mcps, "mcp", client.find_mcps, "MCP"
|
|
920
|
-
)
|
|
882
|
+
resolved_tools = _resolve_resources_by_name(client, tools, "tool", client.find_tools, "Tool")
|
|
883
|
+
resolved_agents = _resolve_resources_by_name(client, agents, "agent", client.find_agents, "Agent")
|
|
884
|
+
resolved_mcps = _resolve_resources_by_name(client, mcps, "mcp", client.find_mcps, "MCP")
|
|
921
885
|
|
|
922
886
|
return resolved_tools, resolved_agents, resolved_mcps
|
|
923
887
|
|
|
@@ -944,16 +908,12 @@ def _build_create_kwargs(
|
|
|
944
908
|
}
|
|
945
909
|
|
|
946
910
|
# Handle language model selection
|
|
947
|
-
lm_selection_dict, should_strip_lm_identity = resolve_language_model_selection(
|
|
948
|
-
merged_data, model
|
|
949
|
-
)
|
|
911
|
+
lm_selection_dict, should_strip_lm_identity = resolve_language_model_selection(merged_data, model)
|
|
950
912
|
create_kwargs.update(lm_selection_dict)
|
|
951
913
|
|
|
952
914
|
# Handle import file specific logic
|
|
953
915
|
if import_file:
|
|
954
|
-
_add_import_file_attributes(
|
|
955
|
-
create_kwargs, merged_data, should_strip_lm_identity
|
|
956
|
-
)
|
|
916
|
+
_add_import_file_attributes(create_kwargs, merged_data, should_strip_lm_identity)
|
|
957
917
|
|
|
958
918
|
return create_kwargs
|
|
959
919
|
|
|
@@ -999,12 +959,7 @@ def _get_language_model_display_name(agent: Any, model: str | None) -> str:
|
|
|
999
959
|
lm_display = getattr(agent, "model", None)
|
|
1000
960
|
if not lm_display:
|
|
1001
961
|
cfg = getattr(agent, "agent_config", {}) or {}
|
|
1002
|
-
lm_display = (
|
|
1003
|
-
cfg.get("lm_name")
|
|
1004
|
-
or cfg.get("model")
|
|
1005
|
-
or model
|
|
1006
|
-
or f"{DEFAULT_MODEL} (backend default)"
|
|
1007
|
-
)
|
|
962
|
+
lm_display = cfg.get("lm_name") or cfg.get("model") or model or f"{DEFAULT_MODEL} (backend default)"
|
|
1008
963
|
return lm_display
|
|
1009
964
|
|
|
1010
965
|
|
|
@@ -1039,7 +994,7 @@ def _handle_command_exception(ctx: Any, e: Exception) -> None:
|
|
|
1039
994
|
handle_json_output(ctx, error=e)
|
|
1040
995
|
if get_ctx_value(ctx, "view") != "json":
|
|
1041
996
|
print_api_error(e)
|
|
1042
|
-
raise click.ClickException(str(e))
|
|
997
|
+
raise click.ClickException(str(e)) from e
|
|
1043
998
|
|
|
1044
999
|
|
|
1045
1000
|
def _handle_creation_exception(ctx: Any, e: Exception) -> None:
|
|
@@ -1093,13 +1048,9 @@ def create(
|
|
|
1093
1048
|
|
|
1094
1049
|
# Handle import file or CLI args
|
|
1095
1050
|
if import_file:
|
|
1096
|
-
merged_data = _handle_import_file_logic(
|
|
1097
|
-
import_file, model, name, instruction, tools, agents, mcps, timeout
|
|
1098
|
-
)
|
|
1051
|
+
merged_data = _handle_import_file_logic(import_file, model, name, instruction, tools, agents, mcps, timeout)
|
|
1099
1052
|
else:
|
|
1100
|
-
merged_data = _build_cli_args_data(
|
|
1101
|
-
name, instruction, model, tools, agents, mcps, timeout
|
|
1102
|
-
)
|
|
1053
|
+
merged_data = _build_cli_args_data(name, instruction, model, tools, agents, mcps, timeout)
|
|
1103
1054
|
|
|
1104
1055
|
# Extract and validate fields
|
|
1105
1056
|
(
|
|
@@ -1111,14 +1062,10 @@ def create(
|
|
|
1111
1062
|
mcps,
|
|
1112
1063
|
timeout,
|
|
1113
1064
|
) = _extract_and_validate_fields(merged_data)
|
|
1114
|
-
name, instruction, timeout = _validate_and_coerce_fields(
|
|
1115
|
-
name, instruction, timeout
|
|
1116
|
-
)
|
|
1065
|
+
name, instruction, timeout = _validate_and_coerce_fields(name, instruction, timeout)
|
|
1117
1066
|
|
|
1118
1067
|
# Resolve resources
|
|
1119
|
-
resolved_tools, resolved_agents, resolved_mcps = _resolve_resources(
|
|
1120
|
-
client, tools, agents, mcps
|
|
1121
|
-
)
|
|
1068
|
+
resolved_tools, resolved_agents, resolved_mcps = _resolve_resources(client, tools, agents, mcps)
|
|
1122
1069
|
|
|
1123
1070
|
# Build create kwargs
|
|
1124
1071
|
create_kwargs = _build_create_kwargs(
|
|
@@ -1148,7 +1095,7 @@ def _get_agent_for_update(client: Any, agent_id: str) -> Any:
|
|
|
1148
1095
|
try:
|
|
1149
1096
|
return client.agents.get_agent_by_id(agent_id)
|
|
1150
1097
|
except Exception as e:
|
|
1151
|
-
raise click.ClickException(f"Agent with ID '{agent_id}' not found: {e}")
|
|
1098
|
+
raise click.ClickException(f"Agent with ID '{agent_id}' not found: {e}") from e
|
|
1152
1099
|
|
|
1153
1100
|
|
|
1154
1101
|
def _handle_update_import_file(
|
|
@@ -1230,16 +1177,12 @@ def _handle_update_import_config(
|
|
|
1230
1177
|
if not import_file:
|
|
1231
1178
|
return
|
|
1232
1179
|
|
|
1233
|
-
lm_selection, should_strip_lm_identity = resolve_language_model_selection(
|
|
1234
|
-
merged_data, None
|
|
1235
|
-
)
|
|
1180
|
+
lm_selection, should_strip_lm_identity = resolve_language_model_selection(merged_data, None)
|
|
1236
1181
|
update_data.update(lm_selection)
|
|
1237
1182
|
|
|
1238
1183
|
raw_cfg = merged_data.get("agent_config") if isinstance(merged_data, dict) else None
|
|
1239
1184
|
if isinstance(raw_cfg, dict):
|
|
1240
|
-
update_data["agent_config"] = sanitize_agent_config(
|
|
1241
|
-
raw_cfg, strip_lm_identity=should_strip_lm_identity
|
|
1242
|
-
)
|
|
1185
|
+
update_data["agent_config"] = sanitize_agent_config(raw_cfg, strip_lm_identity=should_strip_lm_identity)
|
|
1243
1186
|
|
|
1244
1187
|
excluded_fields = {
|
|
1245
1188
|
"name",
|
|
@@ -1308,13 +1251,9 @@ def update(
|
|
|
1308
1251
|
agents,
|
|
1309
1252
|
mcps,
|
|
1310
1253
|
timeout,
|
|
1311
|
-
) = _handle_update_import_file(
|
|
1312
|
-
import_file, name, instruction, tools, agents, mcps, timeout
|
|
1313
|
-
)
|
|
1254
|
+
) = _handle_update_import_file(import_file, name, instruction, tools, agents, mcps, timeout)
|
|
1314
1255
|
|
|
1315
|
-
update_data = _build_update_data(
|
|
1316
|
-
name, instruction, tools, agents, mcps, timeout
|
|
1317
|
-
)
|
|
1256
|
+
update_data = _build_update_data(name, instruction, tools, agents, mcps, timeout)
|
|
1318
1257
|
|
|
1319
1258
|
if merged_data:
|
|
1320
1259
|
_handle_update_import_config(import_file, merged_data, update_data)
|
|
@@ -1352,7 +1291,7 @@ def delete(ctx: Any, agent_id: str, yes: bool) -> None:
|
|
|
1352
1291
|
try:
|
|
1353
1292
|
agent = client.agents.get_agent_by_id(agent_id)
|
|
1354
1293
|
except Exception as e:
|
|
1355
|
-
raise click.ClickException(f"Agent with ID '{agent_id}' not found: {e}")
|
|
1294
|
+
raise click.ClickException(f"Agent with ID '{agent_id}' not found: {e}") from e
|
|
1356
1295
|
|
|
1357
1296
|
# Confirm deletion when not forced
|
|
1358
1297
|
if not yes and not display_confirmation_prompt("Agent", agent.name):
|
|
@@ -1384,9 +1323,7 @@ def delete(ctx: Any, agent_id: str, yes: bool) -> None:
|
|
|
1384
1323
|
"--base-url",
|
|
1385
1324
|
help="Custom LangFlow server base URL (overrides LANGFLOW_BASE_URL env var)",
|
|
1386
1325
|
)
|
|
1387
|
-
@click.option(
|
|
1388
|
-
"--api-key", help="Custom LangFlow API key (overrides LANGFLOW_API_KEY env var)"
|
|
1389
|
-
)
|
|
1326
|
+
@click.option("--api-key", help="Custom LangFlow API key (overrides LANGFLOW_API_KEY env var)")
|
|
1390
1327
|
@output_flags()
|
|
1391
1328
|
@click.pass_context
|
|
1392
1329
|
def sync_langflow(ctx: Any, base_url: str | None, api_key: str | None) -> None:
|
|
@@ -1415,15 +1352,16 @@ def sync_langflow(ctx: Any, base_url: str | None, api_key: str | None) -> None:
|
|
|
1415
1352
|
# Show success message for non-JSON output
|
|
1416
1353
|
if get_ctx_value(ctx, "view") != "json":
|
|
1417
1354
|
# Extract some useful info from the result
|
|
1418
|
-
success_count = result.get("data", {}).get("created_count", 0) + result.get(
|
|
1419
|
-
"
|
|
1420
|
-
)
|
|
1355
|
+
success_count = result.get("data", {}).get("created_count", 0) + result.get("data", {}).get(
|
|
1356
|
+
"updated_count", 0
|
|
1357
|
+
)
|
|
1421
1358
|
total_count = result.get("data", {}).get("total_processed", 0)
|
|
1422
1359
|
|
|
1423
1360
|
handle_rich_output(
|
|
1424
1361
|
ctx,
|
|
1425
1362
|
markup_text(
|
|
1426
|
-
f"[{SUCCESS_STYLE}]✅ Successfully synced {success_count} LangFlow agents
|
|
1363
|
+
f"[{SUCCESS_STYLE}]✅ Successfully synced {success_count} LangFlow agents "
|
|
1364
|
+
f"({total_count} total processed)[/]"
|
|
1427
1365
|
),
|
|
1428
1366
|
)
|
|
1429
1367
|
|
|
@@ -57,9 +57,7 @@ def set_config(key: str, value: str) -> None:
|
|
|
57
57
|
valid_keys = ["api_url", "api_key"]
|
|
58
58
|
|
|
59
59
|
if key not in valid_keys:
|
|
60
|
-
console.print(
|
|
61
|
-
f"[{ERROR_STYLE}]Error: Invalid key '{key}'. Valid keys are: {', '.join(valid_keys)}[/]"
|
|
62
|
-
)
|
|
60
|
+
console.print(f"[{ERROR_STYLE}]Error: Invalid key '{key}'. Valid keys are: {', '.join(valid_keys)}[/]")
|
|
63
61
|
raise click.ClickException(f"Invalid configuration key: {key}")
|
|
64
62
|
|
|
65
63
|
config = load_config()
|
|
@@ -67,9 +65,7 @@ def set_config(key: str, value: str) -> None:
|
|
|
67
65
|
save_config(config)
|
|
68
66
|
|
|
69
67
|
if key == "api_key":
|
|
70
|
-
console.print(
|
|
71
|
-
Text(f"✅ Set {key} = {_mask_api_key(value)}", style=SUCCESS_STYLE)
|
|
72
|
-
)
|
|
68
|
+
console.print(Text(f"✅ Set {key} = {_mask_api_key(value)}", style=SUCCESS_STYLE))
|
|
73
69
|
else:
|
|
74
70
|
console.print(Text(f"✅ Set {key} = {value}", style=SUCCESS_STYLE))
|
|
75
71
|
|
|
@@ -81,9 +77,7 @@ def get_config(key: str) -> None:
|
|
|
81
77
|
config = load_config()
|
|
82
78
|
|
|
83
79
|
if key not in config:
|
|
84
|
-
console.print(
|
|
85
|
-
markup_text(f"[{WARNING_STYLE}]Configuration key '{key}' not found.[/]")
|
|
86
|
-
)
|
|
80
|
+
console.print(markup_text(f"[{WARNING_STYLE}]Configuration key '{key}' not found.[/]"))
|
|
87
81
|
raise click.ClickException(f"Configuration key not found: {key}")
|
|
88
82
|
|
|
89
83
|
value = config[key]
|
|
@@ -101,9 +95,7 @@ def unset_config(key: str) -> None:
|
|
|
101
95
|
config = load_config()
|
|
102
96
|
|
|
103
97
|
if key not in config:
|
|
104
|
-
console.print(
|
|
105
|
-
markup_text(f"[{WARNING_STYLE}]Configuration key '{key}' not found.[/]")
|
|
106
|
-
)
|
|
98
|
+
console.print(markup_text(f"[{WARNING_STYLE}]Configuration key '{key}' not found.[/]"))
|
|
107
99
|
return
|
|
108
100
|
|
|
109
101
|
del config[key]
|
|
@@ -128,9 +120,7 @@ def reset_config(force: bool) -> None:
|
|
|
128
120
|
|
|
129
121
|
if not file_exists and not config_data:
|
|
130
122
|
console.print(f"[{WARNING_STYLE}]No configuration found to reset.[/]")
|
|
131
|
-
console.print(
|
|
132
|
-
Text("✅ Configuration reset (nothing to remove).", style=SUCCESS_STYLE)
|
|
133
|
-
)
|
|
123
|
+
console.print(Text("✅ Configuration reset (nothing to remove).", style=SUCCESS_STYLE))
|
|
134
124
|
return
|
|
135
125
|
|
|
136
126
|
if file_exists:
|
|
@@ -188,9 +178,7 @@ def _mask_api_key(value: str | None) -> str:
|
|
|
188
178
|
def _print_missing_config_hint() -> None:
|
|
189
179
|
hint = command_hint("config configure", slash_command="login")
|
|
190
180
|
if hint:
|
|
191
|
-
console.print(
|
|
192
|
-
f"[{WARNING_STYLE}]No configuration found.[/] Run {format_command_hint(hint) or hint} to set up."
|
|
193
|
-
)
|
|
181
|
+
console.print(f"[{WARNING_STYLE}]No configuration found.[/] Run {format_command_hint(hint) or hint} to set up.")
|
|
194
182
|
else:
|
|
195
183
|
console.print(f"[{WARNING_STYLE}]No configuration found.[/]")
|
|
196
184
|
|
|
@@ -208,9 +196,7 @@ def _render_config_table(config: dict[str, str]) -> None:
|
|
|
208
196
|
|
|
209
197
|
|
|
210
198
|
def _render_configuration_header() -> None:
|
|
211
|
-
branding = AIPBranding.create_from_sdk(
|
|
212
|
-
sdk_version=_SDK_VERSION, package_name="glaip-sdk"
|
|
213
|
-
)
|
|
199
|
+
branding = AIPBranding.create_from_sdk(sdk_version=_SDK_VERSION, package_name="glaip-sdk")
|
|
214
200
|
heading = "[bold]>_ GDP Labs AI Agents Package (AIP CLI)[/bold]"
|
|
215
201
|
console.print(heading)
|
|
216
202
|
console.print()
|
|
@@ -249,9 +235,7 @@ def _prompt_api_key(config: dict[str, str]) -> None:
|
|
|
249
235
|
|
|
250
236
|
def _save_configuration(config: dict[str, str]) -> None:
|
|
251
237
|
save_config(config)
|
|
252
|
-
console.print(
|
|
253
|
-
Text(f"\n✅ Configuration saved to: {CONFIG_FILE}", style=SUCCESS_STYLE)
|
|
254
|
-
)
|
|
238
|
+
console.print(Text(f"\n✅ Configuration saved to: {CONFIG_FILE}", style=SUCCESS_STYLE))
|
|
255
239
|
|
|
256
240
|
|
|
257
241
|
def _test_and_report_connection(config: dict[str, str]) -> None:
|
|
@@ -274,17 +258,13 @@ def _test_and_report_connection(config: dict[str, str]) -> None:
|
|
|
274
258
|
style=WARNING_STYLE,
|
|
275
259
|
)
|
|
276
260
|
)
|
|
277
|
-
console.print(
|
|
278
|
-
" You may need to check your API permissions or network access"
|
|
279
|
-
)
|
|
261
|
+
console.print(" You may need to check your API permissions or network access")
|
|
280
262
|
except Exception as exc:
|
|
281
263
|
console.print(Text(f"❌ Connection failed: {exc}"))
|
|
282
264
|
console.print(" Please check your API URL and key")
|
|
283
265
|
hint_status = command_hint("status", slash_command="status")
|
|
284
266
|
if hint_status:
|
|
285
|
-
console.print(
|
|
286
|
-
f" You can run {format_command_hint(hint_status) or hint_status} later to test again"
|
|
287
|
-
)
|
|
267
|
+
console.print(f" You can run {format_command_hint(hint_status) or hint_status} later to test again")
|
|
288
268
|
finally:
|
|
289
269
|
if client is not None:
|
|
290
270
|
client.close()
|
|
@@ -294,11 +274,7 @@ def _print_post_configuration_hints() -> None:
|
|
|
294
274
|
console.print("\n💡 You can now use AIP CLI commands!")
|
|
295
275
|
hint_status = command_hint("status", slash_command="status")
|
|
296
276
|
if hint_status:
|
|
297
|
-
console.print(
|
|
298
|
-
f" • Run {format_command_hint(hint_status) or hint_status} to check connection"
|
|
299
|
-
)
|
|
277
|
+
console.print(f" • Run {format_command_hint(hint_status) or hint_status} to check connection")
|
|
300
278
|
hint_agents = command_hint("agents list", slash_command="agents")
|
|
301
279
|
if hint_agents:
|
|
302
|
-
console.print(
|
|
303
|
-
f" • Run {format_command_hint(hint_agents) or hint_agents} to see your agents"
|
|
304
|
-
)
|
|
280
|
+
console.print(f" • Run {format_command_hint(hint_agents) or hint_agents} to see your agents")
|