@innvisor/conny-ai 9.8.0 β 9.8.2
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.
- package/CHANGELOG.md +12 -0
- package/conny_app.py +1 -1
- package/conny_i18n.py +81 -2
- package/conny_init.py +20 -0
- package/conny_tui.py +7 -0
- package/npm/conny.js +2 -4
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 9.8.2 - 2026-06-02
|
|
4
|
+
|
|
5
|
+
- persisted the language selected in `conny init` so the rest of the CLI loads it automatically
|
|
6
|
+
- made `conny_i18n` read the saved workspace language on startup
|
|
7
|
+
- kept the `conny init` banner unchanged while aligning other launch paths to the same brand
|
|
8
|
+
|
|
9
|
+
## 9.8.1 - 2026-06-02
|
|
10
|
+
|
|
11
|
+
- made `conny` open the guided setup flow by default instead of the old help banner
|
|
12
|
+
- removed the default launcher banner from the primary `conny` path
|
|
13
|
+
- aligned the TUI version display with `package.json`
|
|
14
|
+
|
|
3
15
|
## 9.8.0 - 2026-06-02
|
|
4
16
|
|
|
5
17
|
- blocked first-contact setup for unknown chats until a valid activation token is provided
|
package/conny_app.py
CHANGED
package/conny_i18n.py
CHANGED
|
@@ -5,6 +5,9 @@ Supported languages: es, en, pt, fr, de
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
from __future__ import annotations
|
|
8
|
+
import json
|
|
9
|
+
import os
|
|
10
|
+
from pathlib import Path
|
|
8
11
|
from typing import Dict, Optional
|
|
9
12
|
from dataclasses import dataclass
|
|
10
13
|
|
|
@@ -20,6 +23,79 @@ SUPPORTED_LANGUAGES = {
|
|
|
20
23
|
DEFAULT_LANGUAGE = "es"
|
|
21
24
|
|
|
22
25
|
|
|
26
|
+
def _workspace_config_path() -> Path:
|
|
27
|
+
explicit = os.environ.get("CONNY_WORKSPACE_CONFIG")
|
|
28
|
+
if explicit:
|
|
29
|
+
return Path(explicit)
|
|
30
|
+
conny_home = os.environ.get("CONNY_HOME")
|
|
31
|
+
if conny_home:
|
|
32
|
+
return Path(conny_home) / "config.json"
|
|
33
|
+
return Path.home() / ".conny" / "config.json"
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _extract_language(payload: object) -> str:
|
|
37
|
+
if not isinstance(payload, dict):
|
|
38
|
+
return ""
|
|
39
|
+
candidates = [
|
|
40
|
+
payload.get("language"),
|
|
41
|
+
payload.get("ui_language"),
|
|
42
|
+
payload.get("locale"),
|
|
43
|
+
]
|
|
44
|
+
for nested_key in ("agent", "meta"):
|
|
45
|
+
nested = payload.get(nested_key)
|
|
46
|
+
if isinstance(nested, dict):
|
|
47
|
+
candidates.append(nested.get("language"))
|
|
48
|
+
candidates.append(nested.get("ui_language"))
|
|
49
|
+
candidates.append(nested.get("locale"))
|
|
50
|
+
for value in candidates:
|
|
51
|
+
if isinstance(value, str) and value in SUPPORTED_LANGUAGES:
|
|
52
|
+
return value
|
|
53
|
+
return ""
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _load_persisted_language() -> str:
|
|
57
|
+
for candidate in (
|
|
58
|
+
os.environ.get("CONNY_LANG"),
|
|
59
|
+
os.environ.get("CONNY_UI_LANG"),
|
|
60
|
+
os.environ.get("CONNY_INIT_LANG"),
|
|
61
|
+
):
|
|
62
|
+
if candidate in SUPPORTED_LANGUAGES:
|
|
63
|
+
return candidate
|
|
64
|
+
path = _workspace_config_path()
|
|
65
|
+
try:
|
|
66
|
+
if path.exists():
|
|
67
|
+
payload = json.loads(path.read_text(encoding="utf-8"))
|
|
68
|
+
lang = _extract_language(payload)
|
|
69
|
+
if lang:
|
|
70
|
+
return lang
|
|
71
|
+
except Exception:
|
|
72
|
+
pass
|
|
73
|
+
return DEFAULT_LANGUAGE
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def _persist_language(lang: str) -> None:
|
|
77
|
+
if lang not in SUPPORTED_LANGUAGES:
|
|
78
|
+
return
|
|
79
|
+
os.environ["CONNY_LANG"] = lang
|
|
80
|
+
os.environ["CONNY_UI_LANG"] = lang
|
|
81
|
+
try:
|
|
82
|
+
path = _workspace_config_path()
|
|
83
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
84
|
+
payload = {}
|
|
85
|
+
if path.exists():
|
|
86
|
+
try:
|
|
87
|
+
payload = json.loads(path.read_text(encoding="utf-8"))
|
|
88
|
+
if not isinstance(payload, dict):
|
|
89
|
+
payload = {}
|
|
90
|
+
except Exception:
|
|
91
|
+
payload = {}
|
|
92
|
+
payload["language"] = lang
|
|
93
|
+
payload["ui_language"] = lang
|
|
94
|
+
path.write_text(json.dumps(payload, indent=2, ensure_ascii=False), encoding="utf-8")
|
|
95
|
+
except Exception:
|
|
96
|
+
pass
|
|
97
|
+
|
|
98
|
+
|
|
23
99
|
@dataclass
|
|
24
100
|
class TranslationSet:
|
|
25
101
|
ui: Dict[str, str]
|
|
@@ -523,7 +599,9 @@ _TRANSLATIONS: Dict[str, TranslationSet] = {
|
|
|
523
599
|
|
|
524
600
|
|
|
525
601
|
class I18n:
|
|
526
|
-
def __init__(self, lang: str =
|
|
602
|
+
def __init__(self, lang: str = None):
|
|
603
|
+
if lang is None:
|
|
604
|
+
lang = _load_persisted_language()
|
|
527
605
|
self.lang = lang if lang in _TRANSLATIONS else DEFAULT_LANGUAGE
|
|
528
606
|
self._cache: Dict[str, str] = {}
|
|
529
607
|
|
|
@@ -576,6 +654,7 @@ def get_i18n() -> I18n:
|
|
|
576
654
|
|
|
577
655
|
def set_language(lang: str) -> None:
|
|
578
656
|
_global_i18n.set_lang(lang)
|
|
657
|
+
_persist_language(lang)
|
|
579
658
|
|
|
580
659
|
|
|
581
660
|
def t(key: str, category: str = "ui") -> str:
|
|
@@ -616,4 +695,4 @@ LANGUAGE_MENU = {
|
|
|
616
695
|
"pt": "π§π· PortuguΓͺs",
|
|
617
696
|
"fr": "π«π· FranΓ§ais",
|
|
618
697
|
"de": "π©πͺ Deutsch",
|
|
619
|
-
}
|
|
698
|
+
}
|
package/conny_init.py
CHANGED
|
@@ -214,6 +214,25 @@ def validate_api_key(provider, key):
|
|
|
214
214
|
return True
|
|
215
215
|
|
|
216
216
|
|
|
217
|
+
def _persist_language(lang: str) -> None:
|
|
218
|
+
try:
|
|
219
|
+
workspace_config_path = Path(os.environ.get("CONNY_WORKSPACE_CONFIG", str(CONNY_HOME / "config.json")))
|
|
220
|
+
workspace_config_path.parent.mkdir(parents=True, exist_ok=True)
|
|
221
|
+
payload = {}
|
|
222
|
+
if workspace_config_path.exists():
|
|
223
|
+
try:
|
|
224
|
+
payload = json.loads(workspace_config_path.read_text(encoding="utf-8"))
|
|
225
|
+
if not isinstance(payload, dict):
|
|
226
|
+
payload = {}
|
|
227
|
+
except Exception:
|
|
228
|
+
payload = {}
|
|
229
|
+
payload["language"] = lang
|
|
230
|
+
payload["ui_language"] = lang
|
|
231
|
+
workspace_config_path.write_text(json.dumps(payload, indent=2, ensure_ascii=False), encoding="utf-8")
|
|
232
|
+
except Exception:
|
|
233
|
+
pass
|
|
234
|
+
|
|
235
|
+
|
|
217
236
|
def _next_available_port() -> int:
|
|
218
237
|
existing_ports = []
|
|
219
238
|
if INSTANCES_DIR.exists():
|
|
@@ -379,6 +398,7 @@ def run_wizard():
|
|
|
379
398
|
lang = LANGUAGES[i][0]
|
|
380
399
|
global CURRENT_LANG
|
|
381
400
|
CURRENT_LANG = lang
|
|
401
|
+
_persist_language(lang)
|
|
382
402
|
|
|
383
403
|
# 1. Identity
|
|
384
404
|
clear()
|
package/conny_tui.py
CHANGED
|
@@ -30,6 +30,13 @@ CONNY_DIR = os.getenv("CONNY_DIR", str(Path(__file__).resolve().parent))
|
|
|
30
30
|
INSTANCES_DIR = os.getenv("INSTANCES_DIR", str(Path.home() / "conny-instances"))
|
|
31
31
|
CLI_SCRIPT = os.getenv("CONNY_CLI", str(Path(__file__).resolve().parent / "conny_cli.py"))
|
|
32
32
|
|
|
33
|
+
try:
|
|
34
|
+
_package_path = Path(CONNY_DIR) / "package.json"
|
|
35
|
+
if _package_path.exists():
|
|
36
|
+
VERSION = json.loads(_package_path.read_text(encoding="utf-8")).get("version", VERSION)
|
|
37
|
+
except Exception:
|
|
38
|
+
pass
|
|
39
|
+
|
|
33
40
|
# ββ Colores curses (Γndices de par) βββββββββββββββββββββββββββββββββββββββββ
|
|
34
41
|
CP_LOGO1 = 1 # Rosa β letras CONNY (gradiente lΓnea 1)
|
|
35
42
|
CP_LOGO2 = 10 # Rosa claro (gradiente lΓnea 2)
|
package/npm/conny.js
CHANGED
|
@@ -518,10 +518,8 @@ if (isHelp) {
|
|
|
518
518
|
process.exit(0);
|
|
519
519
|
}
|
|
520
520
|
|
|
521
|
-
|
|
522
|
-
printBanner();
|
|
523
|
-
}
|
|
521
|
+
const launchArgs = args.length === 0 ? ["new"] : args;
|
|
524
522
|
|
|
525
|
-
if (!execConny(
|
|
523
|
+
if (!execConny(launchArgs)) {
|
|
526
524
|
fail(`No pude iniciar Conny desde ${connyHome}`);
|
|
527
525
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@innvisor/conny-ai",
|
|
3
|
-
"version": "9.8.
|
|
3
|
+
"version": "9.8.2",
|
|
4
4
|
"description": "Open-source CLI and runtime for building Conny AI receptionist agents on WhatsApp and Telegram.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Santiago Rubio",
|
|
@@ -109,4 +109,4 @@
|
|
|
109
109
|
"figlet": "^1.11.0",
|
|
110
110
|
"ora": "^5.4.1"
|
|
111
111
|
}
|
|
112
|
-
}
|
|
112
|
+
}
|