glaip-sdk 0.1.0__py3-none-any.whl → 0.1.1__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.
Files changed (63) hide show
  1. glaip_sdk/_version.py +1 -3
  2. glaip_sdk/branding.py +2 -6
  3. glaip_sdk/cli/agent_config.py +2 -6
  4. glaip_sdk/cli/auth.py +11 -30
  5. glaip_sdk/cli/commands/agents.py +45 -107
  6. glaip_sdk/cli/commands/configure.py +12 -36
  7. glaip_sdk/cli/commands/mcps.py +26 -63
  8. glaip_sdk/cli/commands/models.py +2 -4
  9. glaip_sdk/cli/commands/tools.py +22 -35
  10. glaip_sdk/cli/commands/update.py +3 -8
  11. glaip_sdk/cli/config.py +1 -3
  12. glaip_sdk/cli/display.py +4 -12
  13. glaip_sdk/cli/io.py +8 -14
  14. glaip_sdk/cli/main.py +10 -30
  15. glaip_sdk/cli/mcp_validators.py +5 -15
  16. glaip_sdk/cli/pager.py +3 -9
  17. glaip_sdk/cli/parsers/json_input.py +11 -22
  18. glaip_sdk/cli/resolution.py +3 -9
  19. glaip_sdk/cli/rich_helpers.py +1 -3
  20. glaip_sdk/cli/slash/agent_session.py +5 -10
  21. glaip_sdk/cli/slash/prompt.py +3 -10
  22. glaip_sdk/cli/slash/session.py +46 -95
  23. glaip_sdk/cli/transcript/cache.py +6 -19
  24. glaip_sdk/cli/transcript/capture.py +6 -20
  25. glaip_sdk/cli/transcript/launcher.py +1 -3
  26. glaip_sdk/cli/transcript/viewer.py +11 -40
  27. glaip_sdk/cli/update_notifier.py +165 -21
  28. glaip_sdk/cli/utils.py +33 -84
  29. glaip_sdk/cli/validators.py +11 -12
  30. glaip_sdk/client/_agent_payloads.py +10 -30
  31. glaip_sdk/client/agents.py +33 -63
  32. glaip_sdk/client/base.py +6 -22
  33. glaip_sdk/client/mcps.py +1 -3
  34. glaip_sdk/client/run_rendering.py +6 -14
  35. glaip_sdk/client/tools.py +8 -24
  36. glaip_sdk/client/validators.py +20 -48
  37. glaip_sdk/exceptions.py +1 -3
  38. glaip_sdk/models.py +14 -33
  39. glaip_sdk/payload_schemas/agent.py +1 -3
  40. glaip_sdk/utils/agent_config.py +4 -14
  41. glaip_sdk/utils/client_utils.py +7 -21
  42. glaip_sdk/utils/display.py +2 -6
  43. glaip_sdk/utils/general.py +1 -3
  44. glaip_sdk/utils/import_export.py +3 -9
  45. glaip_sdk/utils/rendering/formatting.py +2 -5
  46. glaip_sdk/utils/rendering/models.py +2 -6
  47. glaip_sdk/utils/rendering/renderer/__init__.py +1 -3
  48. glaip_sdk/utils/rendering/renderer/base.py +63 -189
  49. glaip_sdk/utils/rendering/renderer/debug.py +4 -14
  50. glaip_sdk/utils/rendering/renderer/panels.py +1 -3
  51. glaip_sdk/utils/rendering/renderer/progress.py +3 -11
  52. glaip_sdk/utils/rendering/renderer/stream.py +7 -19
  53. glaip_sdk/utils/rendering/renderer/toggle.py +1 -3
  54. glaip_sdk/utils/rendering/step_tree_state.py +1 -3
  55. glaip_sdk/utils/rendering/steps.py +29 -83
  56. glaip_sdk/utils/resource_refs.py +4 -13
  57. glaip_sdk/utils/serialization.py +14 -46
  58. glaip_sdk/utils/validation.py +4 -4
  59. {glaip_sdk-0.1.0.dist-info → glaip_sdk-0.1.1.dist-info}/METADATA +1 -1
  60. glaip_sdk-0.1.1.dist-info/RECORD +82 -0
  61. glaip_sdk-0.1.0.dist-info/RECORD +0 -82
  62. {glaip_sdk-0.1.0.dist-info → glaip_sdk-0.1.1.dist-info}/WHEEL +0 -0
  63. {glaip_sdk-0.1.0.dist-info → glaip_sdk-0.1.1.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:
@@ -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 if you want to update these credentials."
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
@@ -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
- "--simple", is_flag=True, help="Show simple table without interactive picker"
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} (format: {detected_format})[/]"
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
- client, tools, "tool", client.find_tools, "Tool"
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
- "data", {}
1420
- ).get("updated_count", 0)
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 ({total_count} total processed)[/]"
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")