kiwi-code 0.0.446__tar.gz → 0.0.447__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.
Files changed (75) hide show
  1. kiwi_code-0.0.447/CLAUDE.md +79 -0
  2. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/PKG-INFO +2 -2
  3. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/pyproject.toml +3 -4
  4. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/src/kiwi_cli/__init__.py +2 -1
  5. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/src/kiwi_cli/cli.py +1 -1
  6. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/src/kiwi_cli/client.py +12 -13
  7. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/src/kiwi_cli/commands.py +13 -25
  8. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/src/kiwi_cli/models.py +1 -1
  9. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/src/kiwi_cli/server.py +1 -1
  10. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/src/kiwi_cli/terminal_mode.py +164 -169
  11. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/src/kiwi_runtime/__init__.py +2 -1
  12. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/src/kiwi_runtime/main.py +62 -87
  13. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/src/kiwi_tui/__init__.py +1 -1
  14. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/src/kiwi_tui/main.py +2 -28
  15. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/src/kiwi_tui/screens/dashboard.py +50 -275
  16. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/src/kiwi_tui/screens/login.py +46 -11
  17. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/src/kiwi_tui/screens/runtime_cleanup.py +2 -2
  18. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/src/kiwi_tui/screens/term_dashboard.py +108 -780
  19. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/src/kiwi_tui/slash_commands.py +26 -13
  20. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/src/kiwi_tui/widgets.py +0 -26
  21. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/test_hello.py +1 -1
  22. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/tests/conftest.py +0 -9
  23. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/tests/test_cli_help.py +7 -10
  24. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/tests/test_slash_commands.py +0 -8
  25. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/tests/test_term_dashboard_ui.py +13 -84
  26. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/tests/test_terminal_mode.py +0 -5
  27. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/tests/test_tui_headless.py +34 -35
  28. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/tests/test_tui_interactive_runtime.py +1 -1
  29. kiwi_code-0.0.447/uv.lock +1460 -0
  30. kiwi_code-0.0.446/scripts/ws_auth_check.py +0 -76
  31. kiwi_code-0.0.446/src/common/banner.py +0 -61
  32. kiwi_code-0.0.446/src/kiwi_tui/role_mode.py +0 -269
  33. kiwi_code-0.0.446/tests/__init__.py +0 -0
  34. kiwi_code-0.0.446/tests/test_role_mode_injection.py +0 -131
  35. kiwi_code-0.0.446/uv.lock +0 -1511
  36. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/.github/workflows/publish.yml +0 -0
  37. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/.github/workflows/test.yml +0 -0
  38. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/.gitignore +0 -0
  39. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/.python-version +0 -0
  40. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/Makefile +0 -0
  41. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/README.md +0 -0
  42. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/src/kiwi_cli/auth.py +0 -0
  43. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/src/kiwi_cli/checkpoints.py +0 -0
  44. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/src/kiwi_cli/logger.py +0 -0
  45. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/src/kiwi_cli/runtime_manager.py +0 -0
  46. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/src/kiwi_runtime/__main__.py +0 -0
  47. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/src/kiwi_tui/inline_file_picker.py +0 -0
  48. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/src/kiwi_tui/random_words.py +0 -0
  49. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/src/kiwi_tui/runtime_agent.py +0 -0
  50. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/src/kiwi_tui/screens/__init__.py +0 -0
  51. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/src/kiwi_tui/screens/attach_content.py +0 -0
  52. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/src/kiwi_tui/screens/command_result.py +0 -0
  53. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/src/kiwi_tui/screens/detach_files.py +0 -0
  54. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/src/kiwi_tui/screens/file_browser.py +0 -0
  55. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/src/kiwi_tui/screens/help.py +0 -0
  56. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/src/kiwi_tui/screens/id_picker.py +0 -0
  57. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/src/kiwi_tui/screens/runtime_logs.py +0 -0
  58. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/src/kiwi_tui/screens/slash_picker.py +0 -0
  59. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/src/kiwi_tui/status_words.py +0 -0
  60. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/src/kiwi_tui/term_app.py +0 -0
  61. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/src/kiwi_tui/ui_settings.py +0 -0
  62. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/src/kiwi_tui/worktrees.py +0 -0
  63. {kiwi_code-0.0.446/src/common → kiwi_code-0.0.447/tests}/__init__.py +0 -0
  64. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/tests/test_batch_fs_tool.py +0 -0
  65. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/tests/test_checkpoints.py +0 -0
  66. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/tests/test_copy_path_fs_tool.py +0 -0
  67. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/tests/test_imports.py +0 -0
  68. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/tests/test_read_file_streaming.py +0 -0
  69. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/tests/test_reexec_kiwi.py +0 -0
  70. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/tests/test_runtime_log_trimming.py +0 -0
  71. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/tests/test_search_in_files_fs_tool.py +0 -0
  72. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/tests/test_tokens.py +0 -0
  73. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/tests/test_tui_palette.py +0 -0
  74. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/tests/test_unified_diff.py +0 -0
  75. {kiwi_code-0.0.446 → kiwi_code-0.0.447}/tests/test_worktrees.py +0 -0
