kiwi-code 0.0.447__tar.gz → 0.0.448__tar.gz
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.
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/PKG-INFO +5 -4
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/pyproject.toml +7 -4
- kiwi_code-0.0.448/scripts/ws_auth_check.py +76 -0
- kiwi_code-0.0.448/src/common/banner.py +57 -0
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/src/kiwi_cli/__init__.py +1 -2
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/src/kiwi_cli/checkpoints.py +0 -2
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/src/kiwi_cli/cli.py +2 -2
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/src/kiwi_cli/client.py +18 -20
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/src/kiwi_cli/commands.py +25 -19
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/src/kiwi_cli/terminal_mode.py +170 -165
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/src/kiwi_runtime/__init__.py +1 -2
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/src/kiwi_runtime/main.py +310 -107
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/src/kiwi_tui/__init__.py +1 -1
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/src/kiwi_tui/main.py +58 -214
- kiwi_code-0.0.448/src/kiwi_tui/role_mode.py +256 -0
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/src/kiwi_tui/runtime_agent.py +0 -3
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/src/kiwi_tui/screens/__init__.py +1 -2
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/src/kiwi_tui/screens/command_result.py +0 -10
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/src/kiwi_tui/screens/detach_files.py +1 -1
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/src/kiwi_tui/screens/id_picker.py +0 -19
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/src/kiwi_tui/screens/login.py +33 -62
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/src/kiwi_tui/screens/runtime_cleanup.py +2 -18
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/src/kiwi_tui/screens/runtime_logs.py +0 -9
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/src/kiwi_tui/screens/term_dashboard.py +856 -183
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/src/kiwi_tui/slash_commands.py +14 -33
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/src/kiwi_tui/widgets.py +26 -0
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/src/kiwi_tui/worktrees.py +0 -2
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/test_hello.py +2 -2
- kiwi_code-0.0.448/tests/__init__.py +0 -0
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/tests/conftest.py +9 -0
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/tests/test_cli_help.py +9 -13
- kiwi_code-0.0.448/tests/test_role_mode_injection.py +131 -0
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/tests/test_slash_commands.py +8 -0
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/tests/test_term_dashboard_ui.py +84 -13
- kiwi_code-0.0.448/tests/test_terminal_mode.py +47 -0
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/tests/test_tui_interactive_runtime.py +2 -90
- kiwi_code-0.0.448/uv.lock +1583 -0
- kiwi_code-0.0.447/CLAUDE.md +0 -79
- kiwi_code-0.0.447/src/kiwi_tui/screens/dashboard.py +0 -3870
- kiwi_code-0.0.447/tests/test_terminal_mode.py +0 -107
- kiwi_code-0.0.447/tests/test_tui_headless.py +0 -1099
- kiwi_code-0.0.447/uv.lock +0 -1460
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/.github/workflows/publish.yml +0 -0
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/.github/workflows/test.yml +0 -0
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/.gitignore +0 -0
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/.python-version +0 -0
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/Makefile +0 -0
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/README.md +0 -0
- {kiwi_code-0.0.447/tests → kiwi_code-0.0.448/src/common}/__init__.py +0 -0
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/src/kiwi_cli/auth.py +0 -0
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/src/kiwi_cli/logger.py +0 -0
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/src/kiwi_cli/models.py +0 -0
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/src/kiwi_cli/runtime_manager.py +0 -0
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/src/kiwi_cli/server.py +0 -0
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/src/kiwi_runtime/__main__.py +0 -0
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/src/kiwi_tui/inline_file_picker.py +0 -0
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/src/kiwi_tui/random_words.py +0 -0
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/src/kiwi_tui/screens/attach_content.py +0 -0
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/src/kiwi_tui/screens/file_browser.py +0 -0
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/src/kiwi_tui/screens/help.py +0 -0
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/src/kiwi_tui/screens/slash_picker.py +0 -0
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/src/kiwi_tui/status_words.py +0 -0
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/src/kiwi_tui/term_app.py +0 -0
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/src/kiwi_tui/ui_settings.py +0 -0
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/tests/test_batch_fs_tool.py +0 -0
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/tests/test_checkpoints.py +0 -0
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/tests/test_copy_path_fs_tool.py +0 -0
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/tests/test_imports.py +0 -0
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/tests/test_read_file_streaming.py +0 -0
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/tests/test_reexec_kiwi.py +0 -0
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/tests/test_runtime_log_trimming.py +0 -0
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/tests/test_search_in_files_fs_tool.py +0 -0
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/tests/test_tokens.py +0 -0
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/tests/test_tui_palette.py +0 -0
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/tests/test_unified_diff.py +0 -0
- {kiwi_code-0.0.447 → kiwi_code-0.0.448}/tests/test_worktrees.py +0 -0
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: kiwi-code
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.448
|
|
4
4
|
Summary: A textual-based terminal user interface application
|
|
5
|
-
Project-URL: Homepage, https://
|
|
5
|
+
Project-URL: Homepage, https://kiwicode.ai
|
|
6
6
|
Author-email: Anurag <anurag@meetkiwi.co>
|
|
7
7
|
License: Proprietary
|
|
8
8
|
Keywords: cli,terminal,textual,tui
|
|
@@ -14,11 +14,12 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.12
|
|
15
15
|
Classifier: Programming Language :: Python :: 3.13
|
|
16
16
|
Requires-Python: <4.0,>=3.11
|
|
17
|
-
Requires-Dist:
|
|
17
|
+
Requires-Dist: codeglass>=0.1.2
|
|
18
18
|
Requires-Dist: httpx>=0.25.0
|
|
19
19
|
Requires-Dist: loguru>=0.7.3
|
|
20
20
|
Requires-Dist: psutil>=5.9.0
|
|
21
21
|
Requires-Dist: pydantic>=2.12.5
|
|
22
|
+
Requires-Dist: pykiwiai==0.0.12
|
|
22
23
|
Requires-Dist: setproctitle>=1.3.0
|
|
23
24
|
Requires-Dist: textual-dev>=1.8.0
|
|
24
25
|
Requires-Dist: textual>=8.1.1
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "kiwi-code"
|
|
3
|
-
version = "0.0.
|
|
3
|
+
version = "0.0.448"
|
|
4
4
|
description = "A textual-based terminal user interface application"
|
|
5
5
|
readme = {file = "README.md", content-type = "text/markdown"}
|
|
6
6
|
requires-python = ">=3.11,<4.0"
|
|
7
7
|
dependencies = [
|
|
8
|
-
"
|
|
8
|
+
"pykiwiai==0.0.12",
|
|
9
9
|
"loguru>=0.7.3",
|
|
10
10
|
"pydantic>=2.12.5",
|
|
11
11
|
"textual>=8.1.1",
|
|
@@ -16,6 +16,7 @@ dependencies = [
|
|
|
16
16
|
"psutil>=5.9.0",
|
|
17
17
|
"setproctitle>=1.3.0",
|
|
18
18
|
"wonderwords>=2.2.0",
|
|
19
|
+
"codeglass>=0.1.2",
|
|
19
20
|
]
|
|
20
21
|
|
|
21
22
|
authors = [
|
|
@@ -34,7 +35,8 @@ classifiers = [
|
|
|
34
35
|
]
|
|
35
36
|
|
|
36
37
|
[project.urls]
|
|
37
|
-
Homepage = "https://
|
|
38
|
+
Homepage = "https://kiwicode.ai"
|
|
39
|
+
# Repository = "https://github.com/runkailabs/kiwi-code"
|
|
38
40
|
|
|
39
41
|
[project.scripts]
|
|
40
42
|
kiwi = "kiwi_tui.main:main"
|
|
@@ -54,8 +56,9 @@ filterwarnings = [
|
|
|
54
56
|
"ignore::DeprecationWarning",
|
|
55
57
|
]
|
|
56
58
|
|
|
59
|
+
|
|
57
60
|
[tool.hatch.build.targets.wheel]
|
|
58
|
-
packages = ["src/kiwi_cli", "src/kiwi_tui", "src/kiwi_runtime"]
|
|
61
|
+
packages = ["src/common", "src/kiwi_cli", "src/kiwi_tui", "src/kiwi_runtime"]
|
|
59
62
|
|
|
60
63
|
[build-system]
|
|
61
64
|
requires = ["hatchling"]
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"""Quick WS handshake + auth check.
|
|
2
|
+
|
|
3
|
+
Usage:
|
|
4
|
+
uv run python scripts/ws_auth_check.py --token "$ACCESS_TOKEN"
|
|
5
|
+
|
|
6
|
+
Notes:
|
|
7
|
+
- Pass the *raw* access token. If you paste "Bearer <token>", we will strip the prefix.
|
|
8
|
+
- This script does NOT print the token.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import argparse
|
|
12
|
+
import asyncio
|
|
13
|
+
import json
|
|
14
|
+
import os
|
|
15
|
+
import sys
|
|
16
|
+
import uuid
|
|
17
|
+
|
|
18
|
+
import websockets
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def _normalize_token(token: str) -> str:
|
|
22
|
+
t = token.strip()
|
|
23
|
+
if t.lower().startswith("bearer "):
|
|
24
|
+
t = t.split(" ", 1)[1].strip()
|
|
25
|
+
return t
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
async def main() -> None:
|
|
29
|
+
ap = argparse.ArgumentParser()
|
|
30
|
+
ap.add_argument("--token", required=True, help="Access token (raw JWT; 'Bearer ' prefix is ok)")
|
|
31
|
+
ap.add_argument(
|
|
32
|
+
"--ws-uri",
|
|
33
|
+
default="wss://api.meetkiwi.ai/v1/terminal/ws/connect",
|
|
34
|
+
help="Full ws connect URI (default: wss://api.meetkiwi.ai/v1/terminal/ws/connect)",
|
|
35
|
+
)
|
|
36
|
+
ap.add_argument(
|
|
37
|
+
"--mode",
|
|
38
|
+
default="restricted",
|
|
39
|
+
choices=["restricted", "full"],
|
|
40
|
+
help="Mode to send in auth payload (matches kiwi-runtime)",
|
|
41
|
+
)
|
|
42
|
+
args = ap.parse_args()
|
|
43
|
+
|
|
44
|
+
token = _normalize_token(args.token)
|
|
45
|
+
|
|
46
|
+
async with websockets.connect(
|
|
47
|
+
args.ws_uri,
|
|
48
|
+
ping_interval=None,
|
|
49
|
+
open_timeout=8,
|
|
50
|
+
close_timeout=3,
|
|
51
|
+
max_queue=8,
|
|
52
|
+
) as ws:
|
|
53
|
+
msg = {
|
|
54
|
+
"type": "auth",
|
|
55
|
+
"token": token,
|
|
56
|
+
"agent_id": str(uuid.uuid4()),
|
|
57
|
+
"platform": sys.platform,
|
|
58
|
+
"mode": args.mode,
|
|
59
|
+
"allowed_dirs": [os.getcwd()],
|
|
60
|
+
}
|
|
61
|
+
await ws.send(json.dumps(msg))
|
|
62
|
+
|
|
63
|
+
resp_raw = await asyncio.wait_for(ws.recv(), timeout=10)
|
|
64
|
+
resp = json.loads(resp_raw)
|
|
65
|
+
|
|
66
|
+
print("AUTH_RESP_TYPE", resp.get("type"))
|
|
67
|
+
print("AUTH_RESP_KEYS", sorted(resp.keys()))
|
|
68
|
+
if resp.get("type") == "error":
|
|
69
|
+
print("AUTH_ERROR_MESSAGE", (resp.get("message") or "").strip()[:300])
|
|
70
|
+
else:
|
|
71
|
+
safe = {k: resp.get(k) for k in ("type", "agent_id", "mode", "consumer_id", "message") if k in resp}
|
|
72
|
+
print("AUTH_RESP_SAFE", safe)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
if __name__ == "__main__":
|
|
76
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""Shared Kiwi Code banner assets used by kiwi-runtime and kiwi-tui."""
|
|
2
|
+
|
|
3
|
+
# Block-character chevron-and-dot logo (6 lines, 11 chars wide — same height as
|
|
4
|
+
# the KIWI CODE wordmark). Reads as ">." — half-blocks give the diagonal a
|
|
5
|
+
# half-row step so the stroke stays continuous instead of reading as a staircase.
|
|
6
|
+
LOGO = [
|
|
7
|
+
"▀██▄ ",
|
|
8
|
+
" ▀██▄ ",
|
|
9
|
+
" ▀██▄ ",
|
|
10
|
+
" ▄██▀ ",
|
|
11
|
+
" ▄██▀ ",
|
|
12
|
+
"▄██▀ █▌ ",
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
# "KIWI CODE" block text (6 lines tall).
|
|
16
|
+
TEXT = [
|
|
17
|
+
"██╗ ██╗██╗██╗ ██╗██╗ ██████╗ ██████╗ ██████╗ ███████╗",
|
|
18
|
+
"██║ ██╔╝██║██║ ██║██║ ██╔════╝██╔═══██╗██╔══██╗██╔════╝",
|
|
19
|
+
"█████╔╝ ██║██║ █╗ ██║██║ ██║ ██║ ██║██║ ██║█████╗ ",
|
|
20
|
+
"██╔═██╗ ██║██║███╗██║██║ ██║ ██║ ██║██║ ██║██╔══╝ ",
|
|
21
|
+
"██║ ██╗██║╚███╔███╔╝██║ ╚██████╗╚██████╔╝██████╔╝███████╗",
|
|
22
|
+
"╚═╝ ╚═╝╚═╝ ╚══╝╚══╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝",
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
TAGLINE = "Think fast. Code smarter. Automate everything."
|
|
26
|
+
|
|
27
|
+
# Brand color — darker cyan
|
|
28
|
+
CYAN = "rgb(0,168,184)"
|
|
29
|
+
CYAN_HEX = "#00a8b8"
|
|
30
|
+
|
|
31
|
+
# Layout constants (matching kiwi-runtime banner).
|
|
32
|
+
LOGO_W = 11
|
|
33
|
+
GAP = " "
|
|
34
|
+
TEXT_START = 0
|
|
35
|
+
TAGLINE_ROW = TEXT_START + len(TEXT) + 1
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def compose_banner_lines(tagline: str | None = None) -> list[str]:
|
|
39
|
+
"""Compose logo + KIWI CODE text side by side, returning a list of lines."""
|
|
40
|
+
effective_tagline = tagline if tagline is not None else TAGLINE
|
|
41
|
+
lines = []
|
|
42
|
+
# The logo is shorter than logo+tagline, so keep going past it with blanks.
|
|
43
|
+
for i in range(max(len(LOGO), TAGLINE_ROW + 1)):
|
|
44
|
+
padded = (LOGO[i] if i < len(LOGO) else "").ljust(LOGO_W)
|
|
45
|
+
text_idx = i - TEXT_START
|
|
46
|
+
if 0 <= text_idx < len(TEXT):
|
|
47
|
+
lines.append(f"{padded}{GAP}{TEXT[text_idx]}")
|
|
48
|
+
elif i == TAGLINE_ROW:
|
|
49
|
+
lines.append(f"{padded}{GAP}{effective_tagline}")
|
|
50
|
+
else:
|
|
51
|
+
lines.append(padded)
|
|
52
|
+
return lines
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def compose_banner_text(tagline: str | None = None) -> str:
|
|
56
|
+
"""Return the full banner as a single multi-line string."""
|
|
57
|
+
return "\n".join(compose_banner_lines(tagline=tagline))
|
|
@@ -3,14 +3,14 @@ from typing import Optional, Callable
|
|
|
3
3
|
from loguru import logger
|
|
4
4
|
logger.remove() # Suppress loguru console output in CLI mode
|
|
5
5
|
import typer
|
|
6
|
-
from
|
|
6
|
+
from pykiwiai import AuthenticatedClient
|
|
7
7
|
from .auth import TokenManager
|
|
8
8
|
from .models import AppConfig
|
|
9
9
|
from .server import http_url_from_server
|
|
10
10
|
from . import commands
|
|
11
11
|
from . import __version__ as KIWI_CLI_VERSION
|
|
12
12
|
|
|
13
|
-
app = typer.Typer(name="kiwi", help="Kiwi — interact with the Kiwi
|
|
13
|
+
app = typer.Typer(name="kiwi", help="Kiwi — interact with the Kiwi Code platform.")
|
|
14
14
|
|
|
15
15
|
actions_app = typer.Typer(name="actions", help="Manage actions.")
|
|
16
16
|
action_runs_app = typer.Typer(name="runs", help="Manage action runs (results).")
|
|
@@ -6,22 +6,20 @@ import json
|
|
|
6
6
|
import codecs
|
|
7
7
|
import httpx
|
|
8
8
|
from loguru import logger
|
|
9
|
-
from
|
|
10
|
-
from
|
|
11
|
-
from
|
|
9
|
+
from pykiwiai import Client, AuthenticatedClient
|
|
10
|
+
from pykiwiai.api.hello import hello_v1_hello_get
|
|
11
|
+
from pykiwiai.api.auth import (
|
|
12
12
|
return_user_and_session_v1_auth_post,
|
|
13
13
|
)
|
|
14
|
-
from
|
|
15
|
-
from
|
|
16
|
-
from
|
|
14
|
+
from pykiwiai.api.actions import async_run_action_v1_actions_id_async_run_post
|
|
15
|
+
from pykiwiai.api.action_results import get_action_result_v1_action_results_id_get
|
|
16
|
+
from pykiwiai.models.body_return_user_and_session_v1_auth_post import (
|
|
17
17
|
BodyReturnUserAndSessionV1AuthPost,
|
|
18
18
|
)
|
|
19
|
-
from
|
|
19
|
+
from pykiwiai.models.body_async_run_action_v1_actions_id_async_run_post import (
|
|
20
20
|
BodyAsyncRunActionV1ActionsIdAsyncRunPost,
|
|
21
21
|
)
|
|
22
|
-
from
|
|
23
|
-
BodyAsyncRunActionV1ActionsIdAsyncRunPostInput,
|
|
24
|
-
)
|
|
22
|
+
from pykiwiai.models import DataBlock, Metadata
|
|
25
23
|
from .models import AuthTokens, LoginCredentials
|
|
26
24
|
|
|
27
25
|
|
|
@@ -253,8 +251,8 @@ class AutobotsClientWrapper:
|
|
|
253
251
|
|
|
254
252
|
import mimetypes
|
|
255
253
|
from pathlib import Path
|
|
256
|
-
from
|
|
257
|
-
from
|
|
254
|
+
from pykiwiai.api.files import upload_files_v1_files_post
|
|
255
|
+
from pykiwiai.models.body_upload_files_v1_files_post import BodyUploadFilesV1FilesPost
|
|
258
256
|
|
|
259
257
|
# Validate all files exist first
|
|
260
258
|
paths = []
|
|
@@ -333,18 +331,17 @@ class AutobotsClientWrapper:
|
|
|
333
331
|
if metadata:
|
|
334
332
|
default_metadata.update(metadata)
|
|
335
333
|
|
|
336
|
-
input_data =
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
}
|
|
334
|
+
input_data = DataBlock(
|
|
335
|
+
text=user_input,
|
|
336
|
+
urls=urls or [],
|
|
337
|
+
metadata=Metadata.from_dict(default_metadata),
|
|
338
|
+
)
|
|
342
339
|
|
|
343
340
|
body = BodyAsyncRunActionV1ActionsIdAsyncRunPost(input_=input_data)
|
|
344
341
|
logger.info(f"Request body: {body.to_dict()}")
|
|
345
342
|
|
|
346
343
|
# Import UNSET for optional parameter
|
|
347
|
-
from
|
|
344
|
+
from pykiwiai.types import UNSET
|
|
348
345
|
|
|
349
346
|
response = async_run_action_v1_actions_id_async_run_post.sync_detailed(
|
|
350
347
|
id=action_id,
|
|
@@ -464,7 +461,8 @@ class AutobotsClientWrapper:
|
|
|
464
461
|
logger.info(f"Result structure keys: {result_dict.keys()}")
|
|
465
462
|
if "result" in result_dict and isinstance(result_dict["result"], dict):
|
|
466
463
|
logger.info(f"Result.result keys: {result_dict['result'].keys()}")
|
|
467
|
-
|
|
464
|
+
result = result_dict['result']
|
|
465
|
+
logger.info(f"Result's results : {result['results']}")
|
|
468
466
|
return True, result_dict, "Result retrieved"
|
|
469
467
|
else:
|
|
470
468
|
error_msg = f"Failed to get result: status {response.status_code}"
|
|
@@ -5,17 +5,17 @@ and returns a list of strings (output lines).
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
from typing import Optional
|
|
8
|
-
from
|
|
9
|
-
from
|
|
8
|
+
from pykiwiai import AuthenticatedClient
|
|
9
|
+
from pykiwiai.api.actions import (
|
|
10
10
|
list_actions_v1_actions_get,
|
|
11
11
|
get_action_v1_actions_id_get,
|
|
12
12
|
)
|
|
13
|
-
from
|
|
13
|
+
from pykiwiai.api.action_results import (
|
|
14
14
|
list_action_result_v1_action_results_get,
|
|
15
15
|
get_action_result_v1_action_results_id_get,
|
|
16
16
|
)
|
|
17
17
|
|
|
18
|
-
from
|
|
18
|
+
from pykiwiai.types import UNSET
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
# Helpers
|
|
@@ -35,6 +35,18 @@ def _val(v) -> str:
|
|
|
35
35
|
return str(v)
|
|
36
36
|
|
|
37
37
|
|
|
38
|
+
def _enum(v) -> str:
|
|
39
|
+
"""Return a stable string for either Enum-like objects or plain strings.
|
|
40
|
+
|
|
41
|
+
pykiwiai <=0.0.1 used Enum types (value attribute).
|
|
42
|
+
pykiwiai >=0.0.11 uses Literal[str] so fields are plain strings.
|
|
43
|
+
"""
|
|
44
|
+
if v is None or isinstance(v, type(UNSET)):
|
|
45
|
+
return ""
|
|
46
|
+
return str(getattr(v, "value", v))
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
38
50
|
# actions
|
|
39
51
|
|
|
40
52
|
def actions_list(client: AuthenticatedClient, *, name: Optional[str] = None, limit: int = 20, offset: int = 0) -> list[str]:
|
|
@@ -57,7 +69,7 @@ def actions_list(client: AuthenticatedClient, *, name: Optional[str] = None, lim
|
|
|
57
69
|
]
|
|
58
70
|
for doc in result.docs:
|
|
59
71
|
lines.append(
|
|
60
|
-
f"{doc.field_id:<28} {_val(doc.name):<30} {_val(doc.type_
|
|
72
|
+
f"{doc.field_id:<28} {_val(doc.name):<30} {_val(_enum(doc.type_)):<25} "
|
|
61
73
|
f"{_val(doc.version):<6} {_fmt_date(doc.created_at)}"
|
|
62
74
|
)
|
|
63
75
|
return lines
|
|
@@ -73,7 +85,7 @@ def actions_get(client: AuthenticatedClient, *, id: str) -> list[str]:
|
|
|
73
85
|
return [
|
|
74
86
|
f"ID: {doc.field_id}",
|
|
75
87
|
f"Name: {doc.name}",
|
|
76
|
-
f"Type: {doc.type_
|
|
88
|
+
f"Type: {_enum(doc.type_)}",
|
|
77
89
|
f"Version: {_val(doc.version)}",
|
|
78
90
|
f"Description: {_val(doc.description)}",
|
|
79
91
|
f"Published: {_val(doc.is_published)}",
|
|
@@ -88,13 +100,13 @@ def actions_get(client: AuthenticatedClient, *, id: str) -> list[str]:
|
|
|
88
100
|
def runs_list(client: AuthenticatedClient, *, action_id: Optional[str] = None, action_name: Optional[str] = None,
|
|
89
101
|
status: Optional[str] = None, limit: int = 20, offset: int = 0) -> list[str]:
|
|
90
102
|
"""List action runs. Returns output lines."""
|
|
91
|
-
from
|
|
103
|
+
from pykiwiai.models.event_result_status import check_event_result_status
|
|
92
104
|
|
|
93
105
|
status_enum = UNSET
|
|
94
106
|
if status:
|
|
95
107
|
try:
|
|
96
|
-
status_enum =
|
|
97
|
-
except
|
|
108
|
+
status_enum = check_event_result_status(status.lower())
|
|
109
|
+
except TypeError:
|
|
98
110
|
return [f"Invalid status: {status}. Valid: processing, success, error, stuck, waiting"]
|
|
99
111
|
|
|
100
112
|
resp = list_action_result_v1_action_results_get.sync_detailed(
|
|
@@ -117,7 +129,7 @@ def runs_list(client: AuthenticatedClient, *, action_id: Optional[str] = None, a
|
|
|
117
129
|
]
|
|
118
130
|
for doc in result.docs:
|
|
119
131
|
lines.append(
|
|
120
|
-
f"{doc.field_id:<28} {doc.status
|
|
132
|
+
f"{doc.field_id:<28} {_enum(doc.status):<12} {_val(doc.name):<30} "
|
|
121
133
|
f"{_fmt_date(doc.created_at):<18} {_fmt_date(doc.updated_at)}"
|
|
122
134
|
)
|
|
123
135
|
return lines
|
|
@@ -132,9 +144,9 @@ def runs_get(client: AuthenticatedClient, *, id: str) -> list[str]:
|
|
|
132
144
|
doc = resp.parsed
|
|
133
145
|
lines = [
|
|
134
146
|
f"ID: {doc.field_id}",
|
|
135
|
-
f"Status: {doc.status
|
|
147
|
+
f"Status: {_enum(doc.status)}",
|
|
136
148
|
f"Name: {_val(doc.name)}",
|
|
137
|
-
f"Type: {doc.type_
|
|
149
|
+
f"Type: {_enum(doc.type_)}",
|
|
138
150
|
f"Saved: {_val(doc.is_saved)}",
|
|
139
151
|
f"Created: {_fmt_date(doc.created_at)}",
|
|
140
152
|
f"Updated: {_fmt_date(doc.updated_at)}",
|
|
@@ -144,7 +156,7 @@ def runs_get(client: AuthenticatedClient, *, id: str) -> list[str]:
|
|
|
144
156
|
"",
|
|
145
157
|
"Action:",
|
|
146
158
|
f" Name: {doc.result.name}",
|
|
147
|
-
f" Type: {doc.result.type_
|
|
159
|
+
f" Type: {_enum(doc.result.type_)}",
|
|
148
160
|
f" ID: {doc.result.field_id}",
|
|
149
161
|
]
|
|
150
162
|
return lines
|
|
@@ -167,12 +179,6 @@ Files:
|
|
|
167
179
|
/files Show pending file uploads
|
|
168
180
|
/clear-files Clear pending file uploads
|
|
169
181
|
|
|
170
|
-
Metadata (persistent across runs):
|
|
171
|
-
/metadata Show current metadata
|
|
172
|
-
/metadata set <k> <v> Set a metadata field
|
|
173
|
-
/metadata remove <k> Remove a metadata field
|
|
174
|
-
/metadata clear Clear all metadata
|
|
175
|
-
|
|
176
182
|
Runtime:
|
|
177
183
|
/runtime status Show runtime status
|
|
178
184
|
/runtime start Start runtime
|