|
@@ -105,11 +105,13 @@ try:
|
|
|
from .platform_config import (
|
|
from .platform_config import (
|
|
|
ChattoConfiguration,
|
|
ChattoConfiguration,
|
|
|
ChattoConstants,
|
|
ChattoConstants,
|
|
|
|
|
+ ConfigValue,
|
|
|
)
|
|
)
|
|
|
except ImportError: # pragma: no cover - loaded as a top-level module (tests)
|
|
except ImportError: # pragma: no cover - loaded as a top-level module (tests)
|
|
|
from platform_config import (
|
|
from platform_config import (
|
|
|
ChattoConfiguration,
|
|
ChattoConfiguration,
|
|
|
ChattoConstants,
|
|
ChattoConstants,
|
|
|
|
|
+ ConfigValue,
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@@ -3624,16 +3626,43 @@ def _chatto_config_for_tools() -> "ChattoConfiguration | None":
|
|
|
if _resolved_chatto_config is not None:
|
|
if _resolved_chatto_config is not None:
|
|
|
return _resolved_chatto_config
|
|
return _resolved_chatto_config
|
|
|
try:
|
|
try:
|
|
|
- from gateway.config import load_gateway_config
|
|
|
|
|
|
|
+ from gateway.config import PlatformConfig
|
|
|
|
|
|
|
|
- config = load_gateway_config()
|
|
|
|
|
- pconfig = config.platforms.get(ChattoConstants.PLATFORM_NAME)
|
|
|
|
|
- if pconfig is not None:
|
|
|
|
|
- _resolved_chatto_config = ChattoConfiguration(pconfig=pconfig)
|
|
|
|
|
- return _resolved_chatto_config
|
|
|
|
|
|
|
+ pconfig = PlatformConfig(enabled=True, extra={})
|
|
|
|
|
+ _resolved_chatto_config = ChattoConfiguration(pconfig=pconfig)
|
|
|
except Exception as exc:
|
|
except Exception as exc:
|
|
|
- logger.warning("Chatto tools: gateway config fallback failed: %s", exc)
|
|
|
|
|
- return None
|
|
|
|
|
|
|
+ logger.warning("Chatto tools: empty pconfig build failed: %s", exc)
|
|
|
|
|
+ return None
|
|
|
|
|
+
|
|
|
|
|
+ # ChattoConfiguration resolves env → extra → default, but in a fresh cron
|
|
|
|
|
+ # scope the dotenv residue is stripped from os.environ. build_profile_secret_scope
|
|
|
|
|
+ # re-reads the profile's own .env directly — works in gateway, cron, and CLI
|
|
|
|
|
+ # contexts alike — so missing fields get a second chance from there.
|
|
|
|
|
+ try:
|
|
|
|
|
+ from agent.secret_scope import build_profile_secret_scope
|
|
|
|
|
+ from hermes_constants import get_hermes_home
|
|
|
|
|
+
|
|
|
|
|
+ profile_secrets = dict(build_profile_secret_scope(get_hermes_home()))
|
|
|
|
|
+ except Exception as exc:
|
|
|
|
|
+ logger.warning("Chatto tools: profile secret scope build failed: %s", exc)
|
|
|
|
|
+ profile_secrets = {}
|
|
|
|
|
+
|
|
|
|
|
+ for field in ChattoConfiguration.fields():
|
|
|
|
|
+ current = _resolved_chatto_config._values.get(field.field_name)
|
|
|
|
|
+ current_value = current.value if current is not None else None
|
|
|
|
|
+ # The profile's own .env is authoritative for secrets (token) and for
|
|
|
|
|
+ # fields whose resolved value is just the declared default (base_url):
|
|
|
|
|
+ # ChattoConfiguration already prefers env vars, so a value that made it
|
|
|
|
|
+ # this far came from extra or the default, both weaker than the .env.
|
|
|
|
|
+ secret_value = profile_secrets.get(field.env_name)
|
|
|
|
|
+ if not secret_value:
|
|
|
|
|
+ continue
|
|
|
|
|
+ if current_value and current_value != field.default:
|
|
|
|
|
+ continue # explicit extra config wins over .env
|
|
|
|
|
+ _resolved_chatto_config._values[field.field_name] = ConfigValue(
|
|
|
|
|
+ secret_value, field.field_name, field.env_name
|
|
|
|
|
+ )
|
|
|
|
|
+ return _resolved_chatto_config
|
|
|
|
|
|
|
|
|
|
|
|
|
async def _handle_chatto_send_dm(args: dict) -> dict:
|
|
async def _handle_chatto_send_dm(args: dict) -> dict:
|