@@ -0,0 +1,79 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ Kiwi Code is a TUI + CLI client for the Kiwi AI platform. It provides a chat interface (Textual) and CLI tools (Typer) for managing AI actions, action graphs, and their runs. A WebSocket-based runtime agent executes shell commands on behalf of the LLM.
8
+
9
+ ## Build & Run Commands
10
+
11
+ ```bash
12
+ # Package manager: uv | Build backend: hatchling | Python: 3.13+
13
+ uv sync # Install/sync dependencies
14
+ uv build # Build package
15
+
16
+ # Run
17
+ make run # Launch TUI (kiwi)
18
+ make dev # TUI with live reload
19
+ make serve # Serve TUI in browser (port 8566)
20
+ make cli # Run CLI (kiwicli)
21
+ make runtime ARGS="..." # Run runtime agent with args
22
+
23
+ # Test
24
+ make test-hello # Test backend API connection
25
+ uv run python test_hello.py # Same, without make
26
+
27
+ # Clean
28
+ make clean # Remove caches and build artifacts
29
+ ```
30
+
31
+ There are three entry points defined in pyproject.toml:
32
+ - `kiwi` → `kiwi_tui.main:main` (TUI)
33
+ - `kiwicli` → `kiwi_cli.cli:cli` (CLI)
34
+ - `kiwi-runtime` → `kiwi_runtime.main:main` (WebSocket agent)
35
+
36
+ ## Architecture
37
+
38
+ ```
39
+ ┌─────────────────────────────────┐
40
+ │ Shared Libraries │
41
+ │ commands.py · client.py │
42
+ │ auth.py · models.py · server.py│
43
+ └──────────┬──────────┬───────────┘
44
+ │ │
45
+ ┌──────▼──────┐ └──────────────┐
46
+ │ kiwi (TUI) │ kiwicli (CLI) │
47
+ │ Textual app │ Typer CLI │
48
+ └──────┬──────┘ └──────────────┘
49
+ │ auto-starts
50
+ ┌──────▼──────────────────┐
51
+ │ kiwi-runtime │
52
+ │ WebSocket agent │
53
+ │ One per working dir │
54
+ │ Survives TUI restarts │
55
+ └─────────────────────────┘
56
+ ```
57
+
58
+ **Key design decisions:**
59
+ - Shared infrastructure lives in `kiwi_cli`; TUI imports from it via absolute imports (e.g., `from kiwi_cli.auth import TokenManager`)
60
+ - One runtime agent per working directory, managed via `runtime_manager.py`
61
+ - Runtime state stored in `~/.kiwi/runtimes/<key>/` (pid, log, cwd, tokens)
62
+ - Auth tokens stored in `~/.kiwi/tokens.json` with 0600 permissions
63
+ - No persisted app config; server is selected per invocation via `--server` (defaults to prod)
64
+
65
+ ## Three Source Packages
66
+
67
+ - **`src/kiwi_cli/`** — Typer CLI app and shared infrastructure: auth, client, server, commands, models, runtime_manager, logger. Both `kiwi_tui` and the CLI entry point depend on this package.
68
+ - **`src/kiwi_tui/`** — Textual TUI app, screens, and widgets. Imports shared modules from `kiwi_cli`.
69
+ - **`src/kiwi_runtime/`** — Standalone WebSocket agent (~43KB `main.py`) that connects to Kiwi server and executes shell commands, sandboxed to CWD by default
70
+
71
+ ## Server Presets (runtime)
72
+
73
+ - `app` → `https://api.meetkiwi.ai` (production)
74
+ - `dev` → `https://dev.api.myautobots.com` (default for TUI)
75
+ - `local` → `http://localhost:8000`
76
+
77
+ ## CI/CD
78
+
79
+ GitHub Actions (`publish.yml`): triggered by manual dispatch or `v*.*.*` tags. Runs smoke tests (`kiwicli --help`, `kiwi-runtime --help`, `kiwicli runtime status`), builds, and publishes to PyPI.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kiwi-code
3
- Version: 0.0.446
3
+ Version: 0.0.447
4
4
  Summary: A textual-based terminal user interface application
