glaip-sdk 0.0.9__py3-none-any.whl → 0.0.10__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/branding.py +8 -4
- glaip_sdk/cli/slash/agent_session.py +46 -2
- glaip_sdk/cli/slash/prompt.py +48 -10
- glaip_sdk/cli/slash/session.py +234 -59
- glaip_sdk/cli/utils.py +11 -0
- glaip_sdk/config/constants.py +0 -4
- glaip_sdk/exceptions.py +0 -6
- glaip_sdk/utils/rendering/renderer/base.py +105 -45
- glaip_sdk/utils/rendering/renderer/config.py +2 -2
- {glaip_sdk-0.0.9.dist-info → glaip_sdk-0.0.10.dist-info}/METADATA +1 -1
- {glaip_sdk-0.0.9.dist-info → glaip_sdk-0.0.10.dist-info}/RECORD +13 -13
- {glaip_sdk-0.0.9.dist-info → glaip_sdk-0.0.10.dist-info}/WHEEL +0 -0
- {glaip_sdk-0.0.9.dist-info → glaip_sdk-0.0.10.dist-info}/entry_points.txt +0 -0
glaip_sdk/branding.py
CHANGED
|
@@ -4,7 +4,7 @@ Simple, friendly CLI branding for the GL AIP (GDP Labs AI Agent Package) SDK.
|
|
|
4
4
|
|
|
5
5
|
- Package name: GL AIP (GDP Labs AI Agent Package)
|
|
6
6
|
- Version: auto-detected (AIP_VERSION env or importlib.metadata), or passed in
|
|
7
|
-
- Colors:
|
|
7
|
+
- Colors: GDP Labs brand palette with NO_COLOR/AIP_NO_COLOR fallbacks
|
|
8
8
|
|
|
9
9
|
Author:
|
|
10
10
|
Raymond Christopher (raymond.christopher@gdplabs.id)
|
|
@@ -30,9 +30,13 @@ except Exception: # pragma: no cover
|
|
|
30
30
|
PackageNotFoundError = Exception
|
|
31
31
|
|
|
32
32
|
|
|
33
|
-
# ----
|
|
34
|
-
PRIMARY = "#
|
|
35
|
-
|
|
33
|
+
# ---- GDP Labs Brand Color Palette -----------------------------------------
|
|
34
|
+
PRIMARY = "#004987" # Primary brand blue (dark blue)
|
|
35
|
+
SECONDARY_DARK = "#003A5C" # Darkest variant for emphasis
|
|
36
|
+
SECONDARY_MEDIUM = "#005CB8" # Medium variant for UI elements
|
|
37
|
+
SECONDARY_LIGHT = "#40B4E5" # Light variant for highlights
|
|
38
|
+
|
|
39
|
+
BORDER = PRIMARY # Keep borders aligned with primary brand tone
|
|
36
40
|
TITLE_STYLE = f"bold {PRIMARY}"
|
|
37
41
|
LABEL = "bold"
|
|
38
42
|
|
|
@@ -12,6 +12,7 @@ import click
|
|
|
12
12
|
|
|
13
13
|
from glaip_sdk.cli.commands.agents import get as agents_get_command
|
|
14
14
|
from glaip_sdk.cli.commands.agents import run as agents_run_command
|
|
15
|
+
from glaip_sdk.cli.slash.prompt import _HAS_PROMPT_TOOLKIT, FormattedText
|
|
15
16
|
|
|
16
17
|
if TYPE_CHECKING: # pragma: no cover - type checking only
|
|
17
18
|
from .session import SlashSession
|
|
@@ -34,6 +35,7 @@ class AgentRunSession:
|
|
|
34
35
|
"help": "Display this context-aware menu.",
|
|
35
36
|
"exit": "Return to the command palette.",
|
|
36
37
|
"q": "Return to the command palette.",
|
|
38
|
+
"verbose": "Toggle verbose streaming output.",
|
|
37
39
|
}
|
|
38
40
|
|
|
39
41
|
def run(self) -> None:
|
|
@@ -71,8 +73,30 @@ class AgentRunSession:
|
|
|
71
73
|
def _get_user_input(self) -> str | None:
|
|
72
74
|
"""Get user input with proper error handling."""
|
|
73
75
|
try:
|
|
76
|
+
|
|
77
|
+
def _prompt_message() -> Any:
|
|
78
|
+
verbose_enabled = self.session.verbose_enabled
|
|
79
|
+
verbose_tag = "[verbose:on]" if verbose_enabled else "[verbose:off]"
|
|
80
|
+
prompt_prefix = f"{self._agent_name} ({self._agent_id}) "
|
|
81
|
+
|
|
82
|
+
# Use FormattedText if prompt_toolkit is available, otherwise use simple string
|
|
83
|
+
if _HAS_PROMPT_TOOLKIT and FormattedText is not None:
|
|
84
|
+
segments = [
|
|
85
|
+
("class:prompt", prompt_prefix),
|
|
86
|
+
(
|
|
87
|
+
"class:prompt-verbose-on"
|
|
88
|
+
if verbose_enabled
|
|
89
|
+
else "class:prompt-verbose-off",
|
|
90
|
+
verbose_tag,
|
|
91
|
+
),
|
|
92
|
+
("class:prompt", "\n› "),
|
|
93
|
+
]
|
|
94
|
+
return FormattedText(segments)
|
|
95
|
+
|
|
96
|
+
return f"{prompt_prefix}{verbose_tag}\n› "
|
|
97
|
+
|
|
74
98
|
raw = self.session._prompt(
|
|
75
|
-
|
|
99
|
+
_prompt_message,
|
|
76
100
|
placeholder=self._prompt_placeholder,
|
|
77
101
|
)
|
|
78
102
|
if self._prompt_placeholder:
|
|
@@ -138,9 +162,29 @@ class AgentRunSession:
|
|
|
138
162
|
return
|
|
139
163
|
|
|
140
164
|
try:
|
|
165
|
+
ctx = self.session.ctx
|
|
166
|
+
ctx_obj = getattr(ctx, "obj", None)
|
|
167
|
+
previous_session = None
|
|
168
|
+
if isinstance(ctx_obj, dict):
|
|
169
|
+
previous_session = ctx_obj.get("_slash_session")
|
|
170
|
+
ctx_obj["_slash_session"] = self.session
|
|
171
|
+
|
|
172
|
+
self.session.notify_agent_run_started()
|
|
141
173
|
self.session.ctx.invoke(
|
|
142
|
-
agents_run_command,
|
|
174
|
+
agents_run_command,
|
|
175
|
+
agent_ref=agent_id,
|
|
176
|
+
input_text=message,
|
|
177
|
+
verbose=self.session.verbose_enabled,
|
|
143
178
|
)
|
|
144
179
|
self.session.last_run_input = message
|
|
145
180
|
except click.ClickException as exc:
|
|
146
181
|
self.console.print(f"[red]{exc}[/red]")
|
|
182
|
+
finally:
|
|
183
|
+
try:
|
|
184
|
+
self.session.notify_agent_run_finished()
|
|
185
|
+
finally:
|
|
186
|
+
if isinstance(ctx_obj, dict):
|
|
187
|
+
if previous_session is None:
|
|
188
|
+
ctx_obj.pop("_slash_session", None)
|
|
189
|
+
else:
|
|
190
|
+
ctx_obj["_slash_session"] = previous_session
|
glaip_sdk/cli/slash/prompt.py
CHANGED
|
@@ -14,20 +14,27 @@ _HAS_PROMPT_TOOLKIT = False
|
|
|
14
14
|
try: # pragma: no cover - optional dependency
|
|
15
15
|
from prompt_toolkit import PromptSession
|
|
16
16
|
from prompt_toolkit.completion import Completer, Completion
|
|
17
|
-
from prompt_toolkit.formatted_text import FormattedText
|
|
17
|
+
from prompt_toolkit.formatted_text import FormattedText, to_formatted_text
|
|
18
18
|
from prompt_toolkit.key_binding import KeyBindings
|
|
19
19
|
from prompt_toolkit.patch_stdout import patch_stdout
|
|
20
20
|
from prompt_toolkit.styles import Style
|
|
21
21
|
|
|
22
|
+
try:
|
|
23
|
+
from prompt_toolkit.application import run_in_terminal as ptk_run_in_terminal
|
|
24
|
+
except Exception: # pragma: no cover - compatibility fallback
|
|
25
|
+
ptk_run_in_terminal = None
|
|
26
|
+
|
|
22
27
|
_HAS_PROMPT_TOOLKIT = True
|
|
23
28
|
except Exception: # pragma: no cover - optional dependency
|
|
24
29
|
PromptSession = None # type: ignore[assignment]
|
|
25
30
|
Completer = None # type: ignore[assignment]
|
|
26
31
|
Completion = None # type: ignore[assignment]
|
|
27
32
|
FormattedText = None # type: ignore[assignment]
|
|
33
|
+
to_formatted_text = None # type: ignore[assignment]
|
|
28
34
|
KeyBindings = None # type: ignore[assignment]
|
|
29
35
|
Style = None # type: ignore[assignment]
|
|
30
36
|
patch_stdout = None # type: ignore[assignment]
|
|
37
|
+
ptk_run_in_terminal = None
|
|
31
38
|
|
|
32
39
|
if TYPE_CHECKING: # pragma: no cover - typing only
|
|
33
40
|
from .session import SlashSession
|
|
@@ -76,7 +83,7 @@ def setup_prompt_toolkit(
|
|
|
76
83
|
if PromptSession is None or Style is None:
|
|
77
84
|
return None, None
|
|
78
85
|
|
|
79
|
-
bindings = _create_key_bindings()
|
|
86
|
+
bindings = _create_key_bindings(session)
|
|
80
87
|
|
|
81
88
|
prompt_session = PromptSession(
|
|
82
89
|
completer=SlashCompleter(session),
|
|
@@ -86,6 +93,8 @@ def setup_prompt_toolkit(
|
|
|
86
93
|
prompt_style = Style.from_dict(
|
|
87
94
|
{
|
|
88
95
|
"prompt": "bg:#0f172a #facc15 bold",
|
|
96
|
+
"prompt-verbose-on": "bg:#0f172a #34d399 bold",
|
|
97
|
+
"prompt-verbose-off": "bg:#0f172a #f87171 bold",
|
|
89
98
|
"": "bg:#0f172a #e2e8f0",
|
|
90
99
|
"placeholder": "bg:#0f172a #94a3b8 italic",
|
|
91
100
|
}
|
|
@@ -94,7 +103,7 @@ def setup_prompt_toolkit(
|
|
|
94
103
|
return prompt_session, prompt_style
|
|
95
104
|
|
|
96
105
|
|
|
97
|
-
def _create_key_bindings() -> Any:
|
|
106
|
+
def _create_key_bindings(session: SlashSession) -> Any:
|
|
98
107
|
"""Create prompt_toolkit key bindings for the command palette."""
|
|
99
108
|
|
|
100
109
|
if KeyBindings is None:
|
|
@@ -109,29 +118,57 @@ def _create_key_bindings() -> Any:
|
|
|
109
118
|
elif buffer.complete_state is not None:
|
|
110
119
|
buffer.cancel_completion()
|
|
111
120
|
|
|
112
|
-
@bindings.add("/") # type: ignore[misc]
|
|
113
121
|
def _trigger_slash_completion(event: Any) -> None: # pragma: no cover - UI
|
|
114
122
|
buffer = event.app.current_buffer
|
|
115
123
|
buffer.insert_text("/")
|
|
116
124
|
_refresh_completions(buffer)
|
|
117
125
|
|
|
118
|
-
@bindings.add("backspace") # type: ignore[misc]
|
|
119
126
|
def _handle_backspace(event: Any) -> None: # pragma: no cover - UI
|
|
120
127
|
buffer = event.app.current_buffer
|
|
121
128
|
if buffer.document.cursor_position > 0:
|
|
122
129
|
buffer.delete_before_cursor()
|
|
123
130
|
_refresh_completions(buffer)
|
|
124
131
|
|
|
132
|
+
def _toggle_verbose(event: Any) -> None: # pragma: no cover - UI
|
|
133
|
+
_execute_toggle_verbose(session, event.app)
|
|
134
|
+
|
|
135
|
+
@bindings.add("/") # type: ignore[misc]
|
|
136
|
+
def _add_trigger_slash_completion(event: Any) -> None:
|
|
137
|
+
_trigger_slash_completion(event)
|
|
138
|
+
|
|
139
|
+
@bindings.add("backspace") # type: ignore[misc]
|
|
140
|
+
def _add_handle_backspace(event: Any) -> None:
|
|
141
|
+
_handle_backspace(event)
|
|
142
|
+
|
|
125
143
|
@bindings.add("c-h") # type: ignore[misc]
|
|
126
|
-
def
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
144
|
+
def _add_handle_ctrl_h(event: Any) -> None:
|
|
145
|
+
_handle_backspace(event) # Reuse backspace handler
|
|
146
|
+
|
|
147
|
+
@bindings.add("c-t") # type: ignore[misc]
|
|
148
|
+
def _add_toggle_verbose(event: Any) -> None:
|
|
149
|
+
_toggle_verbose(event)
|
|
131
150
|
|
|
132
151
|
return bindings
|
|
133
152
|
|
|
134
153
|
|
|
154
|
+
def _execute_toggle_verbose(
|
|
155
|
+
session: SlashSession, app: Any
|
|
156
|
+
) -> None: # pragma: no cover - UI
|
|
157
|
+
"""Execute verbose toggle with proper terminal handling."""
|
|
158
|
+
|
|
159
|
+
def _announce() -> None:
|
|
160
|
+
session.toggle_verbose(announce=False)
|
|
161
|
+
|
|
162
|
+
run_in_terminal = getattr(app, "run_in_terminal", None)
|
|
163
|
+
if callable(run_in_terminal):
|
|
164
|
+
run_in_terminal(_announce)
|
|
165
|
+
elif ptk_run_in_terminal is not None:
|
|
166
|
+
ptk_run_in_terminal(_announce)
|
|
167
|
+
else:
|
|
168
|
+
_announce()
|
|
169
|
+
app.invalidate()
|
|
170
|
+
|
|
171
|
+
|
|
135
172
|
def _iter_command_completions(
|
|
136
173
|
session: SlashSession, text: str
|
|
137
174
|
) -> Iterable[Completion]: # pragma: no cover - thin wrapper
|
|
@@ -191,6 +228,7 @@ __all__ = [
|
|
|
191
228
|
"SlashCompleter",
|
|
192
229
|
"setup_prompt_toolkit",
|
|
193
230
|
"FormattedText",
|
|
231
|
+
"to_formatted_text",
|
|
194
232
|
"patch_stdout",
|
|
195
233
|
"PromptSession",
|
|
196
234
|
"Style",
|
glaip_sdk/cli/slash/session.py
CHANGED
|
@@ -29,6 +29,7 @@ from .prompt import (
|
|
|
29
29
|
Style,
|
|
30
30
|
patch_stdout,
|
|
31
31
|
setup_prompt_toolkit,
|
|
32
|
+
to_formatted_text,
|
|
32
33
|
)
|
|
33
34
|
|
|
34
35
|
SlashHandler = Callable[["SlashSession", list[str], bool], bool]
|
|
@@ -61,6 +62,8 @@ class SlashSession:
|
|
|
61
62
|
self._interactive = bool(sys.stdin.isatty() and sys.stdout.isatty())
|
|
62
63
|
self._config_cache: dict[str, Any] | None = None
|
|
63
64
|
self._welcome_rendered = False
|
|
65
|
+
self._verbose_enabled = False
|
|
66
|
+
self._active_renderer: Any | None = None
|
|
64
67
|
|
|
65
68
|
self._home_placeholder = "Start with / to browse commands"
|
|
66
69
|
|
|
@@ -209,46 +212,49 @@ class SlashSession:
|
|
|
209
212
|
def _cmd_help(self, _args: list[str], invoked_from_agent: bool) -> bool:
|
|
210
213
|
try:
|
|
211
214
|
if invoked_from_agent:
|
|
212
|
-
|
|
213
|
-
table.add_column("Input", style="cyan", no_wrap=True)
|
|
214
|
-
table.add_column("What happens", style="green")
|
|
215
|
-
table.add_row(
|
|
216
|
-
"<message>", "Run the active agent once with that prompt."
|
|
217
|
-
)
|
|
218
|
-
table.add_row("/details", "Show the full agent export and metadata.")
|
|
219
|
-
table.add_row(
|
|
220
|
-
self.STATUS_COMMAND, "Display connection status without leaving."
|
|
221
|
-
)
|
|
222
|
-
table.add_row("/exit (/back)", "Return to the slash home screen.")
|
|
223
|
-
table.add_row("/help (/?)", "Display this context-aware menu.")
|
|
224
|
-
self.console.print(table)
|
|
225
|
-
if self.last_run_input:
|
|
226
|
-
self.console.print(f"[dim]Last run input:[/] {self.last_run_input}")
|
|
227
|
-
self.console.print(
|
|
228
|
-
"[dim]Global commands (e.g. `/login`, `/status`) remain available inside the agent prompt.[/dim]"
|
|
229
|
-
)
|
|
215
|
+
self._render_agent_help()
|
|
230
216
|
else:
|
|
231
|
-
|
|
232
|
-
table.add_column("Command", style="cyan", no_wrap=True)
|
|
233
|
-
table.add_column("Description", style="green")
|
|
234
|
-
|
|
235
|
-
for cmd in sorted(self._unique_commands.values(), key=lambda c: c.name):
|
|
236
|
-
aliases = ", ".join(f"/{alias}" for alias in cmd.aliases if alias)
|
|
237
|
-
verb = f"/{cmd.name}"
|
|
238
|
-
if aliases:
|
|
239
|
-
verb = f"{verb} ({aliases})"
|
|
240
|
-
table.add_row(verb, cmd.help)
|
|
241
|
-
|
|
242
|
-
self.console.print(table)
|
|
243
|
-
self.console.print(
|
|
244
|
-
"[dim]Tip: `{self.AGENTS_COMMAND}` lets you jump into an agent run prompt quickly.[/dim]"
|
|
245
|
-
)
|
|
217
|
+
self._render_global_help()
|
|
246
218
|
except Exception as exc: # pragma: no cover - UI/display errors
|
|
247
219
|
self.console.print(f"[red]Error displaying help: {exc}[/red]")
|
|
248
220
|
return False
|
|
249
221
|
|
|
250
222
|
return True
|
|
251
223
|
|
|
224
|
+
def _render_agent_help(self) -> None:
|
|
225
|
+
table = Table(title="Agent Context")
|
|
226
|
+
table.add_column("Input", style="cyan", no_wrap=True)
|
|
227
|
+
table.add_column("What happens", style="green")
|
|
228
|
+
table.add_row("<message>", "Run the active agent once with that prompt.")
|
|
229
|
+
table.add_row("/details", "Show the full agent export and metadata.")
|
|
230
|
+
table.add_row(self.STATUS_COMMAND, "Display connection status without leaving.")
|
|
231
|
+
table.add_row("/verbose", "Toggle verbose streaming output (Ctrl+T works too).")
|
|
232
|
+
table.add_row("/exit (/back)", "Return to the slash home screen.")
|
|
233
|
+
table.add_row("/help (/?)", "Display this context-aware menu.")
|
|
234
|
+
self.console.print(table)
|
|
235
|
+
if self.last_run_input:
|
|
236
|
+
self.console.print(f"[dim]Last run input:[/] {self.last_run_input}")
|
|
237
|
+
self.console.print(
|
|
238
|
+
"[dim]Global commands (e.g. `/login`, `/status`) remain available inside the agent prompt.[/dim]"
|
|
239
|
+
)
|
|
240
|
+
|
|
241
|
+
def _render_global_help(self) -> None:
|
|
242
|
+
table = Table(title="Slash Commands")
|
|
243
|
+
table.add_column("Command", style="cyan", no_wrap=True)
|
|
244
|
+
table.add_column("Description", style="green")
|
|
245
|
+
|
|
246
|
+
for cmd in sorted(self._unique_commands.values(), key=lambda c: c.name):
|
|
247
|
+
aliases = ", ".join(f"/{alias}" for alias in cmd.aliases if alias)
|
|
248
|
+
verb = f"/{cmd.name}"
|
|
249
|
+
if aliases:
|
|
250
|
+
verb = f"{verb} ({aliases})"
|
|
251
|
+
table.add_row(verb, cmd.help)
|
|
252
|
+
|
|
253
|
+
self.console.print(table)
|
|
254
|
+
self.console.print(
|
|
255
|
+
"[dim]Tip: `{self.AGENTS_COMMAND}` lets you jump into an agent run prompt quickly.[/dim]"
|
|
256
|
+
)
|
|
257
|
+
|
|
252
258
|
def _cmd_login(self, _args: list[str], _invoked_from_agent: bool) -> bool:
|
|
253
259
|
self.console.print("[cyan]Launching configuration wizard...[/cyan]")
|
|
254
260
|
try:
|
|
@@ -388,12 +394,119 @@ class SlashSession:
|
|
|
388
394
|
aliases=("q",),
|
|
389
395
|
)
|
|
390
396
|
)
|
|
397
|
+
self._register(
|
|
398
|
+
SlashCommand(
|
|
399
|
+
name="verbose",
|
|
400
|
+
help="Toggle verbose streaming output.",
|
|
401
|
+
handler=SlashSession._cmd_verbose,
|
|
402
|
+
)
|
|
403
|
+
)
|
|
391
404
|
|
|
392
405
|
def _register(self, command: SlashCommand) -> None:
|
|
393
406
|
self._unique_commands[command.name] = command
|
|
394
407
|
for key in (command.name, *command.aliases):
|
|
395
408
|
self._commands[key] = command
|
|
396
409
|
|
|
410
|
+
# ------------------------------------------------------------------
|
|
411
|
+
# Verbose mode helpers
|
|
412
|
+
# ------------------------------------------------------------------
|
|
413
|
+
@property
|
|
414
|
+
def verbose_enabled(self) -> bool:
|
|
415
|
+
"""Return whether verbose agent runs are enabled."""
|
|
416
|
+
|
|
417
|
+
return self._verbose_enabled
|
|
418
|
+
|
|
419
|
+
def set_verbose(self, enabled: bool, *, announce: bool = True) -> None:
|
|
420
|
+
"""Enable or disable verbose mode with optional announcement."""
|
|
421
|
+
|
|
422
|
+
if self._verbose_enabled == enabled:
|
|
423
|
+
if announce:
|
|
424
|
+
self._print_verbose_status(context="already")
|
|
425
|
+
return
|
|
426
|
+
|
|
427
|
+
self._verbose_enabled = enabled
|
|
428
|
+
self._sync_active_renderer()
|
|
429
|
+
if announce:
|
|
430
|
+
self._print_verbose_status(context="changed")
|
|
431
|
+
|
|
432
|
+
def toggle_verbose(self, *, announce: bool = True) -> None:
|
|
433
|
+
"""Flip verbose mode state."""
|
|
434
|
+
|
|
435
|
+
self.set_verbose(not self._verbose_enabled, announce=announce)
|
|
436
|
+
|
|
437
|
+
def _cmd_verbose(self, args: list[str], _invoked_from_agent: bool) -> bool:
|
|
438
|
+
"""Slash handler for `/verbose` command."""
|
|
439
|
+
|
|
440
|
+
if args:
|
|
441
|
+
self.console.print(
|
|
442
|
+
"Usage: `/verbose` toggles verbose streaming output. Press Ctrl+T as a shortcut."
|
|
443
|
+
)
|
|
444
|
+
else:
|
|
445
|
+
self.toggle_verbose()
|
|
446
|
+
|
|
447
|
+
return True
|
|
448
|
+
|
|
449
|
+
def _print_verbose_status(self, *, context: str) -> None:
|
|
450
|
+
state_word = "on" if self._verbose_enabled else "off"
|
|
451
|
+
if context == "already":
|
|
452
|
+
self.console.print(
|
|
453
|
+
f"Verbose mode already {state_word}. Use Ctrl+T or `/verbose` to toggle."
|
|
454
|
+
)
|
|
455
|
+
return
|
|
456
|
+
|
|
457
|
+
change_word = "enabled" if self._verbose_enabled else "disabled"
|
|
458
|
+
self.console.print(
|
|
459
|
+
f"Verbose mode {change_word}. Use Ctrl+T or `/verbose` to toggle."
|
|
460
|
+
)
|
|
461
|
+
|
|
462
|
+
# ------------------------------------------------------------------
|
|
463
|
+
# Agent run coordination helpers
|
|
464
|
+
# ------------------------------------------------------------------
|
|
465
|
+
def register_active_renderer(self, renderer: Any) -> None:
|
|
466
|
+
"""Register the renderer currently streaming an agent run."""
|
|
467
|
+
|
|
468
|
+
self._active_renderer = renderer
|
|
469
|
+
self._sync_active_renderer()
|
|
470
|
+
|
|
471
|
+
def clear_active_renderer(self, renderer: Any | None = None) -> None:
|
|
472
|
+
"""Clear the active renderer if it matches the provided instance."""
|
|
473
|
+
|
|
474
|
+
if renderer is not None and renderer is not self._active_renderer:
|
|
475
|
+
return
|
|
476
|
+
self._active_renderer = None
|
|
477
|
+
|
|
478
|
+
def notify_agent_run_started(self) -> None:
|
|
479
|
+
"""Mark that an agent run is in progress."""
|
|
480
|
+
|
|
481
|
+
self.clear_active_renderer()
|
|
482
|
+
|
|
483
|
+
def notify_agent_run_finished(self) -> None:
|
|
484
|
+
"""Mark that the active agent run has completed."""
|
|
485
|
+
|
|
486
|
+
self.clear_active_renderer()
|
|
487
|
+
|
|
488
|
+
def _sync_active_renderer(self) -> None:
|
|
489
|
+
"""Ensure the active renderer reflects the current verbose state."""
|
|
490
|
+
|
|
491
|
+
renderer = self._active_renderer
|
|
492
|
+
if renderer is None:
|
|
493
|
+
return
|
|
494
|
+
|
|
495
|
+
applied = False
|
|
496
|
+
apply_verbose = getattr(renderer, "apply_verbosity", None)
|
|
497
|
+
if callable(apply_verbose):
|
|
498
|
+
try:
|
|
499
|
+
apply_verbose(self._verbose_enabled)
|
|
500
|
+
applied = True
|
|
501
|
+
except Exception:
|
|
502
|
+
pass
|
|
503
|
+
|
|
504
|
+
if not applied and hasattr(renderer, "verbose"):
|
|
505
|
+
try:
|
|
506
|
+
renderer.verbose = self._verbose_enabled
|
|
507
|
+
except Exception:
|
|
508
|
+
pass
|
|
509
|
+
|
|
397
510
|
def _parse(self, raw: str) -> tuple[str, list[str]]:
|
|
398
511
|
try:
|
|
399
512
|
tokens = shlex.split(raw)
|
|
@@ -416,33 +529,83 @@ class SlashSession:
|
|
|
416
529
|
match = get_close_matches(verb, keys, n=1)
|
|
417
530
|
return match[0] if match else None
|
|
418
531
|
|
|
419
|
-
def
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
532
|
+
def _convert_message(self, value: Any) -> Any:
|
|
533
|
+
"""Convert a message value to the appropriate format for display."""
|
|
534
|
+
if FormattedText is not None and to_formatted_text is not None:
|
|
535
|
+
return to_formatted_text(value)
|
|
536
|
+
if FormattedText is not None:
|
|
537
|
+
return FormattedText([("class:prompt", str(value))])
|
|
538
|
+
return str(value)
|
|
539
|
+
|
|
540
|
+
def _get_prompt_kwargs(self, placeholder: str | None) -> dict[str, Any]:
|
|
541
|
+
"""Get prompt kwargs with optional placeholder styling."""
|
|
542
|
+
prompt_kwargs: dict[str, Any] = {"style": self._ptk_style}
|
|
543
|
+
if placeholder:
|
|
544
|
+
placeholder_text = (
|
|
545
|
+
FormattedText([("class:placeholder", placeholder)])
|
|
546
|
+
if FormattedText is not None
|
|
547
|
+
else placeholder
|
|
548
|
+
)
|
|
549
|
+
prompt_kwargs["placeholder"] = placeholder_text
|
|
550
|
+
return prompt_kwargs
|
|
551
|
+
|
|
552
|
+
def _prompt_with_prompt_toolkit(
|
|
553
|
+
self, message: str | Callable[[], Any], placeholder: str | None
|
|
554
|
+
) -> str:
|
|
555
|
+
"""Handle prompting with prompt_toolkit."""
|
|
556
|
+
with patch_stdout(): # pragma: no cover - UI specific
|
|
557
|
+
if callable(message):
|
|
558
|
+
|
|
559
|
+
def prompt_text() -> Any:
|
|
560
|
+
return self._convert_message(message())
|
|
561
|
+
else:
|
|
562
|
+
prompt_text = self._convert_message(message)
|
|
563
|
+
|
|
564
|
+
prompt_kwargs = self._get_prompt_kwargs(placeholder)
|
|
565
|
+
|
|
566
|
+
try:
|
|
567
|
+
return self._ptk_session.prompt(prompt_text, **prompt_kwargs)
|
|
568
|
+
except (
|
|
569
|
+
TypeError
|
|
570
|
+
): # pragma: no cover - compatibility with older prompt_toolkit
|
|
571
|
+
prompt_kwargs.pop("placeholder", None)
|
|
572
|
+
return self._ptk_session.prompt(prompt_text, **prompt_kwargs)
|
|
573
|
+
|
|
574
|
+
def _extract_message_text(self, raw_value: Any) -> str:
|
|
575
|
+
"""Extract text content from various message formats."""
|
|
576
|
+
if isinstance(raw_value, str):
|
|
577
|
+
return raw_value
|
|
442
578
|
|
|
579
|
+
try:
|
|
580
|
+
if FormattedText is not None and isinstance(raw_value, FormattedText):
|
|
581
|
+
return "".join(text for _style, text in raw_value)
|
|
582
|
+
elif isinstance(raw_value, list):
|
|
583
|
+
return "".join(segment[1] for segment in raw_value)
|
|
584
|
+
else:
|
|
585
|
+
return str(raw_value)
|
|
586
|
+
except Exception:
|
|
587
|
+
return str(raw_value)
|
|
588
|
+
|
|
589
|
+
def _prompt_with_basic_input(
|
|
590
|
+
self, message: str | Callable[[], Any], placeholder: str | None
|
|
591
|
+
) -> str:
|
|
592
|
+
"""Handle prompting with basic input."""
|
|
443
593
|
if placeholder:
|
|
444
594
|
self.console.print(f"[dim]{placeholder}[/dim]")
|
|
445
|
-
|
|
595
|
+
|
|
596
|
+
raw_value = message() if callable(message) else message
|
|
597
|
+
actual_message = self._extract_message_text(raw_value)
|
|
598
|
+
|
|
599
|
+
return input(actual_message)
|
|
600
|
+
|
|
601
|
+
def _prompt(
|
|
602
|
+
self, message: str | Callable[[], Any], *, placeholder: str | None = None
|
|
603
|
+
) -> str:
|
|
604
|
+
"""Main prompt function with reduced complexity."""
|
|
605
|
+
if self._ptk_session and self._ptk_style and patch_stdout:
|
|
606
|
+
return self._prompt_with_prompt_toolkit(message, placeholder)
|
|
607
|
+
|
|
608
|
+
return self._prompt_with_basic_input(message, placeholder)
|
|
446
609
|
|
|
447
610
|
def _get_client(self) -> Any: # type: ignore[no-any-return]
|
|
448
611
|
if self._client is None:
|
|
@@ -503,12 +666,17 @@ class SlashSession:
|
|
|
503
666
|
agent_type = getattr(active_agent, "type", "") or "-"
|
|
504
667
|
description = getattr(active_agent, "description", "") or ""
|
|
505
668
|
|
|
669
|
+
verbose_label = "verbose on" if self._verbose_enabled else "verbose off"
|
|
670
|
+
|
|
506
671
|
header_grid = Table.grid(expand=True)
|
|
507
672
|
header_grid.add_column(ratio=3)
|
|
508
673
|
header_grid.add_column(ratio=1, justify="right")
|
|
509
674
|
|
|
510
675
|
primary_line = f"[bold]{agent_name}[/bold] · [dim]{agent_type}[/dim] · [cyan]{agent_id}[/cyan]"
|
|
511
|
-
header_grid.add_row(
|
|
676
|
+
header_grid.add_row(
|
|
677
|
+
primary_line,
|
|
678
|
+
f"[green]ready[/green] · {verbose_label}",
|
|
679
|
+
)
|
|
512
680
|
|
|
513
681
|
if description:
|
|
514
682
|
header_grid.add_row(f"[dim]{description}[/dim]", "")
|
|
@@ -517,10 +685,12 @@ class SlashSession:
|
|
|
517
685
|
keybar.add_column(justify="left")
|
|
518
686
|
keybar.add_column(justify="left")
|
|
519
687
|
keybar.add_column(justify="left")
|
|
688
|
+
keybar.add_column(justify="left")
|
|
520
689
|
keybar.add_row(
|
|
521
690
|
"[bold]/help[/bold] [dim]Show commands[/dim]",
|
|
522
691
|
"[bold]/details[/bold] [dim]Agent config[/dim]",
|
|
523
692
|
"[bold]/exit[/bold] [dim]Back[/dim]",
|
|
693
|
+
"[bold]Ctrl+T[/bold] [dim]Toggle verbose[/dim]",
|
|
524
694
|
)
|
|
525
695
|
|
|
526
696
|
header_grid.add_row(keybar, "")
|
|
@@ -544,6 +714,8 @@ class SlashSession:
|
|
|
544
714
|
"",
|
|
545
715
|
f"[dim]API URL[/dim]: {api_url or 'Not configured'}",
|
|
546
716
|
f"[dim]Credentials[/dim]: {status}",
|
|
717
|
+
f"[dim]Verbose mode[/dim]: {'on' if self._verbose_enabled else 'off'}",
|
|
718
|
+
"[dim]Tip[/dim]: Press Ctrl+T or run `/verbose` to toggle verbose streaming.",
|
|
547
719
|
]
|
|
548
720
|
extra: list[str] = []
|
|
549
721
|
self._add_agent_info_to_header(extra, active_agent)
|
|
@@ -560,8 +732,10 @@ class SlashSession:
|
|
|
560
732
|
status_bar.add_row(
|
|
561
733
|
"[bold cyan]AIP Palette[/bold cyan]",
|
|
562
734
|
f"[dim]API[/dim]: {api_url or 'Not configured'}",
|
|
563
|
-
"[dim]
|
|
735
|
+
f"[dim]Verbose[/dim]: {'on' if self._verbose_enabled else 'off'}",
|
|
564
736
|
)
|
|
737
|
+
status_bar.add_row("[dim]Ctrl+T toggles verbose[/dim]", "", "")
|
|
738
|
+
status_bar.add_row("[dim]Type /help for shortcuts[/dim]", "", "")
|
|
565
739
|
|
|
566
740
|
if active_agent is not None:
|
|
567
741
|
agent_id = str(getattr(active_agent, "id", ""))
|
|
@@ -602,6 +776,7 @@ class SlashSession:
|
|
|
602
776
|
self.console.print(
|
|
603
777
|
AIPPanel(
|
|
604
778
|
"Type `/help` for command palette commands, `/agents` to browse agents, or `/exit` (`/q`) to leave the palette.\n"
|
|
779
|
+
"Press Ctrl+T to toggle verbose output.\n"
|
|
605
780
|
"Press Ctrl+C to cancel the current entry, Ctrl+D to quit immediately.",
|
|
606
781
|
title="✨ Getting Started",
|
|
607
782
|
border_style="cyan",
|
glaip_sdk/cli/utils.py
CHANGED
|
@@ -1108,6 +1108,17 @@ def build_renderer(
|
|
|
1108
1108
|
verbose=verbose,
|
|
1109
1109
|
)
|
|
1110
1110
|
|
|
1111
|
+
# Link the renderer back to the slash session when running from the palette.
|
|
1112
|
+
try:
|
|
1113
|
+
ctx_obj = getattr(_ctx, "obj", None)
|
|
1114
|
+
if isinstance(ctx_obj, dict):
|
|
1115
|
+
session = ctx_obj.get("_slash_session")
|
|
1116
|
+
if session and hasattr(session, "register_active_renderer"):
|
|
1117
|
+
session.register_active_renderer(renderer)
|
|
1118
|
+
except Exception:
|
|
1119
|
+
# Never let session bookkeeping break renderer creation
|
|
1120
|
+
pass
|
|
1121
|
+
|
|
1111
1122
|
return renderer, working_console
|
|
1112
1123
|
|
|
1113
1124
|
|
glaip_sdk/config/constants.py
CHANGED
glaip_sdk/exceptions.py
CHANGED
|
@@ -98,9 +98,3 @@ class AgentTimeoutError(TimeoutError):
|
|
|
98
98
|
super().__init__(message)
|
|
99
99
|
self.timeout_seconds = timeout_seconds
|
|
100
100
|
self.agent_name = agent_name
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
class ClientError(APIError):
|
|
104
|
-
"""Client-side error (e.g., invalid request format, missing parameters)."""
|
|
105
|
-
|
|
106
|
-
pass
|
|
@@ -310,56 +310,115 @@ class RichStreamRenderer:
|
|
|
310
310
|
|
|
311
311
|
def _ensure_live(self) -> None:
|
|
312
312
|
"""Ensure live display is updated."""
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
# the background refresh thread. Normal Rich consoles always expose
|
|
318
|
-
# _live_stack as a list, so we defensively initialise it if needed.
|
|
319
|
-
live_stack = getattr(self.console, "_live_stack", None)
|
|
320
|
-
if not isinstance(live_stack, list):
|
|
321
|
-
try:
|
|
322
|
-
self.console._live_stack = [] # type: ignore[attr-defined]
|
|
323
|
-
except Exception:
|
|
324
|
-
# If the console forbids attribute assignment we simply skip the
|
|
325
|
-
# live update for this cycle and fall back to buffered printing.
|
|
326
|
-
logger.debug(
|
|
327
|
-
"Console missing _live_stack; skipping live UI initialisation",
|
|
328
|
-
exc_info=True,
|
|
329
|
-
)
|
|
330
|
-
return
|
|
331
|
-
|
|
332
|
-
if self.live is None and self.cfg.live:
|
|
333
|
-
try:
|
|
334
|
-
self.live = Live(
|
|
335
|
-
console=self.console,
|
|
336
|
-
refresh_per_second=1 / self.cfg.refresh_debounce,
|
|
337
|
-
transient=not self.cfg.persist_live,
|
|
338
|
-
)
|
|
339
|
-
self.live.start()
|
|
340
|
-
except Exception:
|
|
341
|
-
self.live = None
|
|
313
|
+
if not self._ensure_live_stack():
|
|
314
|
+
return
|
|
315
|
+
|
|
316
|
+
self._start_live_if_needed()
|
|
342
317
|
|
|
343
318
|
if self.live:
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
319
|
+
self._refresh_live_panels()
|
|
320
|
+
|
|
321
|
+
def _ensure_live_stack(self) -> bool:
|
|
322
|
+
"""Guarantee the console exposes the internal live stack Rich expects."""
|
|
323
|
+
live_stack = getattr(self.console, "_live_stack", None)
|
|
324
|
+
if isinstance(live_stack, list):
|
|
325
|
+
return True
|
|
326
|
+
|
|
327
|
+
try:
|
|
328
|
+
self.console._live_stack = [] # type: ignore[attr-defined]
|
|
329
|
+
return True
|
|
330
|
+
except Exception:
|
|
331
|
+
# If the console forbids attribute assignment we simply skip the live
|
|
332
|
+
# update for this cycle and fall back to buffered printing.
|
|
333
|
+
logger.debug(
|
|
334
|
+
"Console missing _live_stack; skipping live UI initialisation",
|
|
335
|
+
exc_info=True,
|
|
336
|
+
)
|
|
337
|
+
return False
|
|
338
|
+
|
|
339
|
+
def _start_live_if_needed(self) -> None:
|
|
340
|
+
"""Create and start a Live instance when configuration allows."""
|
|
341
|
+
if self.live is not None or not self.cfg.live:
|
|
342
|
+
return
|
|
343
|
+
|
|
344
|
+
try:
|
|
345
|
+
self.live = Live(
|
|
346
|
+
console=self.console,
|
|
347
|
+
refresh_per_second=1 / self.cfg.refresh_debounce,
|
|
348
|
+
transient=not self.cfg.persist_live,
|
|
352
349
|
)
|
|
353
|
-
|
|
354
|
-
|
|
350
|
+
self.live.start()
|
|
351
|
+
except Exception:
|
|
352
|
+
self.live = None
|
|
353
|
+
|
|
354
|
+
def _refresh_live_panels(self) -> None:
|
|
355
|
+
"""Render panels and push them to the active Live display."""
|
|
356
|
+
if not self.live:
|
|
357
|
+
return
|
|
358
|
+
|
|
359
|
+
main_panel = self._render_main_panel()
|
|
360
|
+
steps_renderable = self._render_steps_text()
|
|
361
|
+
steps_panel = AIPPanel(
|
|
362
|
+
steps_renderable,
|
|
363
|
+
title="Steps",
|
|
364
|
+
border_style="blue",
|
|
365
|
+
)
|
|
366
|
+
tool_panels = self._render_tool_panels()
|
|
367
|
+
panels = self._build_live_panels(main_panel, steps_panel, tool_panels)
|
|
368
|
+
|
|
369
|
+
self.live.update(Group(*panels))
|
|
370
|
+
|
|
371
|
+
def _build_live_panels(
|
|
372
|
+
self,
|
|
373
|
+
main_panel: Any,
|
|
374
|
+
steps_panel: Any,
|
|
375
|
+
tool_panels: list[Any],
|
|
376
|
+
) -> list[Any]:
|
|
377
|
+
"""Assemble the panel order for the live display."""
|
|
378
|
+
if self.verbose:
|
|
379
|
+
return [main_panel, steps_panel, *tool_panels]
|
|
380
|
+
|
|
381
|
+
panels: list[Any] = [steps_panel]
|
|
382
|
+
if tool_panels:
|
|
383
|
+
panels.extend(tool_panels)
|
|
384
|
+
panels.append(main_panel)
|
|
385
|
+
return panels
|
|
355
386
|
|
|
356
387
|
def _render_main_panel(self) -> Any:
|
|
357
388
|
"""Render the main content panel."""
|
|
358
389
|
body = "".join(self.state.buffer).strip()
|
|
390
|
+
if not self.verbose:
|
|
391
|
+
final_content = (self.state.final_text or "").strip()
|
|
392
|
+
if final_content:
|
|
393
|
+
return create_final_panel(
|
|
394
|
+
final_content,
|
|
395
|
+
title="Final Result",
|
|
396
|
+
theme=self.cfg.theme,
|
|
397
|
+
)
|
|
359
398
|
# Dynamic title with spinner + elapsed/hints
|
|
360
399
|
title = self._format_enhanced_main_title()
|
|
361
400
|
return create_main_panel(body, title, self.cfg.theme)
|
|
362
401
|
|
|
402
|
+
def apply_verbosity(self, verbose: bool) -> None:
|
|
403
|
+
"""Update verbose behaviour at runtime."""
|
|
404
|
+
|
|
405
|
+
if self.verbose == verbose:
|
|
406
|
+
return
|
|
407
|
+
|
|
408
|
+
self.verbose = verbose
|
|
409
|
+
self.cfg.style = "debug" if verbose else "pretty"
|
|
410
|
+
|
|
411
|
+
desired_live = not verbose
|
|
412
|
+
if desired_live != self.cfg.live:
|
|
413
|
+
self.cfg.live = desired_live
|
|
414
|
+
if not desired_live:
|
|
415
|
+
self._shutdown_live()
|
|
416
|
+
else:
|
|
417
|
+
self._ensure_live()
|
|
418
|
+
|
|
419
|
+
if self.cfg.live:
|
|
420
|
+
self._ensure_live()
|
|
421
|
+
|
|
363
422
|
def _maybe_insert_thinking_gap(
|
|
364
423
|
self, task_id: str | None, context_id: str | None
|
|
365
424
|
) -> None:
|
|
@@ -668,15 +727,16 @@ class RichStreamRenderer:
|
|
|
668
727
|
|
|
669
728
|
def _clamp_snapshot_body(self, body_text: str) -> str:
|
|
670
729
|
"""Clamp snapshot body to configured limits."""
|
|
671
|
-
max_lines = int(self.cfg.snapshot_max_lines or 0)
|
|
730
|
+
max_lines = int(self.cfg.snapshot_max_lines or 0)
|
|
672
731
|
lines = body_text.splitlines()
|
|
673
|
-
if len(lines) > max_lines:
|
|
732
|
+
if max_lines > 0 and len(lines) > max_lines:
|
|
674
733
|
lines = lines[:max_lines] + ["… (truncated)"]
|
|
675
|
-
|
|
734
|
+
body_text = "\n".join(lines)
|
|
676
735
|
|
|
677
|
-
max_chars = int(self.cfg.snapshot_max_chars or 0)
|
|
678
|
-
if len(body_text) > max_chars:
|
|
679
|
-
|
|
736
|
+
max_chars = int(self.cfg.snapshot_max_chars or 0)
|
|
737
|
+
if max_chars > 0 and len(body_text) > max_chars:
|
|
738
|
+
suffix = "\n… (truncated)"
|
|
739
|
+
body_text = body_text[: max_chars - len(suffix)] + suffix
|
|
680
740
|
|
|
681
741
|
return body_text
|
|
682
742
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
glaip_sdk/__init__.py,sha256=FD-oTyFUKsTB9xTuGiqvkhuFXfeZ-TspjkeXERglha8,370
|
|
2
2
|
glaip_sdk/_version.py,sha256=tGkFWAVu2ry4Hy7j-u7ophGbPRX8y-ngBbXDhN1VBIQ,2007
|
|
3
|
-
glaip_sdk/branding.py,sha256=
|
|
3
|
+
glaip_sdk/branding.py,sha256=xsHL7nRAWuwJrAvCi2fZhaPD-AWvdcLNoTVmlw4gZKc,5604
|
|
4
4
|
glaip_sdk/cli/__init__.py,sha256=xCCfuF1Yc7mpCDcfhHZTX0vizvtrDSLeT8MJ3V7m5A0,156
|
|
5
5
|
glaip_sdk/cli/agent_config.py,sha256=VHjebw68wAdhGUzYdPH8qz10oADZPRgUQcPW6F7iHIU,2421
|
|
6
6
|
glaip_sdk/cli/commands/__init__.py,sha256=x0CZlZbZHoHvuzfoTWIyEch6WmNnbPzxajrox6riYp0,173
|
|
@@ -14,10 +14,10 @@ glaip_sdk/cli/io.py,sha256=GPkw3pQMLBGoD5GH-KlbKpNRlVWFZOXHE17F7V3kQsI,3343
|
|
|
14
14
|
glaip_sdk/cli/main.py,sha256=uWuntvFl0hQSLfNa1rXb-J2zUK_msf3vrSbbrqBcEc4,12692
|
|
15
15
|
glaip_sdk/cli/resolution.py,sha256=BOw2NchReLKewAwBAZLWw_3_bI7u3tfzQEO7kQbIiGE,2067
|
|
16
16
|
glaip_sdk/cli/slash/__init__.py,sha256=Vdv6Y8bu-pA8dxDlyP4XrhudBPivztUozhLAz9vaLig,682
|
|
17
|
-
glaip_sdk/cli/slash/agent_session.py,sha256=
|
|
18
|
-
glaip_sdk/cli/slash/prompt.py,sha256=
|
|
19
|
-
glaip_sdk/cli/slash/session.py,sha256=
|
|
20
|
-
glaip_sdk/cli/utils.py,sha256=
|
|
17
|
+
glaip_sdk/cli/slash/agent_session.py,sha256=pDOwGXNHuyJIulrGYu1pacyF3oxHWeDQY-Uv92h2qVg,6859
|
|
18
|
+
glaip_sdk/cli/slash/prompt.py,sha256=Pr5SSTOKFssRsi-AujOm5_BCW_f5MxgLwJ3CCji1ogM,7356
|
|
19
|
+
glaip_sdk/cli/slash/session.py,sha256=W8Fk1t9qqr1B9clhIwsAuv3i_6yYk_vEAuM00zGHxHM,30482
|
|
20
|
+
glaip_sdk/cli/utils.py,sha256=7UNg4qDIR0BDgiWJgtEDaVmRa9fhfUsBLiygcuTDxmE,42236
|
|
21
21
|
glaip_sdk/cli/validators.py,sha256=USbBgY86AwuDHO-Q_g8g7hu-ot4NgITBsWjTWIl62ms,5569
|
|
22
22
|
glaip_sdk/client/__init__.py,sha256=nYLXfBVTTWwKjP0e63iumPYO4k5FifwWaELQPaPIKIg,188
|
|
23
23
|
glaip_sdk/client/agents.py,sha256=FSKubF40wptMNIheC3_iawiX2CRbhTcNLFiz4qkPC6k,34659
|
|
@@ -26,8 +26,8 @@ glaip_sdk/client/main.py,sha256=LlvYHP7-Hy7Eq1ep1kfk337K-Oue5SdKWJpqYfX9eXY,7993
|
|
|
26
26
|
glaip_sdk/client/mcps.py,sha256=yxwrAtztElYDEGhp2EHRpeYUxNsOlTLTqtw9jSKJmcI,8936
|
|
27
27
|
glaip_sdk/client/tools.py,sha256=n8DIiOOf1YU_j9JK3Bx2-rDnkpckPi0MI9Ok2s1kwa4,16634
|
|
28
28
|
glaip_sdk/client/validators.py,sha256=NtPsWjQLjj25LiUnmR-WuS8lL5p4MVRaYT9UVRmj9bo,8809
|
|
29
|
-
glaip_sdk/config/constants.py,sha256=
|
|
30
|
-
glaip_sdk/exceptions.py,sha256=
|
|
29
|
+
glaip_sdk/config/constants.py,sha256=ysEobMiXlLZGIOEaqTdHpPF8kmg5nbLn7BIcBvTCuHM,819
|
|
30
|
+
glaip_sdk/exceptions.py,sha256=DJgaIcvGA09qIX10-ypYgQQ5_k5N3qknmiIFP3p4Z7E,1872
|
|
31
31
|
glaip_sdk/models.py,sha256=Ry_Ihd6FuC0JGb0Obd5T3A22AOp2r9xStQisfE8uo8c,8822
|
|
32
32
|
glaip_sdk/rich_components.py,sha256=pmJd-81OQE8bC9UOXtga5rsax4zphKlzCZ1JoWbbQzQ,803
|
|
33
33
|
glaip_sdk/utils/__init__.py,sha256=fmVGcUFa7G0CCfSMSqfNU2BqFl36G1gOFyDfTvtJfVw,926
|
|
@@ -40,8 +40,8 @@ glaip_sdk/utils/rendering/__init__.py,sha256=vXjwk5rPhhfPyD8S0DnV4GFFEtPJp4HCCg1
|
|
|
40
40
|
glaip_sdk/utils/rendering/formatting.py,sha256=_k8tkcobctmHvdygMljZF7-ALGXpD9-hHF1CNtM2KMU,7201
|
|
41
41
|
glaip_sdk/utils/rendering/models.py,sha256=SS34_00FaoGuSYn-viBkAtIbq7cJNwwPjpxnvyeUmxI,1567
|
|
42
42
|
glaip_sdk/utils/rendering/renderer/__init__.py,sha256=EXwVBmGkSYcype4ocAXo69Z1kXu0gpNXmhH5LW0_B7A,2939
|
|
43
|
-
glaip_sdk/utils/rendering/renderer/base.py,sha256=
|
|
44
|
-
glaip_sdk/utils/rendering/renderer/config.py,sha256
|
|
43
|
+
glaip_sdk/utils/rendering/renderer/base.py,sha256=A_f8r3hWDVrQjzUR5CYzQMekPRIdG-l7Wjh9Hx492Xk,42425
|
|
44
|
+
glaip_sdk/utils/rendering/renderer/config.py,sha256=-P35z9JO_1ypJXAqxJ1ybHraH4i-I1LPopeW3Lh7ACE,785
|
|
45
45
|
glaip_sdk/utils/rendering/renderer/console.py,sha256=4cLOw4Q1fkHkApuj6dWW8eYpeYdcT0t2SO5MbVt5UTc,1844
|
|
46
46
|
glaip_sdk/utils/rendering/renderer/debug.py,sha256=FEYxAu4ZB0CjrJKevqQ2TKDgElA2cf6GqZXCNm12sNQ,3721
|
|
47
47
|
glaip_sdk/utils/rendering/renderer/panels.py,sha256=05u6SjU53iP9VD0YHTNruzD7sO6qYCp-P5dTTSdSZmU,3364
|
|
@@ -53,7 +53,7 @@ glaip_sdk/utils/rich_utils.py,sha256=-Ij-1bIJvnVAi6DrfftchIlMcvOTjVmSE0Qqax0EY_s
|
|
|
53
53
|
glaip_sdk/utils/run_renderer.py,sha256=d_VMI6LbvHPUUeRmGqh5wK_lHqDEIAcym2iqpbtDad0,1365
|
|
54
54
|
glaip_sdk/utils/serialization.py,sha256=cUE6PxqTsfJuEEmsk_Li3QmaDavTIPotEA-BQ-v5exY,9043
|
|
55
55
|
glaip_sdk/utils/validation.py,sha256=QNORcdyvuliEs4EH2_mkDgmoyT9utgl7YNhaf45SEf8,6992
|
|
56
|
-
glaip_sdk-0.0.
|
|
57
|
-
glaip_sdk-0.0.
|
|
58
|
-
glaip_sdk-0.0.
|
|
59
|
-
glaip_sdk-0.0.
|
|
56
|
+
glaip_sdk-0.0.10.dist-info/METADATA,sha256=ryaYhShJ7h43sX_oXbkLdKqpy5-eRgAP0lDczHVkCog,4950
|
|
57
|
+
glaip_sdk-0.0.10.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
58
|
+
glaip_sdk-0.0.10.dist-info/entry_points.txt,sha256=EGs8NO8J1fdFMWA3CsF7sKBEvtHb_fujdCoNPhfMouE,47
|
|
59
|
+
glaip_sdk-0.0.10.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|