openbase-coder 0.1.4__tar.gz → 0.1.5__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.
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/PKG-INFO +1 -1
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/_version.py +2 -2
- openbase_coder-0.1.5/openbase_coder_cli/brain_score.py +27 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/cartesia_voice_catalog.py +6 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/cli/setup.py +172 -2
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/livekit_agent/livekit.py +29 -77
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/livekit_voice_route.py +7 -55
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/brain_readiness.py +21 -10
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/.gitignore +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/LICENSE +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/README.md +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/__init__.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/__main__.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/cli/__init__.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/cli/auth.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/cli/boilersync.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/cli/bootstrap.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/cli/claude_chrome.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/cli/codex_sync.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/cli/computer_use.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/cli/doctor.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/cli/local_server.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/cli/node.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/cli/plugins.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/cli/restart.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/cli/routines.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/cli/server.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/cli/services.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/cli/super_agent_name.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/cli/user.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/cli/utils.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/cli_helpers.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/config/__init__.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/config/asgi.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/config/authentication.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/config/jwt_validation.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/config/proxy.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/config/serializers.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/config/settings.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/config/token_manager.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/config/urls.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/config/viewsets.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/config/wsgi.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/dispatcher_config.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/entrypoint/manage.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/errors.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/livekit_agent/__init__.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/livekit_agent/codex_app_client.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/livekit_agent/codex_thread_state.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/livekit_agent/codex_transport.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/livekit_agent/codex_turns.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/livekit_agent/speech_formatter.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/livekit_agent/speech_replacements.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/livekit_announcer.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/livekit_start_announcer.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/livekit_voice_history.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/logging.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/mcp/__init__.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/mcp/apps.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/mcp/mcp.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/mcp/models.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/mcp/projects.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/mcp/session_manager.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/mcp/thread_import.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/multi_config.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/__init__.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/agents_md.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/approvals.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/apps.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/auth.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/common.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/consumers.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/diagnostics.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/livekit.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/middleware.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/migrations/0001_initial.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/migrations/0002_remove_cron_models.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/migrations/__init__.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/models.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/plugins_tools.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/projects.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/reports.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/routines.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/routing.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/serializers.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/services_views.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/skills.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/thread_cache.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/thread_metadata.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/threads.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/urls.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/views.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/paths.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/plugins/__init__.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/plugins/api.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/plugins/console.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/plugins/install.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/plugins/manager.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/plugins/models.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/plugins/skills.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/plugins/sources.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/plugins/spec.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/plugins/store.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/services/__init__.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/services/boilersync.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/services/console_settings.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/services/definitions.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/services/installation.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/services/launchctl_tools.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/services/launchd.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/services/openbase_services.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/services/registry.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/services/restart.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/services/tailnet_devices.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/services/uv_tools.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/services/voice_warning.py +0 -0
- {openbase_coder-0.1.4 → openbase_coder-0.1.5}/pyproject.toml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: openbase-coder
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.5
|
|
4
4
|
Summary: OpenBase Coder CLI with embedded server
|
|
5
5
|
Project-URL: Repository, https://github.com/openbase-community/openbase-coder
|
|
6
6
|
Project-URL: Issues, https://github.com/openbase-community/openbase-coder/issues
|
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '0.1.
|
|
22
|
-
__version_tuple__ = version_tuple = (0, 1,
|
|
21
|
+
__version__ = version = '0.1.5'
|
|
22
|
+
__version_tuple__ = version_tuple = (0, 1, 5)
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import os
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def brain_score_token_file() -> Path:
|
|
8
|
+
return Path(
|
|
9
|
+
os.getenv(
|
|
10
|
+
"OPENBASE_BRAIN_SCORE_TOKEN_FILE",
|
|
11
|
+
str(Path.home() / ".openbase" / "brain_score_token"),
|
|
12
|
+
)
|
|
13
|
+
).expanduser()
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def load_brain_score_token() -> str:
|
|
17
|
+
configured = os.getenv("OPENBASE_BRAIN_SCORE_TOKEN", "").strip()
|
|
18
|
+
if configured:
|
|
19
|
+
return configured
|
|
20
|
+
try:
|
|
21
|
+
return brain_score_token_file().read_text(encoding="utf-8").strip()
|
|
22
|
+
except (FileNotFoundError, OSError):
|
|
23
|
+
return ""
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def brain_score_token_configured() -> bool:
|
|
27
|
+
return bool(load_brain_score_token())
|
|
@@ -96,6 +96,12 @@ CARTESIA_VOICE_CATALOG: tuple[CartesiaVoiceCatalogEntry, ...] = (
|
|
|
96
96
|
CartesiaVoiceCatalogEntry("91b4cf29-5166-44eb-8054-30d40ecc8081", "Tina", "en", "US", "feminine"),
|
|
97
97
|
)
|
|
98
98
|
|
|
99
|
+
DEFAULT_SUPER_AGENT_VOICE_IDS = tuple(
|
|
100
|
+
voice.id
|
|
101
|
+
for voice in CARTESIA_VOICE_CATALOG
|
|
102
|
+
if voice.id != "9626c31c-bec5-4cca-baa8-f8ba9e84c8bc"
|
|
103
|
+
)
|
|
104
|
+
|
|
99
105
|
_CATALOG_BY_ID = {voice.id: voice for voice in CARTESIA_VOICE_CATALOG}
|
|
100
106
|
_CATALOG_BY_NORMALIZED_NAME = {
|
|
101
107
|
" ".join(voice.name.casefold().split()): voice for voice in CARTESIA_VOICE_CATALOG
|
|
@@ -15,6 +15,7 @@ from openbase_coder_cli.cli.node import run_workspace_package_command
|
|
|
15
15
|
from openbase_coder_cli.paths import (
|
|
16
16
|
CODEX_AGENTS_MD_PATH,
|
|
17
17
|
CODEX_DIRECT_LIVEKIT_INSTRUCTIONS_PATH,
|
|
18
|
+
CODEX_DISPATCHER_CONFIG_PATH,
|
|
18
19
|
CODEX_DISPATCHER_INSTRUCTIONS_PATH,
|
|
19
20
|
CODEX_HOME_DIR,
|
|
20
21
|
CODEX_SUPER_AGENT_INSTRUCTIONS_PATH,
|
|
@@ -35,6 +36,21 @@ CODEX_HOME_DEFAULT_FILES = (
|
|
|
35
36
|
("DISPATCHER_INSTRUCTIONS.md", CODEX_DISPATCHER_INSTRUCTIONS_PATH),
|
|
36
37
|
("SUPER_AGENT_INSTRUCTIONS.md", CODEX_SUPER_AGENT_INSTRUCTIONS_PATH),
|
|
37
38
|
)
|
|
39
|
+
SUPER_AGENTS_MCP_TABLE = "mcp_servers.super-agents"
|
|
40
|
+
SUPER_AGENTS_MCP_COMMAND = "super-agents-mcp"
|
|
41
|
+
CODEX_HOME_PERMISSION_VALUES = (
|
|
42
|
+
("sandbox_mode", json.dumps("danger-full-access")),
|
|
43
|
+
(
|
|
44
|
+
"approval_policy",
|
|
45
|
+
"{ granular = { sandbox_approval = false, rules = false, "
|
|
46
|
+
"mcp_elicitations = false, request_permissions = false, "
|
|
47
|
+
"skill_approval = false } }",
|
|
48
|
+
),
|
|
49
|
+
)
|
|
50
|
+
CODEX_HOME_DEFAULT_DISPATCHER_CONFIG = {
|
|
51
|
+
"dispatcher_reasoning_effort": "low",
|
|
52
|
+
"super_agents_reasoning_effort": "high",
|
|
53
|
+
}
|
|
38
54
|
|
|
39
55
|
|
|
40
56
|
@click.command()
|
|
@@ -110,11 +126,15 @@ def setup(
|
|
|
110
126
|
# --- Symlink Codex auth into the service CODEX_HOME ---
|
|
111
127
|
_symlink_codex_auth()
|
|
112
128
|
_ensure_codex_home_default_files(workspace_dir)
|
|
129
|
+
_ensure_codex_home_dispatcher_config()
|
|
113
130
|
_symlink_codex_home_skills(workspace_dir)
|
|
114
131
|
|
|
115
132
|
# --- Initialize CLI workspace ---
|
|
116
133
|
_init_cli_workspace(workspace_dir)
|
|
117
134
|
|
|
135
|
+
# --- Configure the service CODEX_HOME ---
|
|
136
|
+
_ensure_codex_home_config(workspace_dir)
|
|
137
|
+
|
|
118
138
|
# --- Install/update user-facing CLI shim ---
|
|
119
139
|
_install_cli_shim(workspace_dir)
|
|
120
140
|
|
|
@@ -310,6 +330,23 @@ def _ensure_codex_home_default_files(workspace_dir: str) -> None:
|
|
|
310
330
|
click.echo(f"Created Codex home default at {target_path}")
|
|
311
331
|
|
|
312
332
|
|
|
333
|
+
def _ensure_codex_home_dispatcher_config() -> None:
|
|
334
|
+
"""Create the missing Openbase dispatcher config."""
|
|
335
|
+
if CODEX_DISPATCHER_CONFIG_PATH.exists():
|
|
336
|
+
click.echo(
|
|
337
|
+
f"Codex home dispatcher config already exists at "
|
|
338
|
+
f"{CODEX_DISPATCHER_CONFIG_PATH}"
|
|
339
|
+
)
|
|
340
|
+
return
|
|
341
|
+
|
|
342
|
+
CODEX_DISPATCHER_CONFIG_PATH.parent.mkdir(parents=True, exist_ok=True)
|
|
343
|
+
CODEX_DISPATCHER_CONFIG_PATH.write_text(
|
|
344
|
+
json.dumps(CODEX_HOME_DEFAULT_DISPATCHER_CONFIG, indent=2) + "\n",
|
|
345
|
+
encoding="utf-8",
|
|
346
|
+
)
|
|
347
|
+
click.echo(f"Created Codex home dispatcher config at {CODEX_DISPATCHER_CONFIG_PATH}")
|
|
348
|
+
|
|
349
|
+
|
|
313
350
|
def _symlink_codex_home_skills(workspace_dir: str) -> None:
|
|
314
351
|
"""Symlink workspace-owned skills into the Openbase Codex home."""
|
|
315
352
|
source_root = Path(workspace_dir) / CODEX_HOME_SKILLS_SOURCE_DIR
|
|
@@ -339,6 +376,141 @@ def _symlink_codex_home_skills(workspace_dir: str) -> None:
|
|
|
339
376
|
click.echo(f"Linked Codex home skill {target_path} → {source_path}")
|
|
340
377
|
|
|
341
378
|
|
|
379
|
+
def _ensure_codex_home_config(workspace_dir: str) -> None:
|
|
380
|
+
"""Configure Openbase's service Codex home."""
|
|
381
|
+
CODEX_HOME_DIR.mkdir(parents=True, exist_ok=True)
|
|
382
|
+
config_path = CODEX_HOME_DIR / "config.toml"
|
|
383
|
+
command_path, args = _super_agents_mcp_command(Path(workspace_dir))
|
|
384
|
+
block = (
|
|
385
|
+
f"[{SUPER_AGENTS_MCP_TABLE}]\n"
|
|
386
|
+
f"command = {json.dumps(str(command_path))}\n"
|
|
387
|
+
f"{_toml_args_line(args)}"
|
|
388
|
+
)
|
|
389
|
+
|
|
390
|
+
if not command_path.is_file():
|
|
391
|
+
click.echo(
|
|
392
|
+
f"Super Agents MCP command not found at {command_path}; "
|
|
393
|
+
"writing the expected config path anyway."
|
|
394
|
+
)
|
|
395
|
+
|
|
396
|
+
existing = ""
|
|
397
|
+
if config_path.is_file():
|
|
398
|
+
existing = config_path.read_text(encoding="utf-8")
|
|
399
|
+
|
|
400
|
+
updated = _ensure_toml_root_values(existing, CODEX_HOME_PERMISSION_VALUES)
|
|
401
|
+
updated = _replace_toml_table(updated, SUPER_AGENTS_MCP_TABLE, block)
|
|
402
|
+
if updated == existing:
|
|
403
|
+
click.echo(f"Codex home config already configured at {config_path}")
|
|
404
|
+
return
|
|
405
|
+
|
|
406
|
+
config_path.write_text(updated, encoding="utf-8")
|
|
407
|
+
click.echo(f"Configured Codex home config at {config_path}")
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
def _super_agents_mcp_command(workspace_dir: Path) -> tuple[Path, list[str]]:
|
|
411
|
+
candidates = (
|
|
412
|
+
workspace_dir / ".venv" / "bin" / SUPER_AGENTS_MCP_COMMAND,
|
|
413
|
+
workspace_dir / "cli" / ".venv" / "bin" / SUPER_AGENTS_MCP_COMMAND,
|
|
414
|
+
)
|
|
415
|
+
for candidate in candidates:
|
|
416
|
+
if candidate.is_file():
|
|
417
|
+
return candidate, []
|
|
418
|
+
|
|
419
|
+
if command := which(SUPER_AGENTS_MCP_COMMAND):
|
|
420
|
+
return Path(command), []
|
|
421
|
+
|
|
422
|
+
if uv_bin := which("uv"):
|
|
423
|
+
run_dir = workspace_dir / "cli"
|
|
424
|
+
if not run_dir.is_dir():
|
|
425
|
+
run_dir = workspace_dir
|
|
426
|
+
return Path(uv_bin), [
|
|
427
|
+
"--directory",
|
|
428
|
+
str(run_dir),
|
|
429
|
+
"run",
|
|
430
|
+
SUPER_AGENTS_MCP_COMMAND,
|
|
431
|
+
]
|
|
432
|
+
|
|
433
|
+
return candidates[0], []
|
|
434
|
+
|
|
435
|
+
|
|
436
|
+
def _toml_args_line(args: list[str]) -> str:
|
|
437
|
+
if not args:
|
|
438
|
+
return ""
|
|
439
|
+
return f"args = {json.dumps(args)}\n"
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
def _ensure_toml_root_values(
|
|
443
|
+
text: str,
|
|
444
|
+
values: tuple[tuple[str, str], ...],
|
|
445
|
+
) -> str:
|
|
446
|
+
lines = text.splitlines()
|
|
447
|
+
first_table_index = next(
|
|
448
|
+
(
|
|
449
|
+
index
|
|
450
|
+
for index, line in enumerate(lines)
|
|
451
|
+
if line.strip().startswith("[") and line.strip().endswith("]")
|
|
452
|
+
),
|
|
453
|
+
len(lines),
|
|
454
|
+
)
|
|
455
|
+
root_lines = lines[:first_table_index]
|
|
456
|
+
table_lines = lines[first_table_index:]
|
|
457
|
+
keys = {key for key, _value in values}
|
|
458
|
+
updated_root = [
|
|
459
|
+
line
|
|
460
|
+
for line in root_lines
|
|
461
|
+
if _toml_root_key(line) not in keys
|
|
462
|
+
]
|
|
463
|
+
|
|
464
|
+
while updated_root and not updated_root[-1].strip():
|
|
465
|
+
updated_root.pop()
|
|
466
|
+
|
|
467
|
+
for key, value in values:
|
|
468
|
+
updated_root.append(f"{key} = {value}")
|
|
469
|
+
|
|
470
|
+
while table_lines and not table_lines[0].strip():
|
|
471
|
+
table_lines.pop(0)
|
|
472
|
+
|
|
473
|
+
if table_lines:
|
|
474
|
+
return "\n".join(updated_root) + "\n\n" + "\n".join(table_lines) + "\n"
|
|
475
|
+
return "\n".join(updated_root) + "\n"
|
|
476
|
+
|
|
477
|
+
|
|
478
|
+
def _toml_root_key(line: str) -> str | None:
|
|
479
|
+
stripped = line.strip()
|
|
480
|
+
if not stripped or stripped.startswith("#") or "=" not in stripped:
|
|
481
|
+
return None
|
|
482
|
+
return stripped.split("=", 1)[0].strip()
|
|
483
|
+
|
|
484
|
+
|
|
485
|
+
def _replace_toml_table(text: str, table_name: str, block: str) -> str:
|
|
486
|
+
target_header = f"[{table_name}]"
|
|
487
|
+
lines = text.splitlines()
|
|
488
|
+
output: list[str] = []
|
|
489
|
+
index = 0
|
|
490
|
+
|
|
491
|
+
while index < len(lines):
|
|
492
|
+
if lines[index].strip() == target_header:
|
|
493
|
+
index += 1
|
|
494
|
+
while index < len(lines):
|
|
495
|
+
stripped = lines[index].strip()
|
|
496
|
+
if stripped.startswith("[") and stripped.endswith("]"):
|
|
497
|
+
break
|
|
498
|
+
index += 1
|
|
499
|
+
while output and not output[-1].strip():
|
|
500
|
+
output.pop()
|
|
501
|
+
continue
|
|
502
|
+
|
|
503
|
+
output.append(lines[index])
|
|
504
|
+
index += 1
|
|
505
|
+
|
|
506
|
+
while output and not output[-1].strip():
|
|
507
|
+
output.pop()
|
|
508
|
+
|
|
509
|
+
if output:
|
|
510
|
+
return "\n".join(output) + "\n\n" + block
|
|
511
|
+
return block
|
|
512
|
+
|
|
513
|
+
|
|
342
514
|
def _workspace_skill_sources(source_root: Path) -> list[Path]:
|
|
343
515
|
candidate_roots = [source_root / "skills", source_root]
|
|
344
516
|
seen: set[Path] = set()
|
|
@@ -474,8 +646,6 @@ def _ensure_env_file(
|
|
|
474
646
|
"LIVEKIT_CODEX_THREAD_CWD=~",
|
|
475
647
|
"# Cartesia voice used by the LiveKit agent TTS.",
|
|
476
648
|
"CARTESIA_VOICE_ID=9626c31c-bec5-4cca-baa8-f8ba9e84c8bc",
|
|
477
|
-
"# Optional comma-separated voices for direct thread routing: voice-id:Display Name.",
|
|
478
|
-
"# CARTESIA_SUPER_AGENT_VOICES=f786b574-daa5-4673-aa0c-cbe3e8534c02:Alice",
|
|
479
649
|
"OPENBASE_CODER_CLI_OAUTH_CLIENT_ID=openbase-coder-cli",
|
|
480
650
|
]
|
|
481
651
|
|
|
@@ -42,6 +42,15 @@ from livekit.agents.types import DEFAULT_API_CONNECT_OPTIONS, NOT_GIVEN
|
|
|
42
42
|
from livekit.plugins import assemblyai, cartesia, deepgram, silero
|
|
43
43
|
from livekit.plugins.turn_detector.multilingual import MultilingualModel
|
|
44
44
|
|
|
45
|
+
from openbase_coder_cli.brain_score import (
|
|
46
|
+
brain_score_token_configured,
|
|
47
|
+
brain_score_token_file,
|
|
48
|
+
load_brain_score_token,
|
|
49
|
+
)
|
|
50
|
+
from openbase_coder_cli.cartesia_voice_catalog import (
|
|
51
|
+
DEFAULT_SUPER_AGENT_VOICE_IDS,
|
|
52
|
+
cartesia_voice_for_id,
|
|
53
|
+
)
|
|
45
54
|
from openbase_coder_cli.dispatcher_config import dispatcher_voice
|
|
46
55
|
from openbase_coder_cli.livekit_agent.codex_app_client import CodexAppServerClient
|
|
47
56
|
from openbase_coder_cli.livekit_agent.speech_formatter import format_for_speech
|
|
@@ -165,12 +174,7 @@ BRAIN_SCORE_OUTPUT_PATH = Path(
|
|
|
165
174
|
str(Path.home() / ".openbase" / "brain_score.json"),
|
|
166
175
|
)
|
|
167
176
|
).expanduser()
|
|
168
|
-
BRAIN_SCORE_TOKEN_FILE =
|
|
169
|
-
os.getenv(
|
|
170
|
-
"OPENBASE_BRAIN_SCORE_TOKEN_FILE",
|
|
171
|
-
str(Path.home() / ".openbase" / "brain_score_token"),
|
|
172
|
-
)
|
|
173
|
-
).expanduser()
|
|
177
|
+
BRAIN_SCORE_TOKEN_FILE = brain_score_token_file()
|
|
174
178
|
BRAIN_SCORE_LATITUDE = os.getenv("OPENBASE_BRAIN_SCORE_LATITUDE", "").strip()
|
|
175
179
|
BRAIN_SCORE_LONGITUDE = os.getenv("OPENBASE_BRAIN_SCORE_LONGITUDE", "").strip()
|
|
176
180
|
|
|
@@ -181,27 +185,6 @@ class CartesiaVoice:
|
|
|
181
185
|
name: str
|
|
182
186
|
|
|
183
187
|
|
|
184
|
-
def _super_agent_voices(env: Mapping[str, str]) -> tuple[CartesiaVoice, ...]:
|
|
185
|
-
named_configured = env.get("CARTESIA_SUPER_AGENT_VOICES")
|
|
186
|
-
if named_configured is not None:
|
|
187
|
-
return _parse_voices(named_configured)
|
|
188
|
-
|
|
189
|
-
configured = env.get("CARTESIA_SUPER_AGENT_VOICE_IDS")
|
|
190
|
-
if configured is not None:
|
|
191
|
-
return _voices_from_ids(_parse_voice_ids(configured))
|
|
192
|
-
|
|
193
|
-
dispatcher_voice_id = env.get("CARTESIA_VOICE_ID", DEFAULT_CARTESIA_VOICE_ID)
|
|
194
|
-
announcer_voice_id = env.get(
|
|
195
|
-
"CARTESIA_ANNOUNCER_VOICE_ID",
|
|
196
|
-
DEFAULT_CARTESIA_ANNOUNCER_VOICE_ID,
|
|
197
|
-
)
|
|
198
|
-
return _voices_from_ids(
|
|
199
|
-
voice_id
|
|
200
|
-
for voice_id in (announcer_voice_id,)
|
|
201
|
-
if voice_id and voice_id != dispatcher_voice_id
|
|
202
|
-
)
|
|
203
|
-
|
|
204
|
-
|
|
205
188
|
def dispatcher_voice_config(
|
|
206
189
|
*,
|
|
207
190
|
config_path: str | Path | None = None,
|
|
@@ -212,49 +195,27 @@ def dispatcher_voice_config(
|
|
|
212
195
|
return CartesiaVoice(voice_id=configured["id"], name=configured["name"])
|
|
213
196
|
|
|
214
197
|
|
|
215
|
-
def _parse_voice_ids(value: str) -> tuple[str, ...]:
|
|
216
|
-
return tuple(
|
|
217
|
-
voice_id for voice_id in (part.strip() for part in value.split(",")) if voice_id
|
|
218
|
-
)
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
def _parse_voices(value: str) -> tuple[CartesiaVoice, ...]:
|
|
222
|
-
voices: list[CartesiaVoice] = []
|
|
223
|
-
for part in (part.strip() for part in value.split(",")):
|
|
224
|
-
if not part:
|
|
225
|
-
continue
|
|
226
|
-
voice_id, separator, name = part.partition(":")
|
|
227
|
-
trimmed_voice_id = voice_id.strip()
|
|
228
|
-
if not trimmed_voice_id:
|
|
229
|
-
continue
|
|
230
|
-
trimmed_name = name.strip() if separator else ""
|
|
231
|
-
voices.append(
|
|
232
|
-
CartesiaVoice(
|
|
233
|
-
voice_id=trimmed_voice_id,
|
|
234
|
-
name=trimmed_name or f"Voice {len(voices) + 1}",
|
|
235
|
-
)
|
|
236
|
-
)
|
|
237
|
-
return tuple(voices)
|
|
238
|
-
|
|
239
|
-
|
|
240
198
|
def _voices_from_ids(voice_ids) -> tuple[CartesiaVoice, ...]:
|
|
241
199
|
return tuple(
|
|
242
|
-
CartesiaVoice(
|
|
200
|
+
CartesiaVoice(
|
|
201
|
+
voice_id=voice_id,
|
|
202
|
+
name=cartesia_voice_for_id(voice_id).name
|
|
203
|
+
if cartesia_voice_for_id(voice_id)
|
|
204
|
+
else f"Voice {index + 1}",
|
|
205
|
+
)
|
|
243
206
|
for index, voice_id in enumerate(voice_ids)
|
|
244
207
|
)
|
|
245
208
|
|
|
246
209
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
voice.voice_id for voice in CARTESIA_SUPER_AGENT_VOICES
|
|
250
|
-
)
|
|
210
|
+
SUPER_AGENT_VOICE_IDS = DEFAULT_SUPER_AGENT_VOICE_IDS
|
|
211
|
+
SUPER_AGENT_VOICES = _voices_from_ids(SUPER_AGENT_VOICE_IDS)
|
|
251
212
|
|
|
252
213
|
|
|
253
214
|
def _current_super_agent_voices() -> tuple[CartesiaVoice, ...]:
|
|
254
|
-
voice_ids = tuple(voice.voice_id for voice in
|
|
255
|
-
if voice_ids == tuple(
|
|
256
|
-
return
|
|
257
|
-
return _voices_from_ids(
|
|
215
|
+
voice_ids = tuple(voice.voice_id for voice in SUPER_AGENT_VOICES)
|
|
216
|
+
if voice_ids == tuple(SUPER_AGENT_VOICE_IDS):
|
|
217
|
+
return SUPER_AGENT_VOICES
|
|
218
|
+
return _voices_from_ids(SUPER_AGENT_VOICE_IDS)
|
|
258
219
|
|
|
259
220
|
|
|
260
221
|
def _normalize_spoken_command(text: str) -> str:
|
|
@@ -507,20 +468,11 @@ def _event_text_hash(text: str) -> str:
|
|
|
507
468
|
|
|
508
469
|
|
|
509
470
|
def _load_brain_score_token() -> str:
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
except FileNotFoundError:
|
|
516
|
-
return ""
|
|
517
|
-
except OSError:
|
|
518
|
-
logger.warning(
|
|
519
|
-
"Unable to read brain score token file %s",
|
|
520
|
-
BRAIN_SCORE_TOKEN_FILE,
|
|
521
|
-
exc_info=True,
|
|
522
|
-
)
|
|
523
|
-
return ""
|
|
471
|
+
return load_brain_score_token()
|
|
472
|
+
|
|
473
|
+
|
|
474
|
+
def _brain_score_enabled() -> bool:
|
|
475
|
+
return BRAIN_SCORE_ENABLED and brain_score_token_configured()
|
|
524
476
|
|
|
525
477
|
|
|
526
478
|
class BrainScoreSTT(livekit_stt.STT):
|
|
@@ -2559,12 +2511,12 @@ def _build_stt():
|
|
|
2559
2511
|
if LIVEKIT_STT_PROVIDER == "deepgram":
|
|
2560
2512
|
logger.info("Using Deepgram STT")
|
|
2561
2513
|
stt = deepgram.STT(api_key=DEEPGRAM_API_KEY)
|
|
2562
|
-
stt = BrainScoreSTT(stt) if
|
|
2514
|
+
stt = BrainScoreSTT(stt) if _brain_score_enabled() else stt
|
|
2563
2515
|
return LoggingSTT(stt) if LIVEKIT_VERBOSE_LOGGING else stt
|
|
2564
2516
|
if LIVEKIT_STT_PROVIDER == "assemblyai":
|
|
2565
2517
|
logger.info("Using AssemblyAI STT")
|
|
2566
2518
|
stt = assemblyai.STT(api_key=ASSEMBLY_AI_API_KEY)
|
|
2567
|
-
stt = BrainScoreSTT(stt) if
|
|
2519
|
+
stt = BrainScoreSTT(stt) if _brain_score_enabled() else stt
|
|
2568
2520
|
return LoggingSTT(stt) if LIVEKIT_VERBOSE_LOGGING else stt
|
|
2569
2521
|
|
|
2570
2522
|
raise ValueError(f"Unsupported LIVEKIT_STT_PROVIDER={LIVEKIT_STT_PROVIDER!r}")
|
|
@@ -6,13 +6,13 @@ import json
|
|
|
6
6
|
import os
|
|
7
7
|
import time
|
|
8
8
|
import uuid
|
|
9
|
-
from collections.abc import Mapping
|
|
10
9
|
from dataclasses import asdict, dataclass
|
|
11
10
|
from pathlib import Path
|
|
12
11
|
|
|
13
12
|
import livekit.api as livekit_api
|
|
14
13
|
|
|
15
14
|
from openbase_coder_cli.cartesia_voice_catalog import (
|
|
15
|
+
DEFAULT_SUPER_AGENT_VOICE_IDS,
|
|
16
16
|
cartesia_voice_for_id,
|
|
17
17
|
cartesia_voice_for_name,
|
|
18
18
|
)
|
|
@@ -120,52 +120,6 @@ def instruction_override_supported() -> bool:
|
|
|
120
120
|
return True
|
|
121
121
|
|
|
122
122
|
|
|
123
|
-
def _super_agent_voices(env: Mapping[str, str]) -> tuple[CartesiaVoice, ...]:
|
|
124
|
-
named_configured = env.get("CARTESIA_SUPER_AGENT_VOICES")
|
|
125
|
-
if named_configured is not None:
|
|
126
|
-
return _parse_voices(named_configured)
|
|
127
|
-
|
|
128
|
-
configured = env.get("CARTESIA_SUPER_AGENT_VOICE_IDS")
|
|
129
|
-
if configured is not None:
|
|
130
|
-
return _voices_from_ids(_parse_voice_ids(configured))
|
|
131
|
-
|
|
132
|
-
dispatcher_voice_id = env.get("CARTESIA_VOICE_ID", DEFAULT_CARTESIA_VOICE_ID)
|
|
133
|
-
announcer_voice_id = env.get(
|
|
134
|
-
"CARTESIA_ANNOUNCER_VOICE_ID",
|
|
135
|
-
DEFAULT_CARTESIA_ANNOUNCER_VOICE_ID,
|
|
136
|
-
)
|
|
137
|
-
return _voices_from_ids(
|
|
138
|
-
voice_id
|
|
139
|
-
for voice_id in (announcer_voice_id,)
|
|
140
|
-
if voice_id and voice_id != dispatcher_voice_id
|
|
141
|
-
)
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
def _parse_voice_ids(value: str) -> tuple[str, ...]:
|
|
145
|
-
return tuple(
|
|
146
|
-
voice_id for voice_id in (part.strip() for part in value.split(",")) if voice_id
|
|
147
|
-
)
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
def _parse_voices(value: str) -> tuple[CartesiaVoice, ...]:
|
|
151
|
-
voices: list[CartesiaVoice] = []
|
|
152
|
-
for part in (part.strip() for part in value.split(",")):
|
|
153
|
-
if not part:
|
|
154
|
-
continue
|
|
155
|
-
voice_id, separator, name = part.partition(":")
|
|
156
|
-
trimmed_voice_id = voice_id.strip()
|
|
157
|
-
if not trimmed_voice_id:
|
|
158
|
-
continue
|
|
159
|
-
trimmed_name = name.strip() if separator else ""
|
|
160
|
-
voices.append(
|
|
161
|
-
CartesiaVoice(
|
|
162
|
-
voice_id=trimmed_voice_id,
|
|
163
|
-
name=trimmed_name or f"Voice {len(voices) + 1}",
|
|
164
|
-
)
|
|
165
|
-
)
|
|
166
|
-
return tuple(voices)
|
|
167
|
-
|
|
168
|
-
|
|
169
123
|
def _voices_from_ids(voice_ids) -> tuple[CartesiaVoice, ...]:
|
|
170
124
|
return tuple(
|
|
171
125
|
CartesiaVoice(
|
|
@@ -178,17 +132,15 @@ def _voices_from_ids(voice_ids) -> tuple[CartesiaVoice, ...]:
|
|
|
178
132
|
)
|
|
179
133
|
|
|
180
134
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
voice.voice_id for voice in CARTESIA_SUPER_AGENT_VOICES
|
|
184
|
-
)
|
|
135
|
+
SUPER_AGENT_VOICE_IDS = DEFAULT_SUPER_AGENT_VOICE_IDS
|
|
136
|
+
SUPER_AGENT_VOICES = _voices_from_ids(SUPER_AGENT_VOICE_IDS)
|
|
185
137
|
|
|
186
138
|
|
|
187
139
|
def _current_super_agent_voices() -> tuple[CartesiaVoice, ...]:
|
|
188
|
-
voice_ids = tuple(voice.voice_id for voice in
|
|
189
|
-
if voice_ids == tuple(
|
|
190
|
-
return
|
|
191
|
-
return _voices_from_ids(
|
|
140
|
+
voice_ids = tuple(voice.voice_id for voice in SUPER_AGENT_VOICES)
|
|
141
|
+
if voice_ids == tuple(SUPER_AGENT_VOICE_IDS):
|
|
142
|
+
return SUPER_AGENT_VOICES
|
|
143
|
+
return _voices_from_ids(SUPER_AGENT_VOICE_IDS)
|
|
192
144
|
|
|
193
145
|
|
|
194
146
|
def stable_super_agent_voice(
|
|
@@ -9,6 +9,8 @@ from typing import Any
|
|
|
9
9
|
from rest_framework.decorators import api_view
|
|
10
10
|
from rest_framework.response import Response
|
|
11
11
|
|
|
12
|
+
from openbase_coder_cli.brain_score import brain_score_token_configured
|
|
13
|
+
|
|
12
14
|
|
|
13
15
|
def default_brain_score_output_path() -> Path:
|
|
14
16
|
return Path(
|
|
@@ -54,19 +56,27 @@ def _read_brain_score_file(path: Path) -> dict[str, Any] | None:
|
|
|
54
56
|
return payload
|
|
55
57
|
|
|
56
58
|
|
|
59
|
+
def _unavailable_response(*, disabled_reason: str | None = None) -> dict[str, Any]:
|
|
60
|
+
return {
|
|
61
|
+
"available": False,
|
|
62
|
+
"brain_readiness_score": None,
|
|
63
|
+
"brs": None,
|
|
64
|
+
"parallel_voice_threshold": None,
|
|
65
|
+
"updated_at": None,
|
|
66
|
+
"computed_at": None,
|
|
67
|
+
"chunk_index": None,
|
|
68
|
+
"age_seconds": None,
|
|
69
|
+
"disabled_reason": disabled_reason,
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
|
|
57
73
|
def build_brain_readiness_response(path: Path | None = None) -> dict[str, Any]:
|
|
74
|
+
if not brain_score_token_configured():
|
|
75
|
+
return _unavailable_response(disabled_reason="missing_token")
|
|
76
|
+
|
|
58
77
|
payload = _read_brain_score_file(path or default_brain_score_output_path())
|
|
59
78
|
if payload is None:
|
|
60
|
-
return
|
|
61
|
-
"available": False,
|
|
62
|
-
"brain_readiness_score": None,
|
|
63
|
-
"brs": None,
|
|
64
|
-
"parallel_voice_threshold": None,
|
|
65
|
-
"updated_at": None,
|
|
66
|
-
"computed_at": None,
|
|
67
|
-
"chunk_index": None,
|
|
68
|
-
"age_seconds": None,
|
|
69
|
-
}
|
|
79
|
+
return _unavailable_response()
|
|
70
80
|
|
|
71
81
|
score = _coerce_score(payload.get("brs"))
|
|
72
82
|
updated_at = payload.get("updated_at")
|
|
@@ -83,6 +93,7 @@ def build_brain_readiness_response(path: Path | None = None) -> dict[str, Any]:
|
|
|
83
93
|
"computed_at": payload.get("computed_at"),
|
|
84
94
|
"chunk_index": payload.get("chunk_index"),
|
|
85
95
|
"age_seconds": age_seconds,
|
|
96
|
+
"disabled_reason": None,
|
|
86
97
|
}
|
|
87
98
|
|
|
88
99
|
|
|
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
|
{openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/livekit_agent/codex_app_client.py
RENAMED
|
File without changes
|
{openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/livekit_agent/codex_thread_state.py
RENAMED
|
File without changes
|
{openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/livekit_agent/codex_transport.py
RENAMED
|
File without changes
|
{openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/livekit_agent/codex_turns.py
RENAMED
|
File without changes
|
{openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/livekit_agent/speech_formatter.py
RENAMED
|
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
|
{openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/__init__.py
RENAMED
|
File without changes
|
{openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/agents_md.py
RENAMED
|
File without changes
|
{openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/approvals.py
RENAMED
|
File without changes
|
{openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/apps.py
RENAMED
|
File without changes
|
{openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/auth.py
RENAMED
|
File without changes
|
{openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/common.py
RENAMED
|
File without changes
|
{openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/consumers.py
RENAMED
|
File without changes
|
|
File without changes
|
{openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/livekit.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/models.py
RENAMED
|
File without changes
|
|
File without changes
|
{openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/projects.py
RENAMED
|
File without changes
|
{openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/reports.py
RENAMED
|
File without changes
|
{openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/routines.py
RENAMED
|
File without changes
|
{openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/routing.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/skills.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/threads.py
RENAMED
|
File without changes
|
{openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/urls.py
RENAMED
|
File without changes
|
{openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/openbase_coder_cli_app/views.py
RENAMED
|
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
|
{openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/services/console_settings.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/services/launchctl_tools.py
RENAMED
|
File without changes
|
|
File without changes
|
{openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/services/openbase_services.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{openbase_coder-0.1.4 → openbase_coder-0.1.5}/openbase_coder_cli/services/tailnet_devices.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|