5
5
  Project-URL: Homepage, https://meetkiwi.ai
6
6
  Author-email: Anurag <anurag@meetkiwi.co>
@@ -14,11 +14,11 @@ 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: autobots-client==0.1.1
17
18
  Requires-Dist: httpx>=0.25.0
18
19
  Requires-Dist: loguru>=0.7.3
19
20
  Requires-Dist: psutil>=5.9.0
20
21
  Requires-Dist: pydantic>=2.12.5
21
- Requires-Dist: pykiwiai==0.0.11
22
22
  Requires-Dist: setproctitle>=1.3.0
23
23
  Requires-Dist: textual-dev>=1.8.0
24
24
  Requires-Dist: textual>=8.1.1
@@ -1,11 +1,11 @@
1
1
  [project]
2
2
  name = "kiwi-code"
3
- version = "0.0.446"
3
+ version = "0.0.447"
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
- "pykiwiai==0.0.11",
8
+ "autobots-client==0.1.1",
9
9
  "loguru>=0.7.3",
10
10
  "pydantic>=2.12.5",
11
11
  "textual>=8.1.1",
@@ -54,9 +54,8 @@ filterwarnings = [
54
54
  "ignore::DeprecationWarning",
55
55
  ]
56
56
 
57
-
58
57
  [tool.hatch.build.targets.wheel]
59
- packages = ["src/common", "src/kiwi_cli", "src/kiwi_tui", "src/kiwi_runtime"]
58
+ packages = ["src/kiwi_cli", "src/kiwi_tui", "src/kiwi_runtime"]
60
59
 
61
60
  [build-system]
62
61
  requires = ["hatchling"]
@@ -1,3 +1,4 @@
1
1
  """Kiwi CLI - command-line interface and shared infrastructure modules."""
2
2
 
3
- __version__ = "0.0.446"
3
+
4
+ __version__ = "0.0.447"
@@ -3,7 +3,7 @@ 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 pykiwiai import AuthenticatedClient
6
+ from autobots_client import AuthenticatedClient
7
7
  from .auth import TokenManager
8
8
  from .models import AppConfig
9
9
  from .server import http_url_from_server
@@ -6,20 +6,20 @@ import json
6
6
  import codecs
7
7
  import httpx
8
8
  from loguru import logger
