@oneciel-ai/claude-any 0.1.37 → 0.1.39
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/README.md +18 -1
- package/claude_any.py +271 -108
- package/docs/README.ja.md +18 -1
- package/docs/README.ko.md +18 -1
- package/docs/README.zh.md +17 -1
- package/docs/manual.md +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -48,7 +48,7 @@ arguments through unchanged.
|
|
|
48
48
|
|
|
49
49
|
Credits: One Ciel LLC
|
|
50
50
|
|
|
51
|
-
Current version: `0.1.
|
|
51
|
+
Current version: `0.1.39`
|
|
52
52
|
|
|
53
53
|
## Why This Exists
|
|
54
54
|
|
|
@@ -381,6 +381,23 @@ steps under that larger model's supervision.
|
|
|
381
381
|
|
|
382
382
|
## Changelog
|
|
383
383
|
|
|
384
|
+
### 0.1.39
|
|
385
|
+
|
|
386
|
+
- **Menu input fixes**: restores terminal line/echo mode before text or number
|
|
387
|
+
prompts, so typed numeric values are visible in the prelaunch UI.
|
|
388
|
+
- **Safer numeric validation**: invalid numeric option input now shows an
|
|
389
|
+
inline message instead of crashing the menu.
|
|
390
|
+
- **Preset visibility**: applied presets report the effective context, reserve,
|
|
391
|
+
output, and timeout values.
|
|
392
|
+
|
|
393
|
+
### 0.1.38
|
|
394
|
+
|
|
395
|
+
- **User-selected context windows**: removes the NVIDIA hosted 32K safety cap.
|
|
396
|
+
The router now uses the context window selected in LLM options or headless
|
|
397
|
+
configuration, with model-aware fallback only when no value is configured.
|
|
398
|
+
- **NVIDIA presets updated**: NVIDIA hosted presets now start at 65K and scale
|
|
399
|
+
up to 256K for large-output/reasoning workflows.
|
|
400
|
+
|
|
384
401
|
### 0.1.37
|
|
385
402
|
|
|
386
403
|
- **Pseudo tool-call recovery**: the NVIDIA/OpenAI-compatible stream path now
|
package/claude_any.py
CHANGED
|
@@ -85,7 +85,7 @@ PROVIDER_LABELS = {
|
|
|
85
85
|
"self-hosted-nim": "Self Hosted NIM",
|
|
86
86
|
}
|
|
87
87
|
APP_NAME = "Claude Any"
|
|
88
|
-
VERSION = "0.1.
|
|
88
|
+
VERSION = "0.1.39"
|
|
89
89
|
CREDITS = "Credits: One Ciel LLC"
|
|
90
90
|
|
|
91
91
|
LOG_LEVELS = {"SILENT": 0, "ERROR": 1, "WARN": 2, "INFO": 3, "DEBUG": 4, "TRACE": 5}
|
|
@@ -144,7 +144,7 @@ LANGUAGES = {
|
|
|
144
144
|
"zh": "中文",
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
-
MODEL_PRESETS: dict[str, dict[str, Any]] = {
|
|
147
|
+
MODEL_PRESETS: dict[str, dict[str, Any]] = {
|
|
148
148
|
"glm-4.7": {"compat_max_tokens": 64, "thinking": True, "num_ctx_min": 32768, "num_ctx_max": 131072},
|
|
149
149
|
"glm-5.1": {"compat_max_tokens": 64, "thinking": True, "num_ctx_min": 32768, "num_ctx_max": 131072},
|
|
150
150
|
"glm-4.7:cloud": {"compat_max_tokens": 64, "thinking": True, "num_ctx_min": 32768, "num_ctx_max": 131072},
|
|
@@ -154,10 +154,21 @@ MODEL_PRESETS: dict[str, dict[str, Any]] = {
|
|
|
154
154
|
"qwen3.6:27b": {"compat_max_tokens": 16, "thinking": False, "num_ctx_min": 32768, "num_ctx_max": 65536},
|
|
155
155
|
"deepseek-r1": {"compat_max_tokens": 64, "thinking": True, "num_ctx_min": 32768, "num_ctx_max": 131072},
|
|
156
156
|
"llama3.3:70b": {"compat_max_tokens": 16, "thinking": False, "num_ctx_min": 32768, "num_ctx_max": 131072},
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
def
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
def nvidia_hosted_context_default(model_id: str) -> int:
|
|
161
|
+
model = model_id.lower()
|
|
162
|
+
if "kimi-k2.6" in model or "kimi_k2.6" in model:
|
|
163
|
+
return 262144
|
|
164
|
+
if "deepseek" in model:
|
|
165
|
+
return 131072
|
|
166
|
+
if "glm" in model or "qwen" in model:
|
|
167
|
+
return 65536
|
|
168
|
+
return 65536
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
def model_preset(model_id: str) -> dict[str, Any]:
|
|
161
172
|
"""Return preset dict for a model ID, checking exact match then prefix match."""
|
|
162
173
|
if model_id in MODEL_PRESETS:
|
|
163
174
|
return MODEL_PRESETS[model_id]
|
|
@@ -722,7 +733,7 @@ DEFAULT_CONFIG: dict[str, Any] = {
|
|
|
722
733
|
"native_compat": False,
|
|
723
734
|
"rate_limit_rpm": 40,
|
|
724
735
|
"rate_limit_status": True,
|
|
725
|
-
"context_window":
|
|
736
|
+
"context_window": 65536,
|
|
726
737
|
"max_output_tokens": 4096,
|
|
727
738
|
"temperature": 0.7,
|
|
728
739
|
"top_p": 0.8,
|
|
@@ -788,7 +799,14 @@ def apply_config_migrations(cfg: dict[str, Any]) -> None:
|
|
|
788
799
|
if not migrations.get(marker):
|
|
789
800
|
pcfg = cfg.get("providers", {}).get("nvidia-hosted", {})
|
|
790
801
|
if isinstance(pcfg, dict) and not positive_int(pcfg.get("context_window")):
|
|
791
|
-
pcfg["context_window"] =
|
|
802
|
+
pcfg["context_window"] = nvidia_hosted_context_default(str(pcfg.get("current_model") or ""))
|
|
803
|
+
migrations[marker] = True
|
|
804
|
+
|
|
805
|
+
marker = "nvidia_context_window_unforce_32k_20260513"
|
|
806
|
+
if not migrations.get(marker):
|
|
807
|
+
pcfg = cfg.get("providers", {}).get("nvidia-hosted", {})
|
|
808
|
+
if isinstance(pcfg, dict) and positive_int(pcfg.get("context_window")) == 32768:
|
|
809
|
+
pcfg["context_window"] = nvidia_hosted_context_default(str(pcfg.get("current_model") or ""))
|
|
792
810
|
migrations[marker] = True
|
|
793
811
|
|
|
794
812
|
marker = "stream_enabled_default_true_20260513"
|
|
@@ -3620,7 +3638,7 @@ def openai_context_limit_for_budget(provider: str, pcfg: dict[str, Any]) -> int:
|
|
|
3620
3638
|
if configured:
|
|
3621
3639
|
return configured
|
|
3622
3640
|
if provider == "nvidia-hosted":
|
|
3623
|
-
return
|
|
3641
|
+
return nvidia_hosted_context_default(str(pcfg.get("current_model") or ""))
|
|
3624
3642
|
return 65536
|
|
3625
3643
|
|
|
3626
3644
|
|
|
@@ -6124,14 +6142,72 @@ def apply_llm_preset_to_provider(provider: str, pcfg: dict[str, Any], preset_id:
|
|
|
6124
6142
|
}
|
|
6125
6143
|
for token in tokens_by_preset[preset_id]:
|
|
6126
6144
|
apply_provider_option(provider, pcfg, token)
|
|
6127
|
-
else:
|
|
6128
|
-
native_default = "false" if provider == "nvidia-hosted" else "true"
|
|
6129
|
-
server_limit = upstream_model_context_limit(provider, pcfg) if provider in ("vllm", "self-hosted-nim") else None
|
|
6130
|
-
|
|
6131
|
-
|
|
6132
|
-
"
|
|
6133
|
-
|
|
6134
|
-
|
|
6145
|
+
else:
|
|
6146
|
+
native_default = "false" if provider == "nvidia-hosted" else "true"
|
|
6147
|
+
server_limit = upstream_model_context_limit(provider, pcfg) if provider in ("vllm", "self-hosted-nim") else None
|
|
6148
|
+
if provider == "nvidia-hosted":
|
|
6149
|
+
tokens_by_preset = {
|
|
6150
|
+
"balanced": [
|
|
6151
|
+
"context_window=65536",
|
|
6152
|
+
"reserve=4096",
|
|
6153
|
+
"max_output_tokens=4096",
|
|
6154
|
+
"timeout=300000",
|
|
6155
|
+
"temperature=0.3",
|
|
6156
|
+
"unset:top_p",
|
|
6157
|
+
"unset:top_k",
|
|
6158
|
+
],
|
|
6159
|
+
"coding": [
|
|
6160
|
+
"context_window=65536",
|
|
6161
|
+
"reserve=4096",
|
|
6162
|
+
"max_output_tokens=4096",
|
|
6163
|
+
"timeout=300000",
|
|
6164
|
+
"temperature=0.2",
|
|
6165
|
+
"unset:top_p",
|
|
6166
|
+
"unset:top_k",
|
|
6167
|
+
],
|
|
6168
|
+
"fast": [
|
|
6169
|
+
"context_window=65536",
|
|
6170
|
+
"reserve=2048",
|
|
6171
|
+
"max_output_tokens=2048",
|
|
6172
|
+
"timeout=300000",
|
|
6173
|
+
"temperature=0.2",
|
|
6174
|
+
"unset:top_p",
|
|
6175
|
+
"unset:top_k",
|
|
6176
|
+
],
|
|
6177
|
+
"long-context-65k": [
|
|
6178
|
+
"context_window=131072",
|
|
6179
|
+
"reserve=8192",
|
|
6180
|
+
"max_output_tokens=4096",
|
|
6181
|
+
"timeout=900000",
|
|
6182
|
+
"temperature=0.3",
|
|
6183
|
+
"unset:top_p",
|
|
6184
|
+
"unset:top_k",
|
|
6185
|
+
],
|
|
6186
|
+
"large-output": [
|
|
6187
|
+
"context_window=262144",
|
|
6188
|
+
"reserve=8192",
|
|
6189
|
+
"max_output_tokens=8192",
|
|
6190
|
+
"timeout=1200000",
|
|
6191
|
+
"temperature=0.3",
|
|
6192
|
+
"unset:top_p",
|
|
6193
|
+
"unset:top_k",
|
|
6194
|
+
],
|
|
6195
|
+
"reasoning": [
|
|
6196
|
+
"context_window=262144",
|
|
6197
|
+
"reserve=8192",
|
|
6198
|
+
"max_output_tokens=4096",
|
|
6199
|
+
"timeout=1800000",
|
|
6200
|
+
"temperature=0.6",
|
|
6201
|
+
"unset:top_p",
|
|
6202
|
+
"unset:top_k",
|
|
6203
|
+
],
|
|
6204
|
+
}
|
|
6205
|
+
else:
|
|
6206
|
+
tokens_by_preset = {
|
|
6207
|
+
"balanced": [
|
|
6208
|
+
"context_window=32768",
|
|
6209
|
+
"reserve=2048",
|
|
6210
|
+
"max_output_tokens=4096",
|
|
6135
6211
|
"timeout=300000",
|
|
6136
6212
|
"temperature=0.3",
|
|
6137
6213
|
"unset:top_p",
|
|
@@ -6185,10 +6261,10 @@ def apply_llm_preset_to_provider(provider: str, pcfg: dict[str, Any], preset_id:
|
|
|
6185
6261
|
"timeout=1800000",
|
|
6186
6262
|
"temperature=0.6",
|
|
6187
6263
|
"unset:top_p",
|
|
6188
|
-
"unset:top_k",
|
|
6189
|
-
f"native={native_default}",
|
|
6190
|
-
],
|
|
6191
|
-
|
|
6264
|
+
"unset:top_k",
|
|
6265
|
+
f"native={native_default}",
|
|
6266
|
+
],
|
|
6267
|
+
}
|
|
6192
6268
|
for token in tokens_by_preset[preset_id]:
|
|
6193
6269
|
if provider == "nvidia-hosted" and token.startswith("native="):
|
|
6194
6270
|
continue
|
|
@@ -6206,16 +6282,38 @@ def apply_llm_preset_to_provider(provider: str, pcfg: dict[str, Any], preset_id:
|
|
|
6206
6282
|
f"{ui_text('apply_preset', lang)}: {label}",
|
|
6207
6283
|
f"Provider: {provider}; {ui_text('model_family', lang)}: {model_family_text(family, lang)}",
|
|
6208
6284
|
]
|
|
6209
|
-
if provider in ("vllm", "self-hosted-nim"):
|
|
6210
|
-
server_limit = upstream_model_context_limit(provider, pcfg)
|
|
6211
|
-
if server_limit:
|
|
6212
|
-
lines.append(f"Server max_model_len: {server_limit}")
|
|
6213
|
-
if preset_id in ("long-context-65k", "large-output") and server_limit < 65536:
|
|
6214
|
-
lines.append("Long-context preset requires restarting the server with --max-model-len 65536 or higher.")
|
|
6215
|
-
lines.append("Client settings were capped to the server-reported context length.")
|
|
6216
|
-
elif preset_id in ("long-context-65k", "large-output"):
|
|
6217
|
-
lines.append("Could not verify server max_model_len; vLLM/NIM must be started with a matching context limit.")
|
|
6218
|
-
|
|
6285
|
+
if provider in ("vllm", "nvidia-hosted", "self-hosted-nim"):
|
|
6286
|
+
server_limit = upstream_model_context_limit(provider, pcfg)
|
|
6287
|
+
if server_limit:
|
|
6288
|
+
lines.append(f"Server max_model_len: {server_limit}")
|
|
6289
|
+
if preset_id in ("long-context-65k", "large-output") and server_limit < 65536:
|
|
6290
|
+
lines.append("Long-context preset requires restarting the server with --max-model-len 65536 or higher.")
|
|
6291
|
+
lines.append("Client settings were capped to the server-reported context length.")
|
|
6292
|
+
elif preset_id in ("long-context-65k", "large-output"):
|
|
6293
|
+
lines.append("Could not verify server max_model_len; vLLM/NIM must be started with a matching context limit.")
|
|
6294
|
+
if provider in ("vllm", "nvidia-hosted", "self-hosted-nim"):
|
|
6295
|
+
lines.append(
|
|
6296
|
+
"Applied options: "
|
|
6297
|
+
f"context_window={pcfg.get('context_window', 'default')}, "
|
|
6298
|
+
f"reserve={pcfg.get('context_reserve_tokens', 'default')}, "
|
|
6299
|
+
f"max_output_tokens={pcfg.get('max_output_tokens', 'default')}, "
|
|
6300
|
+
f"timeout={pcfg.get('request_timeout_ms', 'default')}ms"
|
|
6301
|
+
)
|
|
6302
|
+
elif provider in ("ollama", "ollama-cloud"):
|
|
6303
|
+
opts = ollama_extra_options(pcfg)
|
|
6304
|
+
lines.append(
|
|
6305
|
+
"Applied options: "
|
|
6306
|
+
f"num_ctx={ollama_num_ctx_status(pcfg)}, "
|
|
6307
|
+
f"num_predict={opts.get('num_predict', 'default')}, "
|
|
6308
|
+
f"timeout={pcfg.get('request_timeout_ms', 'default')}ms"
|
|
6309
|
+
)
|
|
6310
|
+
elif provider == "anthropic":
|
|
6311
|
+
lines.append(
|
|
6312
|
+
"Applied options: "
|
|
6313
|
+
f"max_output_tokens={pcfg.get('max_output_tokens', 'default')}, "
|
|
6314
|
+
f"timeout={pcfg.get('request_timeout_ms', 'default')}ms"
|
|
6315
|
+
)
|
|
6316
|
+
return lines
|
|
6219
6317
|
|
|
6220
6318
|
|
|
6221
6319
|
def apply_llm_preset_config(provider: str, preset_id: str) -> list[str]:
|
|
@@ -6413,9 +6511,9 @@ def llm_option_panel_rows(provider: str, pcfg: dict[str, Any], lang: str | None
|
|
|
6413
6511
|
add("Rate limit RPM", "rate_limit_rpm", pcfg.get("rate_limit_rpm", 40))
|
|
6414
6512
|
add("Rate limit status", "rate_limit_status", "on" if bool(pcfg.get("rate_limit_status", True)) else "off")
|
|
6415
6513
|
else:
|
|
6416
|
-
if provider in ("vllm", "self-hosted-nim"):
|
|
6417
|
-
add("Context window", "context_window", pcfg.get("context_window", "default"))
|
|
6418
|
-
add("Context reserve", "context_reserve_tokens", pcfg.get("context_reserve_tokens", "default"))
|
|
6514
|
+
if provider in ("vllm", "nvidia-hosted", "self-hosted-nim"):
|
|
6515
|
+
add("Context window", "context_window", pcfg.get("context_window", "default"))
|
|
6516
|
+
add("Context reserve", "context_reserve_tokens", pcfg.get("context_reserve_tokens", "default"))
|
|
6419
6517
|
add("Max output tokens", "max_output_tokens", pcfg.get("max_output_tokens", "default"))
|
|
6420
6518
|
if provider in ("vllm", "nvidia-hosted", "self-hosted-nim"):
|
|
6421
6519
|
add("Timeout ms", "request_timeout_ms", pcfg.get("request_timeout_ms", "default"))
|
|
@@ -6456,13 +6554,38 @@ def llm_option_prompt_default(provider: str, pcfg: dict[str, Any], key: str) ->
|
|
|
6456
6554
|
return "" if value is None else str(value)
|
|
6457
6555
|
|
|
6458
6556
|
|
|
6459
|
-
def set_llm_option_config(provider: str, key: str, raw_value: str) -> list[str]:
|
|
6557
|
+
def set_llm_option_config(provider: str, key: str, raw_value: str) -> list[str]:
|
|
6460
6558
|
cfg = load_config()
|
|
6461
6559
|
pcfg = cfg["providers"][provider]
|
|
6462
|
-
value = raw_value.strip()
|
|
6463
|
-
if not value:
|
|
6464
|
-
return ["Option unchanged."]
|
|
6465
|
-
|
|
6560
|
+
value = raw_value.strip()
|
|
6561
|
+
if not value:
|
|
6562
|
+
return ["Option unchanged."]
|
|
6563
|
+
numeric_keys = {
|
|
6564
|
+
"context_window",
|
|
6565
|
+
"context",
|
|
6566
|
+
"max_model_len",
|
|
6567
|
+
"context_reserve_tokens",
|
|
6568
|
+
"reserve",
|
|
6569
|
+
"max_output_tokens",
|
|
6570
|
+
"max_tokens",
|
|
6571
|
+
"maxtoken",
|
|
6572
|
+
"max_token",
|
|
6573
|
+
"num_ctx_min",
|
|
6574
|
+
"num_ctx_max",
|
|
6575
|
+
"num_predict",
|
|
6576
|
+
"timeout",
|
|
6577
|
+
"timeout_ms",
|
|
6578
|
+
"request_timeout",
|
|
6579
|
+
"request_timeout_ms",
|
|
6580
|
+
"rate_limit",
|
|
6581
|
+
"rate_limit_rpm",
|
|
6582
|
+
"rpm",
|
|
6583
|
+
"top_k",
|
|
6584
|
+
}
|
|
6585
|
+
if key in numeric_keys and value.lower() not in ("default", "unset", "none", "null", "0"):
|
|
6586
|
+
if not re.fullmatch(r"\d+", value):
|
|
6587
|
+
return [f"{key}: enter digits only, or use default/unset to clear."]
|
|
6588
|
+
clear_words = ("default", "unset", "none", "null")
|
|
6466
6589
|
token = f"unset:{key}" if value.lower() in clear_words else f"{key}={value}"
|
|
6467
6590
|
if provider in ("ollama", "ollama-cloud"):
|
|
6468
6591
|
apply_ollama_option(pcfg, token)
|
|
@@ -8040,14 +8163,16 @@ def render_prelaunch_screen(
|
|
|
8040
8163
|
return False
|
|
8041
8164
|
|
|
8042
8165
|
|
|
8043
|
-
def prompt_menu_value(prompt: str, default: str = "", secret: bool = False) -> str:
|
|
8044
|
-
label = f"{prompt}"
|
|
8045
|
-
if default:
|
|
8046
|
-
label += f" [{default}]"
|
|
8047
|
-
label += ": "
|
|
8048
|
-
if
|
|
8049
|
-
|
|
8050
|
-
|
|
8166
|
+
def prompt_menu_value(prompt: str, default: str = "", secret: bool = False, restore_tty: Callable[[], None] | None = None, raw_tty: Callable[[], None] | None = None) -> str:
|
|
8167
|
+
label = f"{prompt}"
|
|
8168
|
+
if default:
|
|
8169
|
+
label += f" [{default}]"
|
|
8170
|
+
label += ": "
|
|
8171
|
+
if restore_tty:
|
|
8172
|
+
restore_tty()
|
|
8173
|
+
if sys.stdout.isatty():
|
|
8174
|
+
sys.stdout.write("\033[?25h")
|
|
8175
|
+
sys.stdout.flush()
|
|
8051
8176
|
sys.stdout.write("\n" + ansi(label, "1;38;5;208"))
|
|
8052
8177
|
sys.stdout.flush()
|
|
8053
8178
|
try:
|
|
@@ -8055,12 +8180,14 @@ def prompt_menu_value(prompt: str, default: str = "", secret: bool = False) -> s
|
|
|
8055
8180
|
value = getpass.getpass("")
|
|
8056
8181
|
else:
|
|
8057
8182
|
value = input()
|
|
8058
|
-
finally:
|
|
8059
|
-
if sys.stdout.isatty():
|
|
8060
|
-
sys.stdout.write("\033[?25l")
|
|
8061
|
-
sys.stdout.flush()
|
|
8062
|
-
|
|
8063
|
-
|
|
8183
|
+
finally:
|
|
8184
|
+
if sys.stdout.isatty():
|
|
8185
|
+
sys.stdout.write("\033[?25l")
|
|
8186
|
+
sys.stdout.flush()
|
|
8187
|
+
if raw_tty:
|
|
8188
|
+
raw_tty()
|
|
8189
|
+
value = value.strip()
|
|
8190
|
+
return value or default
|
|
8064
8191
|
|
|
8065
8192
|
|
|
8066
8193
|
def portable_provider_menu() -> int:
|
|
@@ -8092,22 +8219,23 @@ def portable_prelaunch_menu() -> int:
|
|
|
8092
8219
|
enable_ansi()
|
|
8093
8220
|
main_idx = 7 if settings_ready_except_api_key() else 0
|
|
8094
8221
|
panel: str | None = None
|
|
8095
|
-
panel_idx = 0
|
|
8096
|
-
panel_rows: list[str] = []
|
|
8097
|
-
panel_values: list[str] = []
|
|
8222
|
+
panel_idx = 0
|
|
8223
|
+
panel_rows: list[str] = []
|
|
8224
|
+
panel_values: list[str] = []
|
|
8225
|
+
panel_last_idx: dict[str, int] = {}
|
|
8098
8226
|
checks = preflight_lines()
|
|
8099
8227
|
messages: list[str] = []
|
|
8100
8228
|
first_render = True
|
|
8101
8229
|
|
|
8102
|
-
def open_panel(name: str) -> None:
|
|
8103
|
-
nonlocal panel, panel_idx, panel_rows, panel_values, messages, first_render
|
|
8104
|
-
cfg = load_config()
|
|
8105
|
-
provider, pcfg = get_current_provider(cfg)
|
|
8106
|
-
panel = name
|
|
8107
|
-
panel_idx = 0
|
|
8108
|
-
if name == "language":
|
|
8109
|
-
panel_rows, panel_values = language_panel_rows(cfg)
|
|
8110
|
-
panel_idx = panel_values.index(cfg.get("language", "en"))
|
|
8230
|
+
def open_panel(name: str) -> None:
|
|
8231
|
+
nonlocal panel, panel_idx, panel_rows, panel_values, messages, first_render
|
|
8232
|
+
cfg = load_config()
|
|
8233
|
+
provider, pcfg = get_current_provider(cfg)
|
|
8234
|
+
panel = name
|
|
8235
|
+
panel_idx = panel_last_idx.get(name, 0)
|
|
8236
|
+
if name == "language":
|
|
8237
|
+
panel_rows, panel_values = language_panel_rows(cfg)
|
|
8238
|
+
panel_idx = panel_values.index(cfg.get("language", "en"))
|
|
8111
8239
|
elif name == "provider":
|
|
8112
8240
|
panel_rows, panel_values = provider_panel_rows(cfg)
|
|
8113
8241
|
panel_idx = panel_values.index(provider)
|
|
@@ -8129,15 +8257,19 @@ def portable_prelaunch_menu() -> int:
|
|
|
8129
8257
|
panel_rows, panel_values = [f"Advisor model list failed: {type(exc).__name__}: {exc}", "+ Custom advisor model id..."], []
|
|
8130
8258
|
elif name == "test":
|
|
8131
8259
|
panel_rows, panel_values = ["Run compatibility test", "Back"], ["run", "back"]
|
|
8132
|
-
elif name == "options":
|
|
8133
|
-
panel_rows, panel_values = llm_option_panel_rows(provider, pcfg, cfg.get("language", "en"))
|
|
8134
|
-
elif name == "preset":
|
|
8135
|
-
panel_rows, panel_values = llm_preset_panel_rows(provider, pcfg, cfg.get("language", "en"))
|
|
8136
|
-
|
|
8137
|
-
|
|
8138
|
-
|
|
8139
|
-
|
|
8140
|
-
panel_idx
|
|
8260
|
+
elif name == "options":
|
|
8261
|
+
panel_rows, panel_values = llm_option_panel_rows(provider, pcfg, cfg.get("language", "en"))
|
|
8262
|
+
elif name == "preset":
|
|
8263
|
+
panel_rows, panel_values = llm_preset_panel_rows(provider, pcfg, cfg.get("language", "en"))
|
|
8264
|
+
if panel_rows:
|
|
8265
|
+
panel_idx = max(0, min(panel_idx, len(panel_rows) - 1))
|
|
8266
|
+
|
|
8267
|
+
def close_panel(next_idx: int | None = None) -> None:
|
|
8268
|
+
nonlocal panel, panel_idx, panel_rows, panel_values, main_idx
|
|
8269
|
+
if panel:
|
|
8270
|
+
panel_last_idx[panel] = panel_idx
|
|
8271
|
+
panel = None
|
|
8272
|
+
panel_idx = 0
|
|
8141
8273
|
panel_rows = []
|
|
8142
8274
|
panel_values = []
|
|
8143
8275
|
if next_idx is not None:
|
|
@@ -8160,20 +8292,43 @@ def portable_prelaunch_menu() -> int:
|
|
|
8160
8292
|
termios.tcsetattr(fd, termios.TCSANOW, new)
|
|
8161
8293
|
except Exception:
|
|
8162
8294
|
fd = -1
|
|
8163
|
-
if sys.stdout.isatty():
|
|
8164
|
-
sys.stdout.write("\033[?25l")
|
|
8165
|
-
sys.stdout.flush()
|
|
8166
|
-
|
|
8295
|
+
if sys.stdout.isatty():
|
|
8296
|
+
sys.stdout.write("\033[?25l")
|
|
8297
|
+
sys.stdout.flush()
|
|
8298
|
+
def restore_line_mode() -> None:
|
|
8299
|
+
if old_settings is not None and fd >= 0:
|
|
8300
|
+
try:
|
|
8301
|
+
import termios
|
|
8302
|
+
termios.tcsetattr(fd, termios.TCSANOW, old_settings)
|
|
8303
|
+
except Exception:
|
|
8304
|
+
pass
|
|
8305
|
+
|
|
8306
|
+
def restore_raw_mode() -> None:
|
|
8307
|
+
if old_settings is not None and fd >= 0:
|
|
8308
|
+
try:
|
|
8309
|
+
import termios
|
|
8310
|
+
new = termios.tcgetattr(fd)
|
|
8311
|
+
new[3] = new[3] & ~(termios.ECHO | termios.ICANON)
|
|
8312
|
+
new[6][termios.VMIN] = 1
|
|
8313
|
+
new[6][termios.VTIME] = 0
|
|
8314
|
+
termios.tcsetattr(fd, termios.TCSANOW, new)
|
|
8315
|
+
except Exception:
|
|
8316
|
+
pass
|
|
8317
|
+
|
|
8318
|
+
try:
|
|
8167
8319
|
while True:
|
|
8168
8320
|
first_render = render_prelaunch_screen(main_idx, panel, panel_idx, panel_rows, checks, messages, first_render)
|
|
8169
8321
|
key = read_menu_key(fd) if fd >= 0 else read_menu_key()
|
|
8170
|
-
if panel:
|
|
8171
|
-
|
|
8172
|
-
|
|
8173
|
-
|
|
8174
|
-
|
|
8175
|
-
|
|
8176
|
-
|
|
8322
|
+
if panel:
|
|
8323
|
+
panel_name = panel
|
|
8324
|
+
if key in ("up", "k"):
|
|
8325
|
+
panel_idx = (panel_idx - 1) % max(1, len(panel_rows))
|
|
8326
|
+
panel_last_idx[panel_name] = panel_idx
|
|
8327
|
+
continue
|
|
8328
|
+
if key in ("down", "j"):
|
|
8329
|
+
panel_idx = (panel_idx + 1) % max(1, len(panel_rows))
|
|
8330
|
+
panel_last_idx[panel_name] = panel_idx
|
|
8331
|
+
continue
|
|
8177
8332
|
if key in ("esc", "left", "q"):
|
|
8178
8333
|
close_panel()
|
|
8179
8334
|
continue
|
|
@@ -8198,7 +8353,7 @@ def portable_prelaunch_menu() -> int:
|
|
|
8198
8353
|
close_panel()
|
|
8199
8354
|
continue
|
|
8200
8355
|
if value == "__custom__" or panel_idx >= len(panel_values):
|
|
8201
|
-
model_value = prompt_menu_value("Model id or alias")
|
|
8356
|
+
model_value = prompt_menu_value("Model id or alias", restore_tty=restore_line_mode, raw_tty=restore_raw_mode)
|
|
8202
8357
|
else:
|
|
8203
8358
|
model_value = value
|
|
8204
8359
|
if model_value:
|
|
@@ -8210,7 +8365,7 @@ def portable_prelaunch_menu() -> int:
|
|
|
8210
8365
|
close_panel()
|
|
8211
8366
|
continue
|
|
8212
8367
|
if value == "__custom__" or panel_idx >= len(panel_values):
|
|
8213
|
-
advisor_value = prompt_menu_value("Advisor model id", "deepseek-v4-pro")
|
|
8368
|
+
advisor_value = prompt_menu_value("Advisor model id", "deepseek-v4-pro", restore_tty=restore_line_mode, raw_tty=restore_raw_mode)
|
|
8214
8369
|
else:
|
|
8215
8370
|
advisor_value = value
|
|
8216
8371
|
messages = set_advisor_model_config(advisor_value)
|
|
@@ -8220,7 +8375,7 @@ def portable_prelaunch_menu() -> int:
|
|
|
8220
8375
|
if value == "back":
|
|
8221
8376
|
close_panel()
|
|
8222
8377
|
elif value == "input":
|
|
8223
|
-
key_value = prompt_menu_value(f"API key for {provider}", secret=True)
|
|
8378
|
+
key_value = prompt_menu_value(f"API key for {provider}", secret=True, restore_tty=restore_line_mode, raw_tty=restore_raw_mode)
|
|
8224
8379
|
if key_value:
|
|
8225
8380
|
messages = store_api_key_config(provider, key_value)
|
|
8226
8381
|
refresh_checks()
|
|
@@ -8231,7 +8386,7 @@ def portable_prelaunch_menu() -> int:
|
|
|
8231
8386
|
"nvidia-hosted": "NVIDIA_API_KEY",
|
|
8232
8387
|
"ollama-cloud": "OLLAMA_API_KEY",
|
|
8233
8388
|
}.get(provider, "API_KEY")
|
|
8234
|
-
env_name = prompt_menu_value("Environment variable name", default_env)
|
|
8389
|
+
env_name = prompt_menu_value("Environment variable name", default_env, restore_tty=restore_line_mode, raw_tty=restore_raw_mode)
|
|
8235
8390
|
key_value = os.environ.get(env_name, "").strip()
|
|
8236
8391
|
if key_value:
|
|
8237
8392
|
messages = store_api_key_config(provider, key_value)
|
|
@@ -8244,7 +8399,7 @@ def portable_prelaunch_menu() -> int:
|
|
|
8244
8399
|
if not key_value:
|
|
8245
8400
|
messages = ["Clipboard did not contain readable text."]
|
|
8246
8401
|
else:
|
|
8247
|
-
confirm = prompt_menu_value(f"Clipboard contains {mask_secret(key_value)}. Store it? y/N")
|
|
8402
|
+
confirm = prompt_menu_value(f"Clipboard contains {mask_secret(key_value)}. Store it? y/N", restore_tty=restore_line_mode, raw_tty=restore_raw_mode)
|
|
8248
8403
|
if confirm.lower().startswith("y"):
|
|
8249
8404
|
messages = store_api_key_config(provider, key_value)
|
|
8250
8405
|
else:
|
|
@@ -8260,7 +8415,7 @@ def portable_prelaunch_menu() -> int:
|
|
|
8260
8415
|
close_panel(4)
|
|
8261
8416
|
elif value == "edit":
|
|
8262
8417
|
default = pcfg.get("base_url") or default_base_url(provider)
|
|
8263
|
-
url = prompt_menu_value(f"Base URL for {provider}", default)
|
|
8418
|
+
url = prompt_menu_value(f"Base URL for {provider}", default, restore_tty=restore_line_mode, raw_tty=restore_raw_mode)
|
|
8264
8419
|
if url:
|
|
8265
8420
|
messages = set_base_url_config(provider, url)
|
|
8266
8421
|
refresh_checks()
|
|
@@ -8289,21 +8444,27 @@ def portable_prelaunch_menu() -> int:
|
|
|
8289
8444
|
messages = set_llm_option_config(provider, value, "false" if current else "true")
|
|
8290
8445
|
except Exception as exc:
|
|
8291
8446
|
messages = [f"Option update failed: {type(exc).__name__}: {exc}"]
|
|
8292
|
-
refresh_checks()
|
|
8293
|
-
cfg = load_config()
|
|
8294
|
-
provider, pcfg = get_current_provider(cfg)
|
|
8295
|
-
|
|
8296
|
-
|
|
8297
|
-
|
|
8298
|
-
|
|
8447
|
+
refresh_checks()
|
|
8448
|
+
cfg = load_config()
|
|
8449
|
+
provider, pcfg = get_current_provider(cfg)
|
|
8450
|
+
old_idx = panel_idx
|
|
8451
|
+
panel_rows, panel_values = llm_option_panel_rows(provider, pcfg, cfg.get("language", "en"))
|
|
8452
|
+
panel_idx = max(0, min(old_idx, len(panel_rows) - 1))
|
|
8453
|
+
panel_last_idx["options"] = panel_idx
|
|
8454
|
+
else:
|
|
8455
|
+
default = llm_option_prompt_default(provider, pcfg, value)
|
|
8456
|
+
entered = prompt_menu_value(f"{value} for {provider} (default/unset clears)", default, restore_tty=restore_line_mode, raw_tty=restore_raw_mode)
|
|
8299
8457
|
try:
|
|
8300
8458
|
messages = set_llm_option_config(provider, value, entered)
|
|
8301
8459
|
except Exception as exc:
|
|
8302
8460
|
messages = [f"Option update failed: {type(exc).__name__}: {exc}"]
|
|
8303
|
-
refresh_checks()
|
|
8304
|
-
cfg = load_config()
|
|
8305
|
-
provider, pcfg = get_current_provider(cfg)
|
|
8306
|
-
|
|
8461
|
+
refresh_checks()
|
|
8462
|
+
cfg = load_config()
|
|
8463
|
+
provider, pcfg = get_current_provider(cfg)
|
|
8464
|
+
old_idx = panel_idx
|
|
8465
|
+
panel_rows, panel_values = llm_option_panel_rows(provider, pcfg, cfg.get("language", "en"))
|
|
8466
|
+
panel_idx = max(0, min(old_idx, len(panel_rows) - 1))
|
|
8467
|
+
panel_last_idx["options"] = panel_idx
|
|
8307
8468
|
elif panel == "preset":
|
|
8308
8469
|
if value == "back":
|
|
8309
8470
|
open_panel("options")
|
|
@@ -8315,12 +8476,14 @@ def portable_prelaunch_menu() -> int:
|
|
|
8315
8476
|
except Exception as exc:
|
|
8316
8477
|
messages = [f"Preset failed: {type(exc).__name__}: {exc}"]
|
|
8317
8478
|
refresh_checks()
|
|
8318
|
-
cfg = load_config()
|
|
8319
|
-
provider, pcfg = get_current_provider(cfg)
|
|
8320
|
-
panel = "options"
|
|
8321
|
-
panel_idx = 0
|
|
8322
|
-
panel_rows, panel_values = llm_option_panel_rows(provider, pcfg, cfg.get("language", "en"))
|
|
8323
|
-
|
|
8479
|
+
cfg = load_config()
|
|
8480
|
+
provider, pcfg = get_current_provider(cfg)
|
|
8481
|
+
panel = "options"
|
|
8482
|
+
panel_idx = panel_last_idx.get("options", 0)
|
|
8483
|
+
panel_rows, panel_values = llm_option_panel_rows(provider, pcfg, cfg.get("language", "en"))
|
|
8484
|
+
panel_idx = max(0, min(panel_idx, len(panel_rows) - 1))
|
|
8485
|
+
panel_last_idx["options"] = panel_idx
|
|
8486
|
+
continue
|
|
8324
8487
|
|
|
8325
8488
|
if key in ("up", "k"):
|
|
8326
8489
|
main_idx = (main_idx - 1) % 10
|
package/docs/README.ja.md
CHANGED
|
@@ -47,7 +47,7 @@ vLLM、NVIDIA hosted、self-hosted NIM を選択し、通常の Claude Code 引
|
|
|
47
47
|
|
|
48
48
|
Credits: One Ciel LLC
|
|
49
49
|
|
|
50
|
-
現在のバージョン: `0.1.
|
|
50
|
+
現在のバージョン: `0.1.39`
|
|
51
51
|
|
|
52
52
|
## 作られた理由
|
|
53
53
|
|
|
@@ -351,6 +351,23 @@ Windows/Linux 管理、クリーンアップスクリプト、定期的なセキ
|
|
|
351
351
|
|
|
352
352
|
## 変更履歴
|
|
353
353
|
|
|
354
|
+
### 0.1.39
|
|
355
|
+
|
|
356
|
+
- **メニュー入力修正**: テキスト/数字プロンプトの前に terminal line/echo mode を
|
|
357
|
+
復元し、prelaunch UI で入力した数字が見えるようにしました。
|
|
358
|
+
- **数字検証の安定化**: 数字オプションへ不正な文字を入れてもメニューが
|
|
359
|
+
クラッシュせず、案内メッセージを表示します。
|
|
360
|
+
- **プリセット表示改善**: preset 適用後に実際の context、reserve、output、
|
|
361
|
+
timeout 値をメッセージに表示します。
|
|
362
|
+
|
|
363
|
+
### 0.1.38
|
|
364
|
+
|
|
365
|
+
- **ユーザー選択の context window を優先**: NVIDIA hosted の 32K safety cap を
|
|
366
|
+
削除しました。router は LLM options または headless 設定で選ばれた
|
|
367
|
+
context window を使い、未設定の場合のみモデル別 fallback を使います。
|
|
368
|
+
- **NVIDIA preset 更新**: NVIDIA hosted preset は 65K から開始し、
|
|
369
|
+
large-output/reasoning workflow では 256K まで使います。
|
|
370
|
+
|
|
354
371
|
### 0.1.37
|
|
355
372
|
|
|
356
373
|
- **Pseudo tool-call recovery**: NVIDIA/OpenAI-compatible stream 経路で
|
package/docs/README.ko.md
CHANGED
|
@@ -47,7 +47,7 @@ NVIDIA hosted, self-hosted NIM을 선택하고, Claude Code의 일반 인자는
|
|
|
47
47
|
|
|
48
48
|
Credits: One Ciel LLC
|
|
49
49
|
|
|
50
|
-
현재 버전: `0.1.
|
|
50
|
+
현재 버전: `0.1.39`
|
|
51
51
|
|
|
52
52
|
## 왜 만들었나
|
|
53
53
|
|
|
@@ -351,6 +351,23 @@ Windows 이벤트 로그 리뷰, 바이러스/랜섬웨어 침입 시도 정리,
|
|
|
351
351
|
|
|
352
352
|
## 변경 이력
|
|
353
353
|
|
|
354
|
+
### 0.1.39
|
|
355
|
+
|
|
356
|
+
- **메뉴 입력 수정**: 텍스트/숫자 프롬프트 전에 터미널 line/echo 모드를 복구하여
|
|
357
|
+
prelaunch UI에서 입력한 숫자가 보이게 했습니다.
|
|
358
|
+
- **숫자 검증 안정화**: 숫자 옵션에 잘못된 문자를 넣어도 메뉴가 크래시되지 않고
|
|
359
|
+
안내 메시지를 표시합니다.
|
|
360
|
+
- **프리셋 표시 개선**: preset 적용 후 실제 context, reserve, output, timeout 값을
|
|
361
|
+
메시지에 표시합니다.
|
|
362
|
+
|
|
363
|
+
### 0.1.38
|
|
364
|
+
|
|
365
|
+
- **사용자 선택 context window 우선**: NVIDIA hosted 32K safety cap을 제거했습니다.
|
|
366
|
+
router는 LLM 옵션 또는 headless 설정에서 선택한 context window를 사용하고,
|
|
367
|
+
값이 없을 때만 모델별 fallback을 사용합니다.
|
|
368
|
+
- **NVIDIA preset 업데이트**: NVIDIA hosted preset은 65K부터 시작하고,
|
|
369
|
+
large-output/reasoning 워크플로에서는 256K까지 사용합니다.
|
|
370
|
+
|
|
354
371
|
### 0.1.37
|
|
355
372
|
|
|
356
373
|
- **Pseudo tool-call recovery**: NVIDIA/OpenAI-compatible stream 경로에서
|
package/docs/README.zh.md
CHANGED
|
@@ -47,7 +47,7 @@ NIM,并把普通 Claude Code 参数原样传递。
|
|
|
47
47
|
|
|
48
48
|
Credits: One Ciel LLC
|
|
49
49
|
|
|
50
|
-
当前版本: `0.1.
|
|
50
|
+
当前版本: `0.1.39`
|
|
51
51
|
|
|
52
52
|
## 为什么存在
|
|
53
53
|
|
|
@@ -337,6 +337,22 @@ Hermes 格式模型或部分较旧的 Qwen tool template。
|
|
|
337
337
|
|
|
338
338
|
## 更新日志
|
|
339
339
|
|
|
340
|
+
### 0.1.39
|
|
341
|
+
|
|
342
|
+
- **菜单输入修复**:在文本/数字提示前恢复 terminal line/echo mode,
|
|
343
|
+
prelaunch UI 中输入的数字现在可见。
|
|
344
|
+
- **数字校验更稳**:数字选项输入非法字符时不再让菜单崩溃,而是显示提示消息。
|
|
345
|
+
- **Preset 可见性**:应用 preset 后会显示实际 context、reserve、output、
|
|
346
|
+
timeout 值。
|
|
347
|
+
|
|
348
|
+
### 0.1.38
|
|
349
|
+
|
|
350
|
+
- **优先使用用户选择的 context window**:移除 NVIDIA hosted 的 32K safety cap。
|
|
351
|
+
router 会使用 LLM options 或 headless 配置中选择的 context window,
|
|
352
|
+
只有未配置时才使用按模型推断的 fallback。
|
|
353
|
+
- **NVIDIA preset 更新**:NVIDIA hosted preset 从 65K 起步,
|
|
354
|
+
large-output/reasoning 工作流最高使用 256K。
|
|
355
|
+
|
|
340
356
|
### 0.1.37
|
|
341
357
|
|
|
342
358
|
- **Pseudo tool-call recovery**:NVIDIA/OpenAI-compatible stream 路径现在会
|
package/docs/manual.md
CHANGED
package/package.json
CHANGED