glaip-sdk 0.6.19__py3-none-any.whl → 0.7.27__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 (135) hide show
  1. glaip_sdk/agents/base.py +283 -30
  2. glaip_sdk/agents/component.py +233 -0
  3. glaip_sdk/branding.py +113 -2
  4. glaip_sdk/cli/account_store.py +15 -0
  5. glaip_sdk/cli/auth.py +14 -8
  6. glaip_sdk/cli/commands/accounts.py +1 -1
  7. glaip_sdk/cli/commands/agents/__init__.py +116 -0
  8. glaip_sdk/cli/commands/agents/_common.py +562 -0
  9. glaip_sdk/cli/commands/agents/create.py +155 -0
  10. glaip_sdk/cli/commands/agents/delete.py +64 -0
  11. glaip_sdk/cli/commands/agents/get.py +89 -0
  12. glaip_sdk/cli/commands/agents/list.py +129 -0
  13. glaip_sdk/cli/commands/agents/run.py +264 -0
  14. glaip_sdk/cli/commands/agents/sync_langflow.py +72 -0
  15. glaip_sdk/cli/commands/agents/update.py +112 -0
  16. glaip_sdk/cli/commands/common_config.py +1 -1
  17. glaip_sdk/cli/commands/configure.py +1 -2
  18. glaip_sdk/cli/commands/mcps/__init__.py +94 -0
  19. glaip_sdk/cli/commands/mcps/_common.py +459 -0
  20. glaip_sdk/cli/commands/mcps/connect.py +82 -0
  21. glaip_sdk/cli/commands/mcps/create.py +152 -0
  22. glaip_sdk/cli/commands/mcps/delete.py +73 -0
  23. glaip_sdk/cli/commands/mcps/get.py +212 -0
  24. glaip_sdk/cli/commands/mcps/list.py +69 -0
  25. glaip_sdk/cli/commands/mcps/tools.py +235 -0
  26. glaip_sdk/cli/commands/mcps/update.py +190 -0
  27. glaip_sdk/cli/commands/models.py +2 -4
  28. glaip_sdk/cli/commands/shared/__init__.py +21 -0
  29. glaip_sdk/cli/commands/shared/formatters.py +91 -0
  30. glaip_sdk/cli/commands/tools/__init__.py +69 -0
  31. glaip_sdk/cli/commands/tools/_common.py +80 -0
  32. glaip_sdk/cli/commands/tools/create.py +228 -0
  33. glaip_sdk/cli/commands/tools/delete.py +61 -0
  34. glaip_sdk/cli/commands/tools/get.py +103 -0
  35. glaip_sdk/cli/commands/tools/list.py +69 -0
  36. glaip_sdk/cli/commands/tools/script.py +49 -0
  37. glaip_sdk/cli/commands/tools/update.py +102 -0
  38. glaip_sdk/cli/commands/transcripts/__init__.py +90 -0
  39. glaip_sdk/cli/commands/transcripts/_common.py +9 -0
  40. glaip_sdk/cli/commands/transcripts/clear.py +5 -0
  41. glaip_sdk/cli/commands/transcripts/detail.py +5 -0
  42. glaip_sdk/cli/commands/{transcripts.py → transcripts_original.py} +2 -1
  43. glaip_sdk/cli/commands/update.py +163 -17
  44. glaip_sdk/cli/config.py +1 -0
  45. glaip_sdk/cli/entrypoint.py +20 -0
  46. glaip_sdk/cli/main.py +112 -35
  47. glaip_sdk/cli/pager.py +3 -3
  48. glaip_sdk/cli/resolution.py +2 -1
  49. glaip_sdk/cli/slash/accounts_controller.py +3 -1
  50. glaip_sdk/cli/slash/agent_session.py +1 -1
  51. glaip_sdk/cli/slash/remote_runs_controller.py +3 -1
  52. glaip_sdk/cli/slash/session.py +343 -20
  53. glaip_sdk/cli/slash/tui/__init__.py +29 -1
  54. glaip_sdk/cli/slash/tui/accounts.tcss +97 -6
  55. glaip_sdk/cli/slash/tui/accounts_app.py +1117 -126
  56. glaip_sdk/cli/slash/tui/clipboard.py +316 -0
  57. glaip_sdk/cli/slash/tui/context.py +92 -0
  58. glaip_sdk/cli/slash/tui/indicators.py +341 -0
  59. glaip_sdk/cli/slash/tui/keybind_registry.py +235 -0
  60. glaip_sdk/cli/slash/tui/layouts/__init__.py +14 -0
  61. glaip_sdk/cli/slash/tui/layouts/harlequin.py +184 -0
  62. glaip_sdk/cli/slash/tui/loading.py +43 -21
  63. glaip_sdk/cli/slash/tui/remote_runs_app.py +178 -20
  64. glaip_sdk/cli/slash/tui/terminal.py +407 -0
  65. glaip_sdk/cli/slash/tui/theme/__init__.py +15 -0
  66. glaip_sdk/cli/slash/tui/theme/catalog.py +79 -0
  67. glaip_sdk/cli/slash/tui/theme/manager.py +112 -0
  68. glaip_sdk/cli/slash/tui/theme/tokens.py +55 -0
  69. glaip_sdk/cli/slash/tui/toast.py +388 -0
  70. glaip_sdk/cli/transcript/history.py +1 -1
  71. glaip_sdk/cli/transcript/viewer.py +1 -1
  72. glaip_sdk/cli/tui_settings.py +125 -0
  73. glaip_sdk/cli/update_notifier.py +215 -7
  74. glaip_sdk/cli/validators.py +1 -1
  75. glaip_sdk/client/__init__.py +2 -1
  76. glaip_sdk/client/_schedule_payloads.py +89 -0
  77. glaip_sdk/client/agents.py +293 -17
  78. glaip_sdk/client/base.py +25 -0
  79. glaip_sdk/client/hitl.py +136 -0
  80. glaip_sdk/client/main.py +7 -5
  81. glaip_sdk/client/mcps.py +44 -13
  82. glaip_sdk/client/payloads/agent/__init__.py +23 -0
  83. glaip_sdk/client/{_agent_payloads.py → payloads/agent/requests.py} +28 -48
  84. glaip_sdk/client/payloads/agent/responses.py +43 -0
  85. glaip_sdk/client/run_rendering.py +109 -30
  86. glaip_sdk/client/schedules.py +439 -0
  87. glaip_sdk/client/tools.py +52 -23
  88. glaip_sdk/config/constants.py +22 -2
  89. glaip_sdk/guardrails/__init__.py +80 -0
  90. glaip_sdk/guardrails/serializer.py +91 -0
  91. glaip_sdk/hitl/__init__.py +35 -2
  92. glaip_sdk/hitl/base.py +64 -0
  93. glaip_sdk/hitl/callback.py +43 -0
  94. glaip_sdk/hitl/local.py +1 -31
  95. glaip_sdk/hitl/remote.py +523 -0
  96. glaip_sdk/models/__init__.py +47 -1
  97. glaip_sdk/models/_provider_mappings.py +101 -0
  98. glaip_sdk/models/_validation.py +97 -0
  99. glaip_sdk/models/agent.py +2 -1
  100. glaip_sdk/models/agent_runs.py +2 -1
  101. glaip_sdk/models/constants.py +141 -0
  102. glaip_sdk/models/model.py +170 -0
  103. glaip_sdk/models/schedule.py +224 -0
  104. glaip_sdk/payload_schemas/agent.py +1 -0
  105. glaip_sdk/payload_schemas/guardrails.py +34 -0
  106. glaip_sdk/ptc.py +145 -0
  107. glaip_sdk/registry/tool.py +270 -57
  108. glaip_sdk/runner/__init__.py +20 -3
  109. glaip_sdk/runner/deps.py +4 -1
  110. glaip_sdk/runner/langgraph.py +251 -27
  111. glaip_sdk/runner/logging_config.py +77 -0
  112. glaip_sdk/runner/mcp_adapter/mcp_config_builder.py +30 -9
  113. glaip_sdk/runner/ptc_adapter.py +98 -0
  114. glaip_sdk/runner/tool_adapter/langchain_tool_adapter.py +25 -2
  115. glaip_sdk/schedules/__init__.py +22 -0
  116. glaip_sdk/schedules/base.py +291 -0
  117. glaip_sdk/tools/base.py +67 -14
  118. glaip_sdk/utils/__init__.py +1 -0
  119. glaip_sdk/utils/agent_config.py +8 -2
  120. glaip_sdk/utils/bundler.py +138 -2
  121. glaip_sdk/utils/import_resolver.py +427 -49
  122. glaip_sdk/utils/runtime_config.py +3 -2
  123. glaip_sdk/utils/sync.py +31 -11
  124. glaip_sdk/utils/tool_detection.py +274 -6
  125. {glaip_sdk-0.6.19.dist-info → glaip_sdk-0.7.27.dist-info}/METADATA +22 -8
  126. glaip_sdk-0.7.27.dist-info/RECORD +227 -0
  127. {glaip_sdk-0.6.19.dist-info → glaip_sdk-0.7.27.dist-info}/WHEEL +1 -1
  128. glaip_sdk-0.7.27.dist-info/entry_points.txt +2 -0
  129. glaip_sdk/cli/commands/agents.py +0 -1509
  130. glaip_sdk/cli/commands/mcps.py +0 -1356
  131. glaip_sdk/cli/commands/tools.py +0 -576
  132. glaip_sdk/cli/utils.py +0 -263
  133. glaip_sdk-0.6.19.dist-info/RECORD +0 -163
  134. glaip_sdk-0.6.19.dist-info/entry_points.txt +0 -2
  135. {glaip_sdk-0.6.19.dist-info → glaip_sdk-0.7.27.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,91 @@
1
+ """Guardrail serialization logic.
2
+
3
+ This module provides functionality to serialize GuardrailManager and its engines
4
+ into the JSON format expected by the GL AIP backend. This keeps the serialization
5
+ logic within the SDK rather than polluting the core aip-agents logic.
6
+
7
+ Authors:
8
+ Christian Trisno Sen Long Chen (christian.t.s.l.chen@gdplabs.id)
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ from typing import TYPE_CHECKING, Any
14
+
15
+ if TYPE_CHECKING:
16
+ from glaip_sdk.guardrails import (
17
+ GuardrailManager,
18
+ NemoGuardrailEngine,
19
+ PhraseMatcherEngine,
20
+ )
21
+
22
+
23
+ def _serialize_phrase_matcher(engine: PhraseMatcherEngine) -> dict[str, Any]:
24
+ """Serialize a PhraseMatcherEngine configuration."""
25
+ config: dict[str, Any] = {}
26
+
27
+ # Extract config from BaseGuardrailEngineConfig
28
+ if hasattr(engine, "config") and engine.config:
29
+ config.update(engine.config.model_dump())
30
+
31
+ # Extract specific fields
32
+ if hasattr(engine, "banned_phrases"):
33
+ config["banned_phrases"] = engine.banned_phrases
34
+
35
+ return config
36
+
37
+
38
+ def _serialize_nemo(engine: NemoGuardrailEngine) -> dict[str, Any]:
39
+ """Serialize a NemoGuardrailEngine configuration."""
40
+ config: dict[str, Any] = {}
41
+
42
+ # Extract config from BaseGuardrailEngineConfig
43
+ if hasattr(engine, "config") and engine.config:
44
+ config.update(engine.config.model_dump())
45
+
46
+ # Extract specific fields
47
+ nemo_fields = [
48
+ "topic_safety_mode",
49
+ "allowed_topics",
50
+ "denied_topics",
51
+ "include_core_restrictions",
52
+ "core_restriction_categories",
53
+ "config_dict",
54
+ "denial_phrases",
55
+ ]
56
+ for field in nemo_fields:
57
+ if hasattr(engine, field):
58
+ val = getattr(engine, field)
59
+ if val is not None:
60
+ config[field] = val
61
+
62
+ return config
63
+
64
+
65
+ def serialize_guardrail_manager(manager: GuardrailManager) -> dict[str, Any]:
66
+ """Serialize a GuardrailManager into the backend JSON format.
67
+
68
+ Args:
69
+ manager: The GuardrailManager instance to serialize.
70
+
71
+ Returns:
72
+ A dictionary matching the agent_config.guardrails schema.
73
+ """
74
+ try:
75
+ from glaip_sdk.guardrails import NemoGuardrailEngine, PhraseMatcherEngine # noqa: PLC0415
76
+ except ImportError:
77
+ enabled = getattr(manager, "enabled", True)
78
+ return {"enabled": enabled, "engines": []}
79
+
80
+ engines_config = []
81
+
82
+ if hasattr(manager, "engines"):
83
+ for engine in manager.engines:
84
+ if isinstance(engine, PhraseMatcherEngine):
85
+ engines_config.append({"type": "phrase_matcher", "config": _serialize_phrase_matcher(engine)})
86
+ elif isinstance(engine, NemoGuardrailEngine):
87
+ engines_config.append({"type": "nemo", "config": _serialize_nemo(engine)})
88
+ # Unknown engines are skipped.
89
+
90
+ enabled = getattr(manager, "enabled", True)
91
+ return {"enabled": enabled, "engines": engines_config}
@@ -6,10 +6,43 @@ and remote agent execution modes.
6
6
  For local development, LocalPromptHandler is automatically injected when
7
7
  agent_config.hitl_enabled is True. No manual setup required.
8
8
 
9
+ For remote execution, use RemoteHITLHandler to handle HITL events programmatically.
10
+
9
11
  Authors:
10
12
  Putu Ravindra Wiguna (putu.r.wiguna@gdplabs.id)
13
+ GLAIP SDK Team
11
14
  """
12
15
 
13
- from glaip_sdk.hitl.local import LocalPromptHandler, PauseResumeCallback
16
+ from typing import TYPE_CHECKING, Any
17
+
18
+ # These don't require aip_agents, so import them directly
19
+ from glaip_sdk.hitl.base import HITLCallback, HITLDecision, HITLRequest, HITLResponse
20
+ from glaip_sdk.hitl.callback import PauseResumeCallback
21
+ from glaip_sdk.hitl.remote import RemoteHITLHandler
22
+
23
+ if TYPE_CHECKING:
24
+ from glaip_sdk.hitl.local import LocalPromptHandler
25
+
26
+ __all__ = [
27
+ "LocalPromptHandler",
28
+ "PauseResumeCallback",
29
+ "HITLCallback",
30
+ "HITLDecision",
31
+ "HITLRequest",
32
+ "HITLResponse",
33
+ "RemoteHITLHandler",
34
+ ]
35
+
36
+
37
+ def __getattr__(name: str) -> Any: # noqa: ANN401
38
+ """Lazy import for LocalPromptHandler.
39
+
40
+ This defers the import of aip_agents until LocalPromptHandler is actually accessed,
41
+ preventing ImportError when aip-agents is not installed but HITL is not being used.
42
+ """
43
+ if name == "LocalPromptHandler":
44
+ from glaip_sdk.hitl.local import LocalPromptHandler # noqa: PLC0415
14
45
 
15
- __all__ = ["LocalPromptHandler", "PauseResumeCallback"]
46
+ globals()["LocalPromptHandler"] = LocalPromptHandler
47
+ return LocalPromptHandler
48
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
glaip_sdk/hitl/base.py ADDED
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env python3
2
+ """Base types for HITL approval handling.
3
+
4
+ Authors:
5
+ GLAIP SDK Team
6
+ """
7
+
8
+ from dataclasses import dataclass
9
+ from enum import Enum
10
+ from typing import Any, Protocol, runtime_checkable
11
+
12
+
13
+ class HITLDecision(str, Enum):
14
+ """HITL decision types."""
15
+
16
+ APPROVED = "approved"
17
+ REJECTED = "rejected"
18
+ SKIPPED = "skipped"
19
+
20
+
21
+ @dataclass
22
+ class HITLRequest:
23
+ """HITL approval request from SSE stream."""
24
+
25
+ request_id: str
26
+ tool_name: str
27
+ tool_args: dict[str, Any]
28
+ timeout_at: str # ISO 8601, authoritative deadline
29
+ timeout_seconds: int # Informational, fallback only
30
+
31
+ # Raw metadata for advanced use cases
32
+ hitl_metadata: dict[str, Any]
33
+ tool_metadata: dict[str, Any]
34
+
35
+
36
+ @dataclass
37
+ class HITLResponse:
38
+ """HITL decision response."""
39
+
40
+ decision: HITLDecision
41
+ operator_input: str | None = None
42
+
43
+
44
+ @runtime_checkable
45
+ class HITLCallback(Protocol):
46
+ """Protocol for HITL approval callbacks.
47
+
48
+ Callbacks should complete within the computed callback timeout.
49
+ Callbacks should handle exceptions internally or let them propagate.
50
+ """
51
+
52
+ def __call__(self, request: HITLRequest) -> HITLResponse:
53
+ """Handle HITL approval request.
54
+
55
+ Args:
56
+ request: HITL request with tool info and metadata
57
+
58
+ Returns:
59
+ HITLResponse with decision and optional operator input
60
+
61
+ Raises:
62
+ Any exception will be caught, logged, and treated as REJECTED.
63
+ """
64
+ ...
@@ -0,0 +1,43 @@
1
+ """Pause/resume callback for HITL renderer control.
2
+
3
+ This module provides PauseResumeCallback which allows HITL prompt handlers
4
+ to control the live renderer without directly coupling to the renderer implementation.
5
+
6
+ Author:
7
+ Putu Ravindra Wiguna (putu.r.wiguna@gdplabs.id)
8
+ """
9
+
10
+ from typing import Any
11
+
12
+
13
+ class PauseResumeCallback:
14
+ """Simple callback object for pausing/resuming the live renderer.
15
+
16
+ This allows the LocalPromptHandler to control the renderer without
17
+ directly coupling to the renderer implementation.
18
+ """
19
+
20
+ def __init__(self) -> None:
21
+ """Initialize the callback."""
22
+ self._renderer: Any | None = None
23
+
24
+ def set_renderer(self, renderer: Any) -> None:
25
+ """Set the renderer instance.
26
+
27
+ Args:
28
+ renderer: RichStreamRenderer instance with pause_live() and resume_live() methods.
29
+ """
30
+ self._renderer = renderer
31
+
32
+ def pause(self) -> None:
33
+ """Pause the live renderer before prompting."""
34
+ if self._renderer and hasattr(self._renderer, "_shutdown_live"):
35
+ self._renderer._shutdown_live()
36
+
37
+ def resume(self) -> None:
38
+ """Resume the live renderer after prompting."""
39
+ if self._renderer and hasattr(self._renderer, "_ensure_live"):
40
+ self._renderer._ensure_live()
41
+
42
+
43
+ __all__ = ["PauseResumeCallback"]
glaip_sdk/hitl/local.py CHANGED
@@ -118,34 +118,4 @@ class LocalPromptHandler(BasePromptHandler):
118
118
  self._console.print(f"[dim]Context: {request.context}[/dim]")
119
119
 
120
120
 
121
- class PauseResumeCallback:
122
- """Simple callback object for pausing/resuming the live renderer.
123
-
124
- This allows the LocalPromptHandler to control the renderer without
125
- directly coupling to the renderer implementation.
126
- """
127
-
128
- def __init__(self) -> None:
129
- """Initialize the callback."""
130
- self._renderer: Any | None = None
131
-
132
- def set_renderer(self, renderer: Any) -> None:
133
- """Set the renderer instance.
134
-
135
- Args:
136
- renderer: RichStreamRenderer instance with pause_live() and resume_live() methods.
137
- """
138
- self._renderer = renderer
139
-
140
- def pause(self) -> None:
141
- """Pause the live renderer before prompting."""
142
- if self._renderer and hasattr(self._renderer, "_shutdown_live"):
143
- self._renderer._shutdown_live()
144
-
145
- def resume(self) -> None:
146
- """Resume the live renderer after prompting."""
147
- if self._renderer and hasattr(self._renderer, "_ensure_live"):
148
- self._renderer._ensure_live()
149
-
150
-
151
- __all__ = ["LocalPromptHandler", "PauseResumeCallback"]
121
+ __all__ = ["LocalPromptHandler"]