9
- from pykiwiai import Client, AuthenticatedClient
10
- from pykiwiai.api.hello import hello_v1_hello_get
11
- from pykiwiai.api.auth import (
9
+ from autobots_client import Client, AuthenticatedClient
10
+ from autobots_client.api.hello import hello_v1_hello_get
11
+ from autobots_client.api.auth import (
12
12
  return_user_and_session_v1_auth_post,
13
13
  )
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 (
14
+ from autobots_client.api.actions import async_run_action_v1_actions_id_async_run_post
15
+ from autobots_client.api.action_results import get_action_result_v1_action_results_id_get
16
+ from autobots_client.models.body_return_user_and_session_v1_auth_post import (
17
17
  BodyReturnUserAndSessionV1AuthPost,
18
18
  )
19
- from pykiwiai.models.body_async_run_action_v1_actions_id_async_run_post import (
19
+ from autobots_client.models.body_async_run_action_v1_actions_id_async_run_post import (
20
20
  BodyAsyncRunActionV1ActionsIdAsyncRunPost,
21
21
  )
22
- from pykiwiai.models.body_async_run_action_v1_actions_id_async_run_post_input import (
22
+ from autobots_client.models.body_async_run_action_v1_actions_id_async_run_post_input import (
23
23
  BodyAsyncRunActionV1ActionsIdAsyncRunPostInput,
24
24
  )
25
25
  from .models import AuthTokens, LoginCredentials
@@ -253,8 +253,8 @@ class AutobotsClientWrapper:
253
253
 
254
254
  import mimetypes
255
255
  from pathlib import Path
256
- from pykiwiai.api.files import upload_files_v1_files_post
257
- from pykiwiai.models.body_upload_files_v1_files_post import BodyUploadFilesV1FilesPost
256
+ from autobots_client.api.files import upload_files_v1_files_post
257
+ from autobots_client.models.body_upload_files_v1_files_post import BodyUploadFilesV1FilesPost
258
258
 
259
259
  # Validate all files exist first
260
260
  paths = []
@@ -344,7 +344,7 @@ class AutobotsClientWrapper:
344
344
  logger.info(f"Request body: {body.to_dict()}")
345
345
 
346
346
  # Import UNSET for optional parameter
347
- from pykiwiai.types import UNSET
347
+ from autobots_client.types import UNSET
348
348
 
349
349
  response = async_run_action_v1_actions_id_async_run_post.sync_detailed(
350
350
  id=action_id,
@@ -464,8 +464,7 @@ class AutobotsClientWrapper:
464
464
  logger.info(f"Result structure keys: {result_dict.keys()}")
465
465
  if "result" in result_dict and isinstance(result_dict["result"], dict):
466
466
  logger.info(f"Result.result keys: {result_dict['result'].keys()}")
467
- result = result_dict['result']
468
- logger.info(f"Result's results : {result['results']}")
467
+
469
468
  return True, result_dict, "Result retrieved"
470
469
  else:
471
470
  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 pykiwiai import AuthenticatedClient
9
- from pykiwiai.api.actions import (
8
+ from autobots_client import AuthenticatedClient
9
+ from autobots_client.api.actions import (
10
10
  list_actions_v1_actions_get,
11
11
  get_action_v1_actions_id_get,
12
12
  )
13
- from pykiwiai.api.action_results import (
13
+ from autobots_client.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 pykiwiai.types import UNSET
18
+ from autobots_client.types import UNSET
19
19
 
20
20
 
21
21
  # Helpers
@@ -35,18 +35,6 @@ 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
-
50
38
  # actions
51
39
 
52
40
  def actions_list(client: AuthenticatedClient, *, name: Optional[str] = None, limit: int = 20, offset: int = 0) -> list[str]:
@@ -69,7 +57,7 @@ def actions_list(client: AuthenticatedClient, *, name: Optional[str] = None, lim
69
57
  ]
70
58
  for doc in result.docs:
71
59
  lines.append(
72
- f"{doc.field_id:<28} {_val(doc.name):<30} {_val(_enum(doc.type_)):<25} "
60
+ f"{doc.field_id:<28} {_val(doc.name):<30} {_val(doc.type_.value):<25} "
73
61
  f"{_val(doc.version):<6} {_fmt_date(doc.created_at)}"
74
62
  )
75
63
  return lines
@@ -85,7 +73,7 @@ def actions_get(client: AuthenticatedClient, *, id: str) -> list[str]:
85
73
  return [
86
74
  f"ID: {doc.field_id}",
87
75
  f"Name: {doc.name}",
88
- f"Type: {_enum(doc.type_)}",
76
+ f"Type: {doc.type_.value}",
89
77
  f"Version: {_val(doc.version)}",
90
78
  f"Description: {_val(doc.description)}",
91
79
  f"Published: {_val(doc.is_published)}",
@@ -100,13 +88,13 @@ def actions_get(client: AuthenticatedClient, *, id: str) -> list[str]:
100
88
  def runs_list(client: AuthenticatedClient, *, action_id: Optional[str] = None, action_name: Optional[str] = None,
101
89
  status: Optional[str] = None, limit: int = 20, offset: int = 0) -> list[str]:
102
90
  """List action runs. Returns output lines."""
103
- from pykiwiai.models.event_result_status import check_event_result_status
91
+ from autobots_client.models.event_result_status import EventResultStatus
104
92
 
105
93
  status_enum = UNSET
106
94
  if status:
107
95
  try:
108
- status_enum = check_event_result_status(status.lower())
109
- except TypeError:
96
+ status_enum = EventResultStatus(status.lower())
97
+ except ValueError:
110
98
  return [f"Invalid status: {status}. Valid: processing, success, error, stuck, waiting"]
111
99
 
112
100
  resp = list_action_result_v1_action_results_get.sync_detailed(
@@ -129,7 +117,7 @@ def runs_list(client: AuthenticatedClient, *, action_id: Optional[str] = None, a
129
117
  ]
130
118
  for doc in result.docs:
131
119
  lines.append(
132
- f"{doc.field_id:<28} {_enum(doc.status):<12} {_val(doc.name):<30} "
120
+ f"{doc.field_id:<28} {doc.status.value:<12} {_val(doc.name):<30} "
133
121
  f"{_fmt_date(doc.created_at):<18} {_fmt_date(doc.updated_at)}"
134
122
  )
135
123
  return lines
@@ -144,9 +132,9 @@ def runs_get(client: AuthenticatedClient, *, id: str) -> list[str]:
144
132
  doc = resp.parsed
145
133
  lines = [
146
134
  f"ID: {doc.field_id}",
147
- f"Status: {_enum(doc.status)}",
135
+ f"Status: {doc.status.value}",
148
136
  f"Name: {_val(doc.name)}",
149
- f"Type: {_enum(doc.type_)}",
137
+ f"Type: {doc.type_.value}",
150
138
  f"Saved: {_val(doc.is_saved)}",
151
139
  f"Created: {_fmt_date(doc.created_at)}",
152
140
  f"Updated: {_fmt_date(doc.updated_at)}",
@@ -156,7 +144,7 @@ def runs_get(client: AuthenticatedClient, *, id: str) -> list[str]:
156
144
  "",
157
145
  "Action:",
158
146
  f" Name: {doc.result.name}",
159
- f" Type: {_enum(doc.result.type_)}",
147
+ f" Type: {doc.result.type_.value}",
160
148
  f" ID: {doc.result.field_id}",
161
149
  ]
162
150
  return lines
@@ -115,7 +115,7 @@ class LoginCredentials(BaseModel):
115
115
 
116
116
  class AppConfig(BaseModel):
117
117
  """Application configuration."""
118
- backend_url: str = "https://api.runkai.ai"
118
+ backend_url: str = "https://api.meetkiwi.ai"
119
119
  api_key: Optional[str] = None
120
120
  log_level: str = "INFO"
121
121
  theme: str = "dark"
@@ -11,7 +11,7 @@ The value can be:
11
11
  This module intentionally contains *no persistence*. It is runtime-only.
12
12
  """
13
13
  SERVER_PRESETS: dict[str, dict[str, str]] = {
14
- "app": {"ws": "wss://api.runkai.ai", "http": "https://api.runkai.ai"},
14
+ "app": {"ws": "wss://api.meetkiwi.ai", "http": "https://api.meetkiwi.ai"},
15
15
  "dev": {"ws": "wss://dev.api.myautobots.com", "http": "https://dev.api.myautobots.com"},
16
16
  "local": {"ws": "ws://localhost:8000", "http": "http://localhost:8000"},
17
17
  }