glaip-sdk 0.6.5b3__py3-none-any.whl → 0.7.17__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/__init__.py +42 -5
- glaip_sdk/agents/base.py +362 -39
- 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 +15 -12
- glaip_sdk/cli/commands/configure.py +2 -3
- 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/core/output.py +12 -7
- glaip_sdk/cli/entrypoint.py +20 -0
- glaip_sdk/cli/main.py +127 -39
- glaip_sdk/cli/pager.py +3 -3
- glaip_sdk/cli/resolution.py +2 -1
- glaip_sdk/cli/slash/accounts_controller.py +112 -32
- glaip_sdk/cli/slash/agent_session.py +5 -2
- glaip_sdk/cli/slash/prompt.py +11 -0
- glaip_sdk/cli/slash/remote_runs_controller.py +3 -1
- glaip_sdk/cli/slash/session.py +375 -25
- glaip_sdk/cli/slash/tui/__init__.py +28 -1
- glaip_sdk/cli/slash/tui/accounts.tcss +97 -6
- glaip_sdk/cli/slash/tui/accounts_app.py +1107 -126
- glaip_sdk/cli/slash/tui/clipboard.py +195 -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 +152 -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 +5 -3
- 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 +290 -16
- 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 +414 -3
- glaip_sdk/client/schedules.py +439 -0
- glaip_sdk/client/tools.py +57 -26
- glaip_sdk/config/constants.py +22 -2
- glaip_sdk/guardrails/__init__.py +80 -0
- glaip_sdk/guardrails/serializer.py +89 -0
- glaip_sdk/hitl/__init__.py +48 -0
- glaip_sdk/hitl/base.py +64 -0
- glaip_sdk/hitl/callback.py +43 -0
- glaip_sdk/hitl/local.py +121 -0
- 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/registry/tool.py +273 -66
- glaip_sdk/runner/__init__.py +76 -0
- glaip_sdk/runner/base.py +84 -0
- glaip_sdk/runner/deps.py +115 -0
- glaip_sdk/runner/langgraph.py +1055 -0
- glaip_sdk/runner/logging_config.py +77 -0
- glaip_sdk/runner/mcp_adapter/__init__.py +13 -0
- glaip_sdk/runner/mcp_adapter/base_mcp_adapter.py +43 -0
- glaip_sdk/runner/mcp_adapter/langchain_mcp_adapter.py +257 -0
- glaip_sdk/runner/mcp_adapter/mcp_config_builder.py +116 -0
- glaip_sdk/runner/tool_adapter/__init__.py +18 -0
- glaip_sdk/runner/tool_adapter/base_tool_adapter.py +44 -0
- glaip_sdk/runner/tool_adapter/langchain_tool_adapter.py +242 -0
- 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/a2a/__init__.py +34 -0
- glaip_sdk/utils/a2a/event_processor.py +188 -0
- glaip_sdk/utils/agent_config.py +8 -2
- glaip_sdk/utils/bundler.py +138 -2
- glaip_sdk/utils/import_resolver.py +43 -11
- glaip_sdk/utils/rendering/renderer/base.py +58 -0
- glaip_sdk/utils/runtime_config.py +120 -0
- glaip_sdk/utils/sync.py +31 -11
- glaip_sdk/utils/tool_detection.py +301 -0
- glaip_sdk/utils/tool_storage_provider.py +140 -0
- {glaip_sdk-0.6.5b3.dist-info → glaip_sdk-0.7.17.dist-info}/METADATA +49 -38
- glaip_sdk-0.7.17.dist-info/RECORD +224 -0
- {glaip_sdk-0.6.5b3.dist-info → glaip_sdk-0.7.17.dist-info}/WHEEL +2 -1
- glaip_sdk-0.7.17.dist-info/entry_points.txt +2 -0
- glaip_sdk-0.7.17.dist-info/top_level.txt +1 -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.5b3.dist-info/RECORD +0 -145
- glaip_sdk-0.6.5b3.dist-info/entry_points.txt +0 -3
|
@@ -151,79 +151,149 @@ class AccountsController:
|
|
|
151
151
|
|
|
152
152
|
def _render_textual(self, rows: list[dict[str, str | bool]], store: AccountStore, env_lock: bool) -> None:
|
|
153
153
|
"""Launch the Textual accounts browser."""
|
|
154
|
-
|
|
154
|
+
active_before = store.get_active_account()
|
|
155
|
+
notified = False
|
|
156
|
+
|
|
157
|
+
def _switch_in_textual(name: str) -> tuple[bool, str]:
|
|
158
|
+
nonlocal notified
|
|
159
|
+
switched, message = self._switch_account(
|
|
160
|
+
store,
|
|
161
|
+
name,
|
|
162
|
+
env_lock,
|
|
163
|
+
emit_console=False,
|
|
164
|
+
invalidate_session=True,
|
|
165
|
+
)
|
|
166
|
+
if switched:
|
|
167
|
+
notified = True
|
|
168
|
+
return switched, message
|
|
169
|
+
|
|
170
|
+
callbacks = AccountsTUICallbacks(switch_account=_switch_in_textual)
|
|
155
171
|
active = next((row["name"] for row in rows if row.get("active")), None)
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
172
|
+
try:
|
|
173
|
+
# Inject TUI context for theme support
|
|
174
|
+
tui_ctx = getattr(self.session, "tui_ctx", None)
|
|
175
|
+
run_accounts_textual(rows, active_account=active, env_lock=env_lock, callbacks=callbacks, ctx=tui_ctx)
|
|
176
|
+
except Exception as exc: # pragma: no cover - defensive around Textual failures
|
|
177
|
+
self.console.print(f"[{WARNING_STYLE}]Accounts browser exited unexpectedly: {exc}[/]")
|
|
178
|
+
|
|
179
|
+
# Exit snapshot: surface a success banner when a switch occurred inside the TUI.
|
|
180
|
+
# Always notify when the active account changed, even if Textual raised.
|
|
181
|
+
active_after = store.get_active_account()
|
|
182
|
+
if active_after != active_before and not notified:
|
|
183
|
+
self._notify_account_switched(active_after)
|
|
159
184
|
if active_after != active:
|
|
160
185
|
host_after = ""
|
|
161
|
-
|
|
186
|
+
display_account = active_after or "default"
|
|
187
|
+
account_after = store.get_account(display_account) if hasattr(store, "get_account") else None
|
|
162
188
|
if account_after:
|
|
163
189
|
host_after = account_after.get("api_url", "")
|
|
164
190
|
host_suffix = f" • {host_after}" if host_after else ""
|
|
165
191
|
self.console.print(
|
|
166
192
|
AIPPanel(
|
|
167
|
-
f"[{SUCCESS_STYLE}]Active account ➜ {
|
|
193
|
+
f"[{SUCCESS_STYLE}]Active account ➜ {display_account}[/]{host_suffix}",
|
|
168
194
|
title="✅ Account Switched",
|
|
169
195
|
border_style=SUCCESS_STYLE,
|
|
170
196
|
)
|
|
171
197
|
)
|
|
172
198
|
|
|
173
|
-
def
|
|
174
|
-
"""
|
|
199
|
+
def _format_connection_error_message(self, error_reason: str, account_name: str, api_url: str) -> str:
|
|
200
|
+
"""Format error message for connection validation failures."""
|
|
201
|
+
code, detail = self._parse_error_reason(error_reason)
|
|
202
|
+
if code == "connection_failed":
|
|
203
|
+
return f"Switch aborted: cannot reach {api_url}. Check URL or network."
|
|
204
|
+
if code == "api_failed":
|
|
205
|
+
return f"Switch aborted: API error for '{account_name}'. Check credentials."
|
|
206
|
+
detail_suffix = f": {detail}" if detail else ""
|
|
207
|
+
return f"Switch aborted: {code or 'Validation failed'}{detail_suffix}"
|
|
208
|
+
|
|
209
|
+
def _emit_error_message(self, msg: str, style: str = ERROR_STYLE) -> None:
|
|
210
|
+
"""Emit an error or warning message to the console."""
|
|
211
|
+
self.console.print(f"[{style}]{msg}[/]")
|
|
212
|
+
|
|
213
|
+
def _validate_account_switch(
|
|
214
|
+
self, store: AccountStore, name: str, env_lock: bool, emit_console: bool
|
|
215
|
+
) -> tuple[bool, str, dict[str, str] | None]:
|
|
216
|
+
"""Validate account switch prerequisites; returns (is_valid, error_msg, account_dict)."""
|
|
175
217
|
if env_lock:
|
|
176
218
|
msg = "Env credentials detected (AIP_API_URL/AIP_API_KEY); switching is disabled."
|
|
177
|
-
|
|
178
|
-
|
|
219
|
+
if emit_console:
|
|
220
|
+
self._emit_error_message(msg, WARNING_STYLE)
|
|
221
|
+
return False, msg, None
|
|
179
222
|
|
|
180
223
|
account = store.get_account(name)
|
|
181
224
|
if not account:
|
|
182
225
|
msg = f"Account '{name}' not found."
|
|
183
|
-
|
|
184
|
-
|
|
226
|
+
if emit_console:
|
|
227
|
+
self._emit_error_message(msg)
|
|
228
|
+
return False, msg, None
|
|
185
229
|
|
|
186
230
|
api_url = account.get("api_url", "")
|
|
187
231
|
api_key = account.get("api_key", "")
|
|
188
232
|
if not api_url or not api_key:
|
|
189
233
|
edit_cmd = f"aip accounts edit {name}"
|
|
190
234
|
msg = f"Account '{name}' is missing credentials. Use `/login` or `{edit_cmd}`."
|
|
191
|
-
|
|
192
|
-
|
|
235
|
+
if emit_console:
|
|
236
|
+
self._emit_error_message(msg)
|
|
237
|
+
return False, msg, None
|
|
193
238
|
|
|
194
239
|
ok, error_reason = check_connection_with_reason(api_url, api_key, abort_on_error=False)
|
|
195
240
|
if not ok:
|
|
196
|
-
|
|
197
|
-
if
|
|
198
|
-
msg
|
|
199
|
-
|
|
200
|
-
msg = f"Switch aborted: API error for '{name}'. Check credentials."
|
|
201
|
-
else:
|
|
202
|
-
detail_suffix = f": {detail}" if detail else ""
|
|
203
|
-
msg = f"Switch aborted: {code or 'Validation failed'}{detail_suffix}"
|
|
204
|
-
self.console.print(f"[{WARNING_STYLE}]{msg}[/]")
|
|
205
|
-
return False, msg
|
|
241
|
+
msg = self._format_connection_error_message(error_reason, name, api_url)
|
|
242
|
+
if emit_console:
|
|
243
|
+
self._emit_error_message(msg, WARNING_STYLE)
|
|
244
|
+
return False, msg, None
|
|
206
245
|
|
|
246
|
+
return True, "", account
|
|
247
|
+
|
|
248
|
+
def _execute_account_switch(
|
|
249
|
+
self, store: AccountStore, name: str, account: dict[str, str], invalidate_session: bool, emit_console: bool
|
|
250
|
+
) -> tuple[bool, str]:
|
|
251
|
+
"""Execute the account switch and emit success message."""
|
|
207
252
|
try:
|
|
208
253
|
store.set_active_account(name)
|
|
254
|
+
api_url = account.get("api_url", "")
|
|
255
|
+
api_key = account.get("api_key", "")
|
|
209
256
|
masked_key = mask_api_key_display(api_key)
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
257
|
+
if invalidate_session:
|
|
258
|
+
self._notify_account_switched(name)
|
|
259
|
+
if emit_console:
|
|
260
|
+
self.console.print(
|
|
261
|
+
AIPPanel(
|
|
262
|
+
f"[{SUCCESS_STYLE}]Active account ➜ {name}[/]\nAPI URL: {api_url}\nKey: {masked_key}",
|
|
263
|
+
title="✅ Account Switched",
|
|
264
|
+
border_style=SUCCESS_STYLE,
|
|
265
|
+
)
|
|
215
266
|
)
|
|
216
|
-
)
|
|
217
267
|
return True, f"Switched to '{name}'."
|
|
218
268
|
except AccountStoreError as exc:
|
|
219
269
|
msg = f"Failed to set active account: {exc}"
|
|
220
|
-
|
|
270
|
+
if emit_console:
|
|
271
|
+
self._emit_error_message(msg)
|
|
221
272
|
return False, msg
|
|
222
273
|
except Exception as exc: # NOSONAR(S1045) - catch-all needed for unexpected errors
|
|
223
274
|
msg = f"Unexpected error while switching to '{name}': {exc}"
|
|
224
|
-
|
|
275
|
+
if emit_console:
|
|
276
|
+
self._emit_error_message(msg)
|
|
225
277
|
return False, msg
|
|
226
278
|
|
|
279
|
+
def _switch_account(
|
|
280
|
+
self,
|
|
281
|
+
store: AccountStore,
|
|
282
|
+
name: str,
|
|
283
|
+
env_lock: bool,
|
|
284
|
+
*,
|
|
285
|
+
emit_console: bool = True,
|
|
286
|
+
invalidate_session: bool = True,
|
|
287
|
+
) -> tuple[bool, str]:
|
|
288
|
+
"""Validate and switch active account; returns (success, message)."""
|
|
289
|
+
is_valid, error_msg, account = self._validate_account_switch(store, name, env_lock, emit_console)
|
|
290
|
+
if not is_valid:
|
|
291
|
+
return False, error_msg
|
|
292
|
+
|
|
293
|
+
if account is None: # Defensive – should never happen, but avoid crashing in production
|
|
294
|
+
return False, "Unable to locate account after validation."
|
|
295
|
+
return self._execute_account_switch(store, name, account, invalidate_session, emit_console)
|
|
296
|
+
|
|
227
297
|
@staticmethod
|
|
228
298
|
def _parse_error_reason(reason: str | None) -> tuple[str, str]:
|
|
229
299
|
"""Parse error reason into (code, detail) to avoid fragile substring checks."""
|
|
@@ -404,8 +474,18 @@ class AccountsController:
|
|
|
404
474
|
except Exception as exc:
|
|
405
475
|
self.console.print(f"[{WARNING_STYLE}]Account saved but could not set active: {exc}[/]")
|
|
406
476
|
else:
|
|
477
|
+
self._notify_account_switched(name)
|
|
407
478
|
self._announce_active_change(store, name)
|
|
408
479
|
|
|
480
|
+
def _notify_account_switched(self, name: str | None) -> None:
|
|
481
|
+
"""Best-effort notify the hosting session that the active account changed."""
|
|
482
|
+
notify = getattr(self.session, "on_account_switched", None)
|
|
483
|
+
if callable(notify):
|
|
484
|
+
try:
|
|
485
|
+
notify(name)
|
|
486
|
+
except Exception: # pragma: no cover - best-effort callback
|
|
487
|
+
pass
|
|
488
|
+
|
|
409
489
|
def _confirm_delete_prompt(self, name: str) -> bool:
|
|
410
490
|
"""Ask for delete confirmation; return True when confirmed."""
|
|
411
491
|
self.console.print(f"[{WARNING_STYLE}]Type '{name}' to confirm deletion. This cannot be undone.[/]")
|
|
@@ -17,7 +17,7 @@ from glaip_sdk.cli.commands.agents import run as agents_run_command
|
|
|
17
17
|
from glaip_sdk.cli.constants import DEFAULT_AGENT_INSTRUCTION_PREVIEW_LIMIT
|
|
18
18
|
from glaip_sdk.cli.hints import format_command_hint
|
|
19
19
|
from glaip_sdk.cli.slash.prompt import _HAS_PROMPT_TOOLKIT, FormattedText
|
|
20
|
-
from glaip_sdk.cli.
|
|
20
|
+
from glaip_sdk.cli.core.context import bind_slash_session_context
|
|
21
21
|
|
|
22
22
|
if TYPE_CHECKING: # pragma: no cover - type checking only
|
|
23
23
|
from glaip_sdk.cli.slash.session import SlashSession
|
|
@@ -38,7 +38,10 @@ class AgentRunSession:
|
|
|
38
38
|
self.console = session.console
|
|
39
39
|
self._agent_id = str(getattr(agent, "id", ""))
|
|
40
40
|
self._agent_name = getattr(agent, "name", "") or self._agent_id
|
|
41
|
-
self._prompt_placeholder: str =
|
|
41
|
+
self._prompt_placeholder: str = (
|
|
42
|
+
"Chat with this agent here; use / for shortcuts. "
|
|
43
|
+
"Alt+Enter inserts a newline. Ctrl+T opens the last transcript."
|
|
44
|
+
)
|
|
42
45
|
self._contextual_completion_help: dict[str, str] = {
|
|
43
46
|
"details": "Show this agent's configuration (+ expands prompt).",
|
|
44
47
|
"help": "Display this context-aware menu.",
|
glaip_sdk/cli/slash/prompt.py
CHANGED
|
@@ -162,6 +162,17 @@ def _create_key_bindings(_session: SlashSession) -> Any:
|
|
|
162
162
|
if buffer.complete_state is not None:
|
|
163
163
|
buffer.cancel_completion()
|
|
164
164
|
|
|
165
|
+
@bindings.add("c-t") # type: ignore[misc]
|
|
166
|
+
def _handle_ctrl_t_key(event: Any) -> None: # vulture: ignore
|
|
167
|
+
"""Handle Ctrl+T key - open the transcript viewer (when available)."""
|
|
168
|
+
buffer = event.app.current_buffer
|
|
169
|
+
if buffer.complete_state is not None:
|
|
170
|
+
buffer.cancel_completion()
|
|
171
|
+
|
|
172
|
+
open_viewer = getattr(_session, "open_transcript_viewer", None)
|
|
173
|
+
if callable(open_viewer):
|
|
174
|
+
open_viewer(announce=True)
|
|
175
|
+
|
|
165
176
|
return bindings
|
|
166
177
|
|
|
167
178
|
|
|
@@ -30,7 +30,7 @@ from glaip_sdk.branding import (
|
|
|
30
30
|
)
|
|
31
31
|
from glaip_sdk.cli.constants import DEFAULT_REMOTE_RUNS_PAGE_LIMIT
|
|
32
32
|
from glaip_sdk.cli.slash.tui.remote_runs_app import RemoteRunsTUICallbacks, run_remote_runs_textual
|
|
33
|
-
from glaip_sdk.cli.
|
|
33
|
+
from glaip_sdk.cli.core.prompting import prompt_export_choice_questionary, questionary_safe_ask
|
|
34
34
|
from glaip_sdk.exceptions import (
|
|
35
35
|
AuthenticationError,
|
|
36
36
|
ForbiddenError,
|
|
@@ -294,12 +294,14 @@ class RemoteRunsController:
|
|
|
294
294
|
fetch_detail=fetch_detail,
|
|
295
295
|
export_run=export_run,
|
|
296
296
|
)
|
|
297
|
+
tui_ctx = getattr(self.session, "tui_ctx", None)
|
|
297
298
|
page, limit, cursor = run_remote_runs_textual(
|
|
298
299
|
runs_page,
|
|
299
300
|
state.get("cursor", 0),
|
|
300
301
|
callbacks,
|
|
301
302
|
agent_name=agent_name,
|
|
302
303
|
agent_id=agent_id,
|
|
304
|
+
ctx=tui_ctx,
|
|
303
305
|
)
|
|
304
306
|
state["page"] = page
|
|
305
307
|
state["limit"] = limit
|