kiwi-code 0.0.512__tar.gz → 0.0.513__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.512 → kiwi_code-0.0.513}/PKG-INFO +1 -1
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/pyproject.toml +1 -1
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_cli/autocode.py +33 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_cli/terminal_mode.py +3 -2
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_tui/screens/term_dashboard.py +12 -5
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_autocode_actions.py +49 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_term_dashboard_ui.py +53 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/uv.lock +1 -1
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/.github/workflows/publish.yml +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/.github/workflows/test.yml +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/.gitignore +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/.python-version +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/Makefile +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/README.md +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/docs/runtime_audit.html +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/docs/social_login_e2e.md +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/scripts/set_edition.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/scripts/ws_auth_check.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/common/__init__.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/common/banner.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_cli/__init__.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_cli/_edition.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_cli/auth.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_cli/checkpoints.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_cli/cli.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_cli/client.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_cli/commands.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_cli/edition.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_cli/human_questions.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_cli/io_threads.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_cli/logger.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_cli/models.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_cli/oauth.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_cli/run_activity.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_cli/runtime_manager.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_cli/server.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_cli/subagents.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_runtime/__init__.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_runtime/__main__.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_runtime/auth.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_runtime/checkpoints.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_runtime/cli.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_runtime/commands.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_runtime/constants.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_runtime/fs/__init__.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_runtime/fs/batch.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_runtime/fs/codelens.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_runtime/fs/context.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_runtime/fs/edits.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_runtime/fs/handler.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_runtime/fs/paths.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_runtime/fs/read.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_runtime/fs/search.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_runtime/fs/text.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_runtime/fs/upload.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_runtime/fs/write.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_runtime/handlers.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_runtime/link.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_runtime/main.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_runtime/restricted.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_runtime/sessions.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_runtime/state.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_runtime/tui_bridge.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_runtime/ui.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_runtime/uploads.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_tui/__init__.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_tui/attention.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_tui/autoupdate.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_tui/inline_file_picker.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_tui/latex_unicode.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_tui/main.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_tui/random_words.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_tui/role_mode.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_tui/runtime_agent.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_tui/screens/__init__.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_tui/screens/attach_content.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_tui/screens/command_result.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_tui/screens/detach_files.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_tui/screens/file_browser.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_tui/screens/help.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_tui/screens/id_picker.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_tui/screens/login.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_tui/screens/runtime_cleanup.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_tui/screens/runtime_logs.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_tui/screens/slash_picker.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_tui/screens/term_activity_view.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_tui/screens/term_dashboard_css.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_tui/screens/term_dashboard_helpers.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_tui/screens/term_dashboard_widgets.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_tui/screens/term_question_widgets.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_tui/screens/term_status_line.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_tui/screens/term_subagent_widgets.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_tui/slash_commands.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_tui/status_words.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_tui/term_app.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_tui/terminal_theme.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_tui/ui_settings.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_tui/widgets.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/src/kiwi_tui/worktrees.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/test_hello.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/__init__.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/conftest.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_account_server.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_attention.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_autoupdate.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_batch_fs_tool.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_checkpoints.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_cli_help.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_command_tips.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_copy_path_fs_tool.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_fs_edit_fidelity.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_human_questions.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_imports.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_io_threads.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_login_social.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_math_and_tables.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_oauth.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_read_file_streaming.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_reexec_kiwi.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_reply_selection.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_role_mode_injection.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_run_activity.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_run_steering.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_runtime_cleanup_per_account.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_runtime_connection.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_runtime_edit_diffs.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_runtime_fixes.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_runtime_imports_on_windows.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_runtime_log_trimming.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_runtime_social_login.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_search_in_files_fs_tool.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_slash_commands.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_stats_command.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_status_line.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_subagents.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_terminal_mode.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_terminal_theme.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_toasts.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_tokens.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_tui_interactive_runtime.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_tui_palette.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_unified_diff.py +0 -0
- {kiwi_code-0.0.512 → kiwi_code-0.0.513}/tests/test_worktrees.py +0 -0
|
@@ -8,6 +8,11 @@ contains "autocode" in any spelling: "Autocode", "AutoCodeClaude",
|
|
|
8
8
|
When two of them have the same name ignoring case, spaces and punctuation
|
|
9
9
|
("AutocodeClaude" and "AutoCodeClaude", "Autocode OpenAI Flash" and
|
|
10
10
|
"AutocodeOpenaiFlash"), only the most recently created one is kept.
|
|
11
|
+
|
|
12
|
+
Which one a new session starts with depends on the account (``default_id_for``):
|
|
13
|
+
Work (Enterprise, api.meetkiwi.ai) starts with "Autocode OpenAI Flash", Personal
|
|
14
|
+
(Subscription, api.runkai.ai) and every other server with "Autocode". The VS Code
|
|
15
|
+
extension makes the same choice (src/defaultAgent.ts).
|
|
11
16
|
"""
|
|
12
17
|
|
|
13
18
|
import re
|
|
@@ -17,11 +22,17 @@ from datetime import datetime, timezone
|
|
|
17
22
|
from pykiwiai import AuthenticatedClient
|
|
18
23
|
from pykiwiai.api.actions import list_system_actions_v1_actions_system_actions_get
|
|
19
24
|
|
|
25
|
+
from kiwi_cli.server import SERVER_PRESETS
|
|
26
|
+
|
|
20
27
|
# Fetch every system action in one page: paging with offset is not reliable on
|
|
21
28
|
# the servers (offset > 0 returns an empty page).
|
|
22
29
|
_SYSTEM_ACTIONS_LIMIT = 500
|
|
23
30
|
|
|
24
31
|
|
|
32
|
+
#: The default on the Work (Enterprise) server, compared as _normalize compares names.
|
|
33
|
+
_ENTERPRISE_DEFAULT = "autocodeopenaiflash"
|
|
34
|
+
|
|
35
|
+
|
|
25
36
|
def _normalize(name: object) -> str:
|
|
26
37
|
return re.sub(r"[^a-z0-9]", "", str(name or "").lower())
|
|
27
38
|
|
|
@@ -64,6 +75,28 @@ class AutocodeActions:
|
|
|
64
75
|
return action.id
|
|
65
76
|
return self.actions[0].id if self.actions else None
|
|
66
77
|
|
|
78
|
+
def name_of(self, action_id: object) -> str | None:
|
|
79
|
+
"""The name of the AutoCode action ``action_id``, or None if it is not one."""
|
|
80
|
+
for action in self.actions:
|
|
81
|
+
if action.id == action_id:
|
|
82
|
+
return action.name
|
|
83
|
+
return None
|
|
84
|
+
|
|
85
|
+
def default_id_for(self, backend_url: object) -> str | None:
|
|
86
|
+
"""The action a new session starts with on ``backend_url``: "Autocode OpenAI
|
|
87
|
+
Flash" on the Work (Enterprise) server when it has one, else ``default_id``."""
|
|
88
|
+
if is_enterprise_backend(backend_url):
|
|
89
|
+
for action in self.actions:
|
|
90
|
+
if _normalize(action.name) == _ENTERPRISE_DEFAULT:
|
|
91
|
+
return action.id
|
|
92
|
+
return self.default_id
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def is_enterprise_backend(backend_url: object) -> bool:
|
|
96
|
+
"""True for the Work (Enterprise) server, api.meetkiwi.ai."""
|
|
97
|
+
url = str(backend_url or "").strip().rstrip("/").lower()
|
|
98
|
+
return url == SERVER_PRESETS["work"]["http"]
|
|
99
|
+
|
|
67
100
|
|
|
68
101
|
def _created(action: AutocodeAction) -> datetime:
|
|
69
102
|
"""When the action was created. Falls back to the timestamp in its ObjectId."""
|
|
@@ -227,10 +227,11 @@ def _default_action_id(session: _TerminalSession) -> str:
|
|
|
227
227
|
found = fetch_autocode_actions(session.client.client)
|
|
228
228
|
if found.status_code in (401, 403) and _refresh_tokens(session):
|
|
229
229
|
found = fetch_autocode_actions(session.client.client)
|
|
230
|
-
|
|
230
|
+
default_id = found.default_id_for(session.backend_url)
|
|
231
|
+
if default_id is None:
|
|
231
232
|
detail = "no AutoCode actions on this server" if found.ok else f"HTTP {found.status_code}"
|
|
232
233
|
raise TerminalModeError(f"Could not find the AutoCode action ({detail}). Pass --action-id to choose one.")
|
|
233
|
-
return
|
|
234
|
+
return default_id
|
|
234
235
|
|
|
235
236
|
|
|
236
237
|
def _build_authenticated_session(server: str | None) -> _TerminalSession:
|
|
@@ -1503,7 +1503,8 @@ class TermDashboardScreen(Screen):
|
|
|
1503
1503
|
cwd = str(Path.cwd())
|
|
1504
1504
|
cwd_short = cwd if len(cwd) <= 44 else f"{cwd[:20]}…{cwd[-20:]}"
|
|
1505
1505
|
|
|
1506
|
-
|
|
1506
|
+
# While its name loads, an action shows as "…", not as its id.
|
|
1507
|
+
action = self.current_action_name or ("…" if self.current_action_id else "")
|
|
1507
1508
|
action = str(action)
|
|
1508
1509
|
action_short = action if len(action) <= 16 else (action[:12] + "…")
|
|
1509
1510
|
|
|
@@ -1643,7 +1644,7 @@ class TermDashboardScreen(Screen):
|
|
|
1643
1644
|
def _refresh_welcome_meta(self) -> None:
|
|
1644
1645
|
"""Update action name + run id displayed in the welcome header."""
|
|
1645
1646
|
try:
|
|
1646
|
-
action = self.current_action_name or self.current_action_id
|
|
1647
|
+
action = self.current_action_name or ("…" if self.current_action_id else "—")
|
|
1647
1648
|
run = self.current_run_id or "—"
|
|
1648
1649
|
self.query_one("#term-welcome-account", Static).update(self._account_text())
|
|
1649
1650
|
self.query_one("#term-welcome-action", Static).update(f"Action: {action}")
|
|
@@ -1764,9 +1765,14 @@ class TermDashboardScreen(Screen):
|
|
|
1764
1765
|
except Exception as e:
|
|
1765
1766
|
logger.debug(f"Loading AutoCode actions failed: {e}")
|
|
1766
1767
|
if not self.current_action_id and self._autocode is not None:
|
|
1767
|
-
self.current_action_id = self._autocode.
|
|
1768
|
+
self.current_action_id = self._autocode.default_id_for(self._autocode_backend) or ""
|
|
1768
1769
|
requested_id = self.current_action_id
|
|
1769
|
-
|
|
1770
|
+
# An AutoCode action's name is already in the list just fetched: show it with the
|
|
1771
|
+
# id, rather than the id first and the name a request later.
|
|
1772
|
+
known = self._autocode.name_of(requested_id) if self._autocode is not None and requested_id else None
|
|
1773
|
+
if known and not self.current_action_name:
|
|
1774
|
+
self.current_action_name = known
|
|
1775
|
+
if not requested_id or known:
|
|
1770
1776
|
self._refresh_top_bar()
|
|
1771
1777
|
self._refresh_hint_model()
|
|
1772
1778
|
self._refresh_input_label()
|
|
@@ -1779,7 +1785,8 @@ class TermDashboardScreen(Screen):
|
|
|
1779
1785
|
if resp.status_code == 200 and resp.parsed:
|
|
1780
1786
|
self.current_action_name = getattr(resp.parsed, "name", None) or requested_id
|
|
1781
1787
|
else:
|
|
1782
|
-
|
|
1788
|
+
# The name could not be found: the id is all there is to show.
|
|
1789
|
+
self.current_action_name = requested_id
|
|
1783
1790
|
self._refresh_top_bar()
|
|
1784
1791
|
self._refresh_hint_model()
|
|
1785
1792
|
self._refresh_input_label()
|
|
@@ -154,3 +154,52 @@ def test_the_default_autocode_is_also_the_latest_one(monkeypatch):
|
|
|
154
154
|
)
|
|
155
155
|
found = fetch_autocode_actions(client=None)
|
|
156
156
|
assert [a.id for a in found.actions] == ["new"] and found.default_id == "new"
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
# The default by account: Work (Enterprise, api.meetkiwi.ai) starts with Autocode OpenAI
|
|
160
|
+
# Flash, Personal (Subscription, api.runkai.ai) and every other server with Autocode. The
|
|
161
|
+
# VS Code extension makes the same choice (src/defaultAgent.ts).
|
|
162
|
+
|
|
163
|
+
WORK = "https://api.meetkiwi.ai"
|
|
164
|
+
PERSONAL = "https://api.runkai.ai"
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def _flash_and_autocode(monkeypatch):
|
|
168
|
+
_respond(
|
|
169
|
+
monkeypatch,
|
|
170
|
+
200,
|
|
171
|
+
[
|
|
172
|
+
_doc("a", "Autocode"),
|
|
173
|
+
_doc("f1", "Autocode OpenAI Flash", created_at=datetime(2026, 5, 1)),
|
|
174
|
+
_doc("f2", "AutocodeOpenaiFlash", created_at=datetime(2026, 10, 24)),
|
|
175
|
+
_doc("c", "AutoCodeClaude", "claude"),
|
|
176
|
+
],
|
|
177
|
+
)
|
|
178
|
+
return fetch_autocode_actions(client=None)
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
@pytest.mark.parametrize("url", [WORK, WORK + "/", "https://API.meetkiwi.ai"])
|
|
182
|
+
def test_work_starts_with_the_latest_flash(monkeypatch, url):
|
|
183
|
+
assert _flash_and_autocode(monkeypatch).default_id_for(url) == "f2"
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
@pytest.mark.parametrize("url", [PERSONAL, "https://dev.api.myautobots.com", "http://localhost:8000", "", None])
|
|
187
|
+
def test_personal_and_other_servers_start_with_autocode(monkeypatch, url):
|
|
188
|
+
assert _flash_and_autocode(monkeypatch).default_id_for(url) == "a"
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
def test_work_without_flash_starts_with_autocode(monkeypatch):
|
|
192
|
+
_respond(monkeypatch, 200, [_doc("a", "Autocode"), _doc("c", "AutoCodeClaude", "claude")])
|
|
193
|
+
assert fetch_autocode_actions(client=None).default_id_for(WORK) == "a"
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def test_no_actions_means_no_default_on_work_either():
|
|
197
|
+
assert AutocodeActions(status_code=200).default_id_for(WORK) is None
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def test_name_of_gives_an_autocode_actions_name(monkeypatch):
|
|
201
|
+
found = _flash_and_autocode(monkeypatch)
|
|
202
|
+
assert found.name_of("f2") == "AutocodeOpenaiFlash"
|
|
203
|
+
assert found.name_of("a") == "Autocode"
|
|
204
|
+
assert found.name_of("unknown") is None
|
|
205
|
+
assert found.name_of(None) is None
|
|
@@ -979,3 +979,56 @@ async def test_scrolling_up_while_a_reply_streams_stays_up_until_back_at_the_end
|
|
|
979
979
|
await pilot.pause(0.3)
|
|
980
980
|
await stream(5)
|
|
981
981
|
assert gap() <= 1
|
|
982
|
+
|
|
983
|
+
|
|
984
|
+
@pytest.mark.asyncio
|
|
985
|
+
async def test_an_action_shows_by_name_never_by_its_id_while_the_name_loads() -> None:
|
|
986
|
+
app = _TermDashboardTestApp()
|
|
987
|
+
async with app.run_test(size=(120, 60)) as pilot:
|
|
988
|
+
await pilot.pause(0.05)
|
|
989
|
+
screen = app.screen
|
|
990
|
+
screen.current_action_id = "6a0625b8ab5f80ba8ac5d012"
|
|
991
|
+
screen.current_action_name = None
|
|
992
|
+
screen._refresh_welcome_meta()
|
|
993
|
+
screen._refresh_top_bar()
|
|
994
|
+
await pilot.pause(0)
|
|
995
|
+
|
|
996
|
+
assert str(screen.query_one("#term-welcome-action").content) == "Action: …"
|
|
997
|
+
assert "6a0625b8" not in _top_bar_text(screen)
|
|
998
|
+
|
|
999
|
+
|
|
1000
|
+
@pytest.mark.asyncio
|
|
1001
|
+
async def test_the_default_autocode_is_named_from_its_list_without_a_second_request(monkeypatch) -> None:
|
|
1002
|
+
from kiwi_cli.autocode import AutocodeAction, AutocodeActions
|
|
1003
|
+
from pykiwiai.api.actions import get_action_v1_actions_id_get
|
|
1004
|
+
|
|
1005
|
+
app = _TermDashboardTestApp()
|
|
1006
|
+
async with app.run_test(size=(120, 60)) as pilot:
|
|
1007
|
+
await pilot.pause(0.05)
|
|
1008
|
+
screen = app.screen
|
|
1009
|
+
app.autobots_client = SimpleNamespace(client=object(), base_url="https://api.meetkiwi.ai")
|
|
1010
|
+
app._sync_autobots_client_from_disk = lambda: None
|
|
1011
|
+
listed = AutocodeActions(
|
|
1012
|
+
status_code=200,
|
|
1013
|
+
actions=(
|
|
1014
|
+
AutocodeAction(id="a", name="Autocode", type="openai"),
|
|
1015
|
+
AutocodeAction(id="f", name="Autocode OpenAI Flash", type="openai"),
|
|
1016
|
+
),
|
|
1017
|
+
)
|
|
1018
|
+
|
|
1019
|
+
async def load(refresh: bool = False):
|
|
1020
|
+
screen._autocode, screen._autocode_backend = listed, "https://api.meetkiwi.ai"
|
|
1021
|
+
return listed
|
|
1022
|
+
|
|
1023
|
+
monkeypatch.setattr(screen, "_load_autocode_actions", load)
|
|
1024
|
+
|
|
1025
|
+
def no_request(**_kwargs):
|
|
1026
|
+
raise AssertionError("the name was already known")
|
|
1027
|
+
|
|
1028
|
+
monkeypatch.setattr(get_action_v1_actions_id_get, "sync_detailed", no_request)
|
|
1029
|
+
screen.current_action_id = ""
|
|
1030
|
+
screen.current_action_name = None
|
|
1031
|
+
|
|
1032
|
+
await screen._fetch_action_name_async()
|
|
1033
|
+
assert screen.current_action_id == "f"
|
|
1034
|
+
assert screen.current_action_name == "Autocode OpenAI Flash"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|