glaip-sdk 0.6.25__py3-none-any.whl → 0.7.0__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/cli/commands/agents/__init__.py +119 -0
- glaip_sdk/cli/commands/agents/_common.py +561 -0
- glaip_sdk/cli/commands/agents/create.py +151 -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/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/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/slash/tui/__init__.py +10 -1
- glaip_sdk/cli/slash/tui/context.py +51 -0
- glaip_sdk/cli/slash/tui/terminal.py +402 -0
- glaip_sdk/client/agents.py +1 -1
- glaip_sdk/client/main.py +1 -1
- 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} +22 -47
- glaip_sdk/client/payloads/agent/responses.py +43 -0
- glaip_sdk/client/tools.py +52 -23
- glaip_sdk/registry/tool.py +193 -81
- glaip_sdk/tools/base.py +41 -10
- glaip_sdk/utils/import_resolver.py +40 -2
- {glaip_sdk-0.6.25.dist-info → glaip_sdk-0.7.0.dist-info}/METADATA +2 -2
- {glaip_sdk-0.6.25.dist-info → glaip_sdk-0.7.0.dist-info}/RECORD +51 -18
- glaip_sdk/cli/commands/agents.py +0 -1502
- glaip_sdk/cli/commands/mcps.py +0 -1355
- glaip_sdk/cli/commands/tools.py +0 -575
- /glaip_sdk/cli/commands/{transcripts.py → transcripts_original.py} +0 -0
- {glaip_sdk-0.6.25.dist-info → glaip_sdk-0.7.0.dist-info}/WHEEL +0 -0
- {glaip_sdk-0.6.25.dist-info → glaip_sdk-0.7.0.dist-info}/entry_points.txt +0 -0
- {glaip_sdk-0.6.25.dist-info → glaip_sdk-0.7.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""Delete tool command.
|
|
2
|
+
|
|
3
|
+
Authors:
|
|
4
|
+
Raymond Christopher (raymond.christopher@gdplabs.id)
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from typing import Any
|
|
10
|
+
|
|
11
|
+
import click
|
|
12
|
+
|
|
13
|
+
from glaip_sdk.cli.context import get_ctx_value, output_flags
|
|
14
|
+
from glaip_sdk.cli.display import (
|
|
15
|
+
display_api_error,
|
|
16
|
+
display_confirmation_prompt,
|
|
17
|
+
display_deletion_success,
|
|
18
|
+
handle_json_output,
|
|
19
|
+
handle_rich_output,
|
|
20
|
+
)
|
|
21
|
+
from glaip_sdk.cli.core.rendering import spinner_context
|
|
22
|
+
|
|
23
|
+
from ._common import _get_tool_by_id_with_spinner, console, tools_group
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@tools_group.command()
|
|
27
|
+
@click.argument("tool_id")
|
|
28
|
+
@click.option("-y", "--yes", is_flag=True, help="Skip confirmation")
|
|
29
|
+
@output_flags()
|
|
30
|
+
@click.pass_context
|
|
31
|
+
def delete(ctx: Any, tool_id: str, yes: bool) -> None:
|
|
32
|
+
"""Delete a tool."""
|
|
33
|
+
try:
|
|
34
|
+
# Get tool by ID (no ambiguity handling needed)
|
|
35
|
+
tool = _get_tool_by_id_with_spinner(ctx, tool_id)
|
|
36
|
+
|
|
37
|
+
# Confirm deletion via centralized display helper
|
|
38
|
+
if not yes and not display_confirmation_prompt("Tool", tool.name):
|
|
39
|
+
return
|
|
40
|
+
|
|
41
|
+
with spinner_context(
|
|
42
|
+
ctx,
|
|
43
|
+
"[bold blue]Deleting tool…[/bold blue]",
|
|
44
|
+
console_override=console,
|
|
45
|
+
):
|
|
46
|
+
tool.delete()
|
|
47
|
+
|
|
48
|
+
handle_json_output(
|
|
49
|
+
ctx,
|
|
50
|
+
{
|
|
51
|
+
"success": True,
|
|
52
|
+
"message": f"Tool '{tool.name}' deleted",
|
|
53
|
+
},
|
|
54
|
+
)
|
|
55
|
+
handle_rich_output(ctx, display_deletion_success("Tool", tool.name))
|
|
56
|
+
|
|
57
|
+
except Exception as e:
|
|
58
|
+
handle_json_output(ctx, error=e)
|
|
59
|
+
if get_ctx_value(ctx, "view") != "json":
|
|
60
|
+
display_api_error(e, "tool deletion")
|
|
61
|
+
raise click.ClickException(str(e)) from e
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"""Get tool command.
|
|
2
|
+
|
|
3
|
+
Authors:
|
|
4
|
+
Raymond Christopher (raymond.christopher@gdplabs.id)
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
import click
|
|
13
|
+
|
|
14
|
+
from glaip_sdk.branding import WARNING_STYLE
|
|
15
|
+
from glaip_sdk.cli.context import output_flags
|
|
16
|
+
from glaip_sdk.cli.core.context import get_client
|
|
17
|
+
from glaip_sdk.cli.core.output import format_datetime_fields, handle_resource_export, output_result
|
|
18
|
+
from glaip_sdk.cli.core.rendering import spinner_context
|
|
19
|
+
from glaip_sdk.cli.io import fetch_raw_resource_details
|
|
20
|
+
from glaip_sdk.icons import ICON_TOOL
|
|
21
|
+
|
|
22
|
+
from ._common import _resolve_tool, console, tools_group
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@tools_group.command()
|
|
26
|
+
@click.argument("tool_ref")
|
|
27
|
+
@click.option("--select", type=int, help="Choose among ambiguous matches (1-based)")
|
|
28
|
+
@click.option(
|
|
29
|
+
"--export",
|
|
30
|
+
type=click.Path(dir_okay=False, writable=True),
|
|
31
|
+
help="Export complete tool configuration to file (format auto-detected from .json/.yaml extension)",
|
|
32
|
+
)
|
|
33
|
+
@output_flags()
|
|
34
|
+
@click.pass_context
|
|
35
|
+
def get(ctx: Any, tool_ref: str, select: int | None, export: str | None) -> None:
|
|
36
|
+
r"""Get tool details.
|
|
37
|
+
|
|
38
|
+
\b
|
|
39
|
+
Examples:
|
|
40
|
+
aip tools get my-tool
|
|
41
|
+
aip tools get my-tool --export tool.json # Exports complete configuration as JSON
|
|
42
|
+
aip tools get my-tool --export tool.yaml # Exports complete configuration as YAML
|
|
43
|
+
"""
|
|
44
|
+
try:
|
|
45
|
+
client = get_client(ctx)
|
|
46
|
+
|
|
47
|
+
# Resolve tool with ambiguity handling
|
|
48
|
+
tool = _resolve_tool(ctx, client, tool_ref, select)
|
|
49
|
+
|
|
50
|
+
# Handle export option
|
|
51
|
+
if export:
|
|
52
|
+
handle_resource_export(
|
|
53
|
+
ctx,
|
|
54
|
+
tool,
|
|
55
|
+
Path(export),
|
|
56
|
+
resource_type="tool",
|
|
57
|
+
get_by_id_func=client.get_tool_by_id,
|
|
58
|
+
console_override=console,
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
# Try to fetch raw API data first to preserve ALL fields
|
|
62
|
+
with spinner_context(
|
|
63
|
+
ctx,
|
|
64
|
+
"[bold blue]Fetching detailed tool data…[/bold blue]",
|
|
65
|
+
console_override=console,
|
|
66
|
+
):
|
|
67
|
+
raw_tool_data = fetch_raw_resource_details(client, tool, "tools")
|
|
68
|
+
|
|
69
|
+
if raw_tool_data:
|
|
70
|
+
# Use raw API data - this preserves ALL fields
|
|
71
|
+
# Format dates for better display (minimal postprocessing)
|
|
72
|
+
formatted_data = format_datetime_fields(raw_tool_data)
|
|
73
|
+
|
|
74
|
+
# Display using output_result with raw data
|
|
75
|
+
output_result(
|
|
76
|
+
ctx,
|
|
77
|
+
formatted_data,
|
|
78
|
+
title="Tool Details",
|
|
79
|
+
panel_title=f"{ICON_TOOL} {raw_tool_data.get('name', 'Unknown')}",
|
|
80
|
+
)
|
|
81
|
+
else:
|
|
82
|
+
# Fall back to original method if raw fetch fails
|
|
83
|
+
console.print(f"[{WARNING_STYLE}]Falling back to Pydantic model data[/]")
|
|
84
|
+
|
|
85
|
+
# Create result data with all available fields from backend
|
|
86
|
+
result_data = {
|
|
87
|
+
"id": str(getattr(tool, "id", "N/A")),
|
|
88
|
+
"name": getattr(tool, "name", "N/A"),
|
|
89
|
+
"tool_type": getattr(tool, "tool_type", "N/A"),
|
|
90
|
+
"framework": getattr(tool, "framework", "N/A"),
|
|
91
|
+
"version": getattr(tool, "version", "N/A"),
|
|
92
|
+
"description": getattr(tool, "description", "N/A"),
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
output_result(
|
|
96
|
+
ctx,
|
|
97
|
+
result_data,
|
|
98
|
+
title="Tool Details",
|
|
99
|
+
panel_title=f"{ICON_TOOL} {tool.name}",
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
except Exception as e:
|
|
103
|
+
raise click.ClickException(str(e)) from e
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"""List tools command.
|
|
2
|
+
|
|
3
|
+
Authors:
|
|
4
|
+
Raymond Christopher (raymond.christopher@gdplabs.id)
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from typing import Any
|
|
10
|
+
|
|
11
|
+
import click
|
|
12
|
+
|
|
13
|
+
from glaip_sdk.branding import ACCENT_STYLE, INFO
|
|
14
|
+
from glaip_sdk.cli.context import output_flags
|
|
15
|
+
from glaip_sdk.cli.core.context import get_client
|
|
16
|
+
from glaip_sdk.cli.core.output import coerce_to_row, output_list
|
|
17
|
+
from glaip_sdk.cli.core.rendering import spinner_context
|
|
18
|
+
from glaip_sdk.icons import ICON_TOOL
|
|
19
|
+
|
|
20
|
+
from ._common import console, tools_group
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@tools_group.command(name="list")
|
|
24
|
+
@output_flags()
|
|
25
|
+
@click.option(
|
|
26
|
+
"--type",
|
|
27
|
+
"tool_type",
|
|
28
|
+
help="Filter tools by type (e.g., custom, native)",
|
|
29
|
+
type=str,
|
|
30
|
+
required=False,
|
|
31
|
+
)
|
|
32
|
+
@click.pass_context
|
|
33
|
+
def list_tools(ctx: Any, tool_type: str | None) -> None:
|
|
34
|
+
"""List all tools."""
|
|
35
|
+
try:
|
|
36
|
+
client = get_client(ctx)
|
|
37
|
+
with spinner_context(
|
|
38
|
+
ctx,
|
|
39
|
+
"[bold blue]Fetching tools…[/bold blue]",
|
|
40
|
+
console_override=console,
|
|
41
|
+
):
|
|
42
|
+
tools = client.list_tools(tool_type=tool_type)
|
|
43
|
+
|
|
44
|
+
# Define table columns: (data_key, header, style, width)
|
|
45
|
+
columns = [
|
|
46
|
+
("id", "ID", "dim", 36),
|
|
47
|
+
("name", "Name", ACCENT_STYLE, None),
|
|
48
|
+
("framework", "Framework", INFO, None),
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
# Transform function for safe dictionary access
|
|
52
|
+
def transform_tool(tool: Any) -> dict[str, Any]:
|
|
53
|
+
"""Transform a tool object to a display row dictionary.
|
|
54
|
+
|
|
55
|
+
Args:
|
|
56
|
+
tool: Tool object to transform.
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
Dictionary with id, name, and framework fields.
|
|
60
|
+
"""
|
|
61
|
+
row = coerce_to_row(tool, ["id", "name", "framework"])
|
|
62
|
+
# Ensure id is always a string
|
|
63
|
+
row["id"] = str(row["id"])
|
|
64
|
+
return row
|
|
65
|
+
|
|
66
|
+
output_list(ctx, tools, f"{ICON_TOOL} Available Tools", columns, transform_tool)
|
|
67
|
+
|
|
68
|
+
except Exception as e:
|
|
69
|
+
raise click.ClickException(str(e)) from e
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"""Get tool script command.
|
|
2
|
+
|
|
3
|
+
Authors:
|
|
4
|
+
Raymond Christopher (raymond.christopher@gdplabs.id)
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import json
|
|
10
|
+
from typing import Any
|
|
11
|
+
|
|
12
|
+
import click
|
|
13
|
+
|
|
14
|
+
from glaip_sdk.branding import ERROR_STYLE, SUCCESS_STYLE
|
|
15
|
+
from glaip_sdk.cli.context import get_ctx_value, output_flags
|
|
16
|
+
from glaip_sdk.cli.core.context import get_client
|
|
17
|
+
from glaip_sdk.cli.core.rendering import spinner_context
|
|
18
|
+
from glaip_sdk.cli.display import handle_json_output
|
|
19
|
+
from glaip_sdk.cli.rich_helpers import print_markup
|
|
20
|
+
|
|
21
|
+
from ._common import console, tools_group
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@tools_group.command("script")
|
|
25
|
+
@click.argument("tool_id")
|
|
26
|
+
@output_flags()
|
|
27
|
+
@click.pass_context
|
|
28
|
+
def script(ctx: Any, tool_id: str) -> None:
|
|
29
|
+
"""Get tool script content."""
|
|
30
|
+
try:
|
|
31
|
+
client = get_client(ctx)
|
|
32
|
+
with spinner_context(
|
|
33
|
+
ctx,
|
|
34
|
+
"[bold blue]Fetching tool script…[/bold blue]",
|
|
35
|
+
console_override=console,
|
|
36
|
+
):
|
|
37
|
+
script_content = client.get_tool_script(tool_id)
|
|
38
|
+
|
|
39
|
+
if get_ctx_value(ctx, "view") == "json":
|
|
40
|
+
click.echo(json.dumps({"script": script_content}, indent=2))
|
|
41
|
+
else:
|
|
42
|
+
console.print(f"[{SUCCESS_STYLE}]📜 Tool Script for '{tool_id}':[/]")
|
|
43
|
+
console.print(script_content)
|
|
44
|
+
|
|
45
|
+
except Exception as e:
|
|
46
|
+
handle_json_output(ctx, error=e)
|
|
47
|
+
if get_ctx_value(ctx, "view") != "json":
|
|
48
|
+
print_markup(f"[{ERROR_STYLE}]Error getting tool script: {e}[/]", console=console)
|
|
49
|
+
raise click.ClickException(str(e)) from e
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"""Update tool command.
|
|
2
|
+
|
|
3
|
+
Authors:
|
|
4
|
+
Raymond Christopher (raymond.christopher@gdplabs.id)
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from typing import Any
|
|
10
|
+
|
|
11
|
+
import click
|
|
12
|
+
|
|
13
|
+
from glaip_sdk.branding import SUCCESS_STYLE, WARNING_STYLE
|
|
14
|
+
from glaip_sdk.cli.context import get_ctx_value, output_flags
|
|
15
|
+
from glaip_sdk.cli.display import display_api_error, display_update_success, handle_json_output, handle_rich_output
|
|
16
|
+
from glaip_sdk.cli.core.context import get_client
|
|
17
|
+
from glaip_sdk.cli.core.rendering import spinner_context
|
|
18
|
+
from glaip_sdk.cli.rich_helpers import markup_text
|
|
19
|
+
|
|
20
|
+
from ._common import _get_tool_by_id_with_spinner, console, tools_group
|
|
21
|
+
from .create import _parse_tags
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@tools_group.command()
|
|
25
|
+
@click.argument("tool_id")
|
|
26
|
+
@click.option(
|
|
27
|
+
"--file",
|
|
28
|
+
type=click.Path(exists=True),
|
|
29
|
+
help="New tool file for code update (custom tools only)",
|
|
30
|
+
)
|
|
31
|
+
@click.option("--description", help="New description")
|
|
32
|
+
@click.option("--tags", help="Comma-separated tags")
|
|
33
|
+
@output_flags()
|
|
34
|
+
@click.pass_context
|
|
35
|
+
def update(
|
|
36
|
+
ctx: Any,
|
|
37
|
+
tool_id: str,
|
|
38
|
+
file: str | None,
|
|
39
|
+
description: str | None,
|
|
40
|
+
tags: str | None,
|
|
41
|
+
) -> None:
|
|
42
|
+
"""Update a tool (code or metadata)."""
|
|
43
|
+
try:
|
|
44
|
+
client = get_client(ctx)
|
|
45
|
+
|
|
46
|
+
# Get tool by ID (no ambiguity handling needed)
|
|
47
|
+
tool = _get_tool_by_id_with_spinner(ctx, tool_id)
|
|
48
|
+
|
|
49
|
+
update_kwargs: dict[str, Any] = {}
|
|
50
|
+
if description is not None:
|
|
51
|
+
update_kwargs["description"] = description
|
|
52
|
+
if tags:
|
|
53
|
+
update_kwargs["tags"] = _parse_tags(tags)
|
|
54
|
+
|
|
55
|
+
if file:
|
|
56
|
+
# Update code via file upload (custom tools only)
|
|
57
|
+
if tool.tool_type != "custom":
|
|
58
|
+
raise click.ClickException(
|
|
59
|
+
"File updates are only supported for custom tools. "
|
|
60
|
+
f"Tool '{tool.name}' is of type '{tool.tool_type}'."
|
|
61
|
+
)
|
|
62
|
+
with spinner_context(
|
|
63
|
+
ctx,
|
|
64
|
+
"[bold blue]Uploading new tool code…[/bold blue]",
|
|
65
|
+
console_override=console,
|
|
66
|
+
):
|
|
67
|
+
updated_tool = client.tools.update_tool_via_file(
|
|
68
|
+
tool.id,
|
|
69
|
+
file,
|
|
70
|
+
framework=tool.framework,
|
|
71
|
+
**update_kwargs,
|
|
72
|
+
)
|
|
73
|
+
handle_rich_output(
|
|
74
|
+
ctx,
|
|
75
|
+
markup_text(f"[{SUCCESS_STYLE}]✓[/] Tool code updated from {file}"),
|
|
76
|
+
)
|
|
77
|
+
elif update_kwargs:
|
|
78
|
+
# Update metadata only (native tools only)
|
|
79
|
+
if tool.tool_type != "native":
|
|
80
|
+
raise click.ClickException(
|
|
81
|
+
"Metadata updates are only supported for native tools. "
|
|
82
|
+
f"Tool '{tool.name}' is of type '{tool.tool_type}'."
|
|
83
|
+
)
|
|
84
|
+
with spinner_context(
|
|
85
|
+
ctx,
|
|
86
|
+
"[bold blue]Updating tool metadata…[/bold blue]",
|
|
87
|
+
console_override=console,
|
|
88
|
+
):
|
|
89
|
+
updated_tool = client.tools.update_tool(tool, **update_kwargs)
|
|
90
|
+
handle_rich_output(ctx, markup_text(f"[{SUCCESS_STYLE}]✓[/] Tool metadata updated"))
|
|
91
|
+
else:
|
|
92
|
+
handle_rich_output(ctx, markup_text(f"[{WARNING_STYLE}]No updates specified[/]"))
|
|
93
|
+
return
|
|
94
|
+
|
|
95
|
+
handle_json_output(ctx, updated_tool.model_dump())
|
|
96
|
+
handle_rich_output(ctx, display_update_success("Tool", updated_tool.name))
|
|
97
|
+
|
|
98
|
+
except Exception as e:
|
|
99
|
+
handle_json_output(ctx, error=e)
|
|
100
|
+
if get_ctx_value(ctx, "view") != "json":
|
|
101
|
+
display_api_error(e, "tool update")
|
|
102
|
+
raise click.ClickException(str(e)) from e
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"""Transcript CLI commands package.
|
|
2
|
+
|
|
3
|
+
Authors:
|
|
4
|
+
Raymond Christopher (raymond.christopher@gdplabs.id)
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from glaip_sdk.cli.commands.transcripts._common import transcripts_group
|
|
8
|
+
from glaip_sdk.cli.commands.transcripts.clear import transcripts_clear
|
|
9
|
+
from glaip_sdk.cli.commands.transcripts.detail import transcripts_detail
|
|
10
|
+
|
|
11
|
+
# Import helper functions from original file for backward compatibility
|
|
12
|
+
# NOTE: Transcripts migration is deferred per spec (see resource-command-alignment/spec.md).
|
|
13
|
+
# NOTE: Migration is tracked in ../observability/transcript-storage-viewer-services/spec.md (Phase 0).
|
|
14
|
+
# This package currently re-exports from transcripts_original.py until the migration is completed.
|
|
15
|
+
from glaip_sdk.cli.commands.transcripts_original import ( # noqa: E402, type: ignore
|
|
16
|
+
_abbreviate_path,
|
|
17
|
+
_build_table,
|
|
18
|
+
_build_viewer_context,
|
|
19
|
+
_coerce_timestamp_to_float,
|
|
20
|
+
_collect_targets,
|
|
21
|
+
_confirm_deletion,
|
|
22
|
+
_decode_transcript,
|
|
23
|
+
_emit_warnings,
|
|
24
|
+
_format_duration,
|
|
25
|
+
_format_timestamp,
|
|
26
|
+
_format_timestamp_display,
|
|
27
|
+
_handle_clear_result,
|
|
28
|
+
_launch_transcript_viewer,
|
|
29
|
+
_load_transcript_text,
|
|
30
|
+
_maybe_launch_transcript_viewer,
|
|
31
|
+
_parse_event_received_timestamp,
|
|
32
|
+
_parse_transcript_line,
|
|
33
|
+
_print_snapshot,
|
|
34
|
+
_render_deletion_preview,
|
|
35
|
+
_render_detail_view,
|
|
36
|
+
_render_history_overview,
|
|
37
|
+
_render_transcript_display,
|
|
38
|
+
_resolve_transcript_path,
|
|
39
|
+
_row_label,
|
|
40
|
+
_should_exit_for_targets,
|
|
41
|
+
_should_use_transcript_viewer,
|
|
42
|
+
_transcripts_payload,
|
|
43
|
+
_validate_clear_options,
|
|
44
|
+
console,
|
|
45
|
+
sys,
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
# Import functions from other modules for test compatibility
|
|
49
|
+
from glaip_sdk.cli.transcript.history import load_history_snapshot # noqa: E402
|
|
50
|
+
from glaip_sdk.cli.transcript.viewer import run_viewer_session # noqa: E402
|
|
51
|
+
from glaip_sdk.utils.rendering.layout.panels import create_final_panel # noqa: E402
|
|
52
|
+
|
|
53
|
+
__all__ = [
|
|
54
|
+
"transcripts_group",
|
|
55
|
+
"transcripts_clear",
|
|
56
|
+
"transcripts_detail",
|
|
57
|
+
"_abbreviate_path",
|
|
58
|
+
"_build_table",
|
|
59
|
+
"_build_viewer_context",
|
|
60
|
+
"_coerce_timestamp_to_float",
|
|
61
|
+
"_collect_targets",
|
|
62
|
+
"_confirm_deletion",
|
|
63
|
+
"_decode_transcript",
|
|
64
|
+
"_emit_warnings",
|
|
65
|
+
"_format_duration",
|
|
66
|
+
"_format_timestamp",
|
|
67
|
+
"_format_timestamp_display",
|
|
68
|
+
"_handle_clear_result",
|
|
69
|
+
"_launch_transcript_viewer",
|
|
70
|
+
"_load_transcript_text",
|
|
71
|
+
"_maybe_launch_transcript_viewer",
|
|
72
|
+
"_parse_event_received_timestamp",
|
|
73
|
+
"_parse_transcript_line",
|
|
74
|
+
"_print_snapshot",
|
|
75
|
+
"_render_deletion_preview",
|
|
76
|
+
"_render_detail_view",
|
|
77
|
+
"_render_history_overview",
|
|
78
|
+
"_render_transcript_display",
|
|
79
|
+
"_resolve_transcript_path",
|
|
80
|
+
"_row_label",
|
|
81
|
+
"_should_exit_for_targets",
|
|
82
|
+
"_should_use_transcript_viewer",
|
|
83
|
+
"_transcripts_payload",
|
|
84
|
+
"_validate_clear_options",
|
|
85
|
+
"console",
|
|
86
|
+
"sys",
|
|
87
|
+
"load_history_snapshot",
|
|
88
|
+
"run_viewer_session",
|
|
89
|
+
"create_final_panel",
|
|
90
|
+
]
|
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
"""Textual UI helpers for slash commands."""
|
|
2
2
|
|
|
3
|
+
from glaip_sdk.cli.slash.tui.context import TUIContext
|
|
3
4
|
from glaip_sdk.cli.slash.tui.remote_runs_app import (
|
|
4
5
|
RemoteRunsTextualApp,
|
|
5
6
|
RemoteRunsTUICallbacks,
|
|
6
7
|
run_remote_runs_textual,
|
|
7
8
|
)
|
|
9
|
+
from glaip_sdk.cli.slash.tui.terminal import TerminalCapabilities, detect_terminal_background
|
|
8
10
|
|
|
9
|
-
__all__ = [
|
|
11
|
+
__all__ = [
|
|
12
|
+
"TUIContext",
|
|
13
|
+
"TerminalCapabilities",
|
|
14
|
+
"detect_terminal_background",
|
|
15
|
+
"RemoteRunsTextualApp",
|
|
16
|
+
"RemoteRunsTUICallbacks",
|
|
17
|
+
"run_remote_runs_textual",
|
|
18
|
+
]
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""Shared context for all TUI components.
|
|
2
|
+
|
|
3
|
+
This module provides the TUIContext dataclass, which serves as the Python equivalent
|
|
4
|
+
of OpenCode's nested provider pattern. It provides a single container for all TUI
|
|
5
|
+
services and state that can be injected into components.
|
|
6
|
+
|
|
7
|
+
Authors:
|
|
8
|
+
Raymond Christopher (raymond.christopher@gdplabs.id)
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from __future__ import annotations
|
|
12
|
+
|
|
13
|
+
from dataclasses import dataclass
|
|
14
|
+
|
|
15
|
+
from glaip_sdk.cli.slash.tui.terminal import TerminalCapabilities
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dataclass
|
|
19
|
+
class TUIContext:
|
|
20
|
+
"""Shared context for all TUI components (Python equivalent of OpenCode's providers).
|
|
21
|
+
|
|
22
|
+
This context provides access to all TUI services and state. Components that will
|
|
23
|
+
be implemented in later phases are typed as Optional and will be None initially.
|
|
24
|
+
|
|
25
|
+
Attributes:
|
|
26
|
+
terminal: Terminal capability detection results.
|
|
27
|
+
keybinds: Central keybind registry (Phase 3).
|
|
28
|
+
theme: Theme manager for light/dark mode and color tokens (Phase 2).
|
|
29
|
+
toasts: Toast notification bus (Phase 4).
|
|
30
|
+
clipboard: Clipboard adapter with OSC 52 support (Phase 4).
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
terminal: TerminalCapabilities
|
|
34
|
+
keybinds: object | None = None
|
|
35
|
+
theme: object | None = None
|
|
36
|
+
toasts: object | None = None
|
|
37
|
+
clipboard: object | None = None
|
|
38
|
+
|
|
39
|
+
@classmethod
|
|
40
|
+
async def create(cls) -> TUIContext:
|
|
41
|
+
"""Create a TUIContext instance with detected terminal capabilities.
|
|
42
|
+
|
|
43
|
+
This factory method detects terminal capabilities asynchronously and
|
|
44
|
+
returns a populated TUIContext instance. Other components (keybinds,
|
|
45
|
+
theme, toasts, clipboard) will be set incrementally as they are created.
|
|
46
|
+
|
|
47
|
+
Returns:
|
|
48
|
+
TUIContext instance with terminal capabilities detected.
|
|
49
|
+
"""
|
|
50
|
+
terminal = await TerminalCapabilities.detect()
|
|
51
|
+
return cls(terminal=terminal)
|