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.
- glaip_sdk/agents/base.py +283 -30
- glaip_sdk/agents/component.py +233 -0
- glaip_sdk/branding.py +113 -2
- glaip_sdk/cli/account_store.py +15 -0
- glaip_sdk/cli/auth.py +14 -8
- glaip_sdk/cli/commands/accounts.py +1 -1
- glaip_sdk/cli/commands/agents/__init__.py +116 -0
- glaip_sdk/cli/commands/agents/_common.py +562 -0
- glaip_sdk/cli/commands/agents/create.py +155 -0
- glaip_sdk/cli/commands/agents/delete.py +64 -0
- glaip_sdk/cli/commands/agents/get.py +89 -0
- glaip_sdk/cli/commands/agents/list.py +129 -0
- glaip_sdk/cli/commands/agents/run.py +264 -0
- glaip_sdk/cli/commands/agents/sync_langflow.py +72 -0
- glaip_sdk/cli/commands/agents/update.py +112 -0
- glaip_sdk/cli/commands/common_config.py +1 -1
- glaip_sdk/cli/commands/configure.py +1 -2
- glaip_sdk/cli/commands/mcps/__init__.py +94 -0
- glaip_sdk/cli/commands/mcps/_common.py +459 -0
- glaip_sdk/cli/commands/mcps/connect.py +82 -0
- glaip_sdk/cli/commands/mcps/create.py +152 -0
- glaip_sdk/cli/commands/mcps/delete.py +73 -0
- glaip_sdk/cli/commands/mcps/get.py +212 -0
- glaip_sdk/cli/commands/mcps/list.py +69 -0
- glaip_sdk/cli/commands/mcps/tools.py +235 -0
- glaip_sdk/cli/commands/mcps/update.py +190 -0
- glaip_sdk/cli/commands/models.py +2 -4
- glaip_sdk/cli/commands/shared/__init__.py +21 -0
- glaip_sdk/cli/commands/shared/formatters.py +91 -0
- glaip_sdk/cli/commands/tools/__init__.py +69 -0
- glaip_sdk/cli/commands/tools/_common.py +80 -0
- glaip_sdk/cli/commands/tools/create.py +228 -0
- glaip_sdk/cli/commands/tools/delete.py +61 -0
- glaip_sdk/cli/commands/tools/get.py +103 -0
- glaip_sdk/cli/commands/tools/list.py +69 -0
- glaip_sdk/cli/commands/tools/script.py +49 -0
- glaip_sdk/cli/commands/tools/update.py +102 -0
- glaip_sdk/cli/commands/transcripts/__init__.py +90 -0
- glaip_sdk/cli/commands/transcripts/_common.py +9 -0
- glaip_sdk/cli/commands/transcripts/clear.py +5 -0
- glaip_sdk/cli/commands/transcripts/detail.py +5 -0
- glaip_sdk/cli/commands/{transcripts.py → transcripts_original.py} +2 -1
- glaip_sdk/cli/commands/update.py +163 -17
- glaip_sdk/cli/config.py +1 -0
- glaip_sdk/cli/entrypoint.py +20 -0
- glaip_sdk/cli/main.py +112 -35
- glaip_sdk/cli/pager.py +3 -3
- glaip_sdk/cli/resolution.py +2 -1
- glaip_sdk/cli/slash/accounts_controller.py +3 -1
- glaip_sdk/cli/slash/agent_session.py +1 -1
- glaip_sdk/cli/slash/remote_runs_controller.py +3 -1
- glaip_sdk/cli/slash/session.py +343 -20
- glaip_sdk/cli/slash/tui/__init__.py +29 -1
- glaip_sdk/cli/slash/tui/accounts.tcss +97 -6
- glaip_sdk/cli/slash/tui/accounts_app.py +1117 -126
- glaip_sdk/cli/slash/tui/clipboard.py +316 -0
- glaip_sdk/cli/slash/tui/context.py +92 -0
- glaip_sdk/cli/slash/tui/indicators.py +341 -0
- glaip_sdk/cli/slash/tui/keybind_registry.py +235 -0
- glaip_sdk/cli/slash/tui/layouts/__init__.py +14 -0
- glaip_sdk/cli/slash/tui/layouts/harlequin.py +184 -0
- glaip_sdk/cli/slash/tui/loading.py +43 -21
- glaip_sdk/cli/slash/tui/remote_runs_app.py +178 -20
- glaip_sdk/cli/slash/tui/terminal.py +407 -0
- glaip_sdk/cli/slash/tui/theme/__init__.py +15 -0
- glaip_sdk/cli/slash/tui/theme/catalog.py +79 -0
- glaip_sdk/cli/slash/tui/theme/manager.py +112 -0
- glaip_sdk/cli/slash/tui/theme/tokens.py +55 -0
- glaip_sdk/cli/slash/tui/toast.py +388 -0
- glaip_sdk/cli/transcript/history.py +1 -1
- glaip_sdk/cli/transcript/viewer.py +1 -1
- glaip_sdk/cli/tui_settings.py +125 -0
- glaip_sdk/cli/update_notifier.py +215 -7
- glaip_sdk/cli/validators.py +1 -1
- glaip_sdk/client/__init__.py +2 -1
- glaip_sdk/client/_schedule_payloads.py +89 -0
- glaip_sdk/client/agents.py +293 -17
- glaip_sdk/client/base.py +25 -0
- glaip_sdk/client/hitl.py +136 -0
- glaip_sdk/client/main.py +7 -5
- glaip_sdk/client/mcps.py +44 -13
- glaip_sdk/client/payloads/agent/__init__.py +23 -0
- glaip_sdk/client/{_agent_payloads.py → payloads/agent/requests.py} +28 -48
- glaip_sdk/client/payloads/agent/responses.py +43 -0
- glaip_sdk/client/run_rendering.py +109 -30
- glaip_sdk/client/schedules.py +439 -0
- glaip_sdk/client/tools.py +52 -23
- glaip_sdk/config/constants.py +22 -2
- glaip_sdk/guardrails/__init__.py +80 -0
- glaip_sdk/guardrails/serializer.py +91 -0
- glaip_sdk/hitl/__init__.py +35 -2
- glaip_sdk/hitl/base.py +64 -0
- glaip_sdk/hitl/callback.py +43 -0
- glaip_sdk/hitl/local.py +1 -31
- glaip_sdk/hitl/remote.py +523 -0
- glaip_sdk/models/__init__.py +47 -1
- glaip_sdk/models/_provider_mappings.py +101 -0
- glaip_sdk/models/_validation.py +97 -0
- glaip_sdk/models/agent.py +2 -1
- glaip_sdk/models/agent_runs.py +2 -1
- glaip_sdk/models/constants.py +141 -0
- glaip_sdk/models/model.py +170 -0
- glaip_sdk/models/schedule.py +224 -0
- glaip_sdk/payload_schemas/agent.py +1 -0
- glaip_sdk/payload_schemas/guardrails.py +34 -0
- glaip_sdk/ptc.py +145 -0
- glaip_sdk/registry/tool.py +270 -57
- glaip_sdk/runner/__init__.py +20 -3
- glaip_sdk/runner/deps.py +4 -1
- glaip_sdk/runner/langgraph.py +251 -27
- glaip_sdk/runner/logging_config.py +77 -0
- glaip_sdk/runner/mcp_adapter/mcp_config_builder.py +30 -9
- glaip_sdk/runner/ptc_adapter.py +98 -0
- glaip_sdk/runner/tool_adapter/langchain_tool_adapter.py +25 -2
- glaip_sdk/schedules/__init__.py +22 -0
- glaip_sdk/schedules/base.py +291 -0
- glaip_sdk/tools/base.py +67 -14
- glaip_sdk/utils/__init__.py +1 -0
- glaip_sdk/utils/agent_config.py +8 -2
- glaip_sdk/utils/bundler.py +138 -2
- glaip_sdk/utils/import_resolver.py +427 -49
- glaip_sdk/utils/runtime_config.py +3 -2
- glaip_sdk/utils/sync.py +31 -11
- glaip_sdk/utils/tool_detection.py +274 -6
- {glaip_sdk-0.6.19.dist-info → glaip_sdk-0.7.27.dist-info}/METADATA +22 -8
- glaip_sdk-0.7.27.dist-info/RECORD +227 -0
- {glaip_sdk-0.6.19.dist-info → glaip_sdk-0.7.27.dist-info}/WHEEL +1 -1
- glaip_sdk-0.7.27.dist-info/entry_points.txt +2 -0
- glaip_sdk/cli/commands/agents.py +0 -1509
- glaip_sdk/cli/commands/mcps.py +0 -1356
- glaip_sdk/cli/commands/tools.py +0 -576
- glaip_sdk/cli/utils.py +0 -263
- glaip_sdk-0.6.19.dist-info/RECORD +0 -163
- glaip_sdk-0.6.19.dist-info/entry_points.txt +0 -2
- {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}
|
glaip_sdk/hitl/__init__.py
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
-
|
|
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"]
|