feat: 添加时区设置功能,默认时区改为 CST-8
- 新增 set_timezone LLM 工具,支持通过对话设置时区 - 新增 set_timezone / timezone_show CLI 命令 - 默认时区从 PST 改为 CST-8(中国标准时间 UTC+8) - 支持 POSIX 格式和 18 个城市名映射(Asia/Shanghai 等) - 时区通过 NVS 持久化存储(system_config namespace) - config_show 中显示当前时区配置 - 更新 changelog.md 和 taolun.md 文档
This commit is contained in:
@@ -56,10 +56,14 @@ static const char ONBOARD_HTML[] =
|
||||
"<label>Model</label>"
|
||||
"<input id='model' placeholder='claude-opus-4-5' value='claude-opus-4-5'>"
|
||||
"<label>Provider</label>"
|
||||
"<select id='provider'>"
|
||||
"<select id='provider' onchange='onProviderChange()'>"
|
||||
"<option value='anthropic'>Anthropic</option>"
|
||||
"<option value='openai'>OpenAI</option>"
|
||||
"<option value='siliconflow'>SiliconFlow (硅基流动)</option>"
|
||||
"<option value='volcengine'>Volcengine (火山引擎)</option>"
|
||||
"</select>"
|
||||
"<label>Base URL</label>"
|
||||
"<input id='base_url' placeholder='https://api.example.com/v1'>"
|
||||
"</div></div>"
|
||||
|
||||
/* Telegram section */
|
||||
@@ -133,8 +137,15 @@ static const char ONBOARD_HTML[] =
|
||||
"btn.textContent='Scan WiFi Networks';btn.disabled=false;"
|
||||
"}).catch(()=>{btn.textContent='Scan WiFi Networks';btn.disabled=false})}"
|
||||
|
||||
"function onProviderChange(){"
|
||||
"var p=document.getElementById('provider').value;"
|
||||
"var u=document.getElementById('base_url');"
|
||||
"if(p==='siliconflow'){u.value='https://api.siliconflow.cn/v1'}"
|
||||
"else if(p==='volcengine'){u.value='https://ark.cn-beijing.volces.com/api/v3'}"
|
||||
"else{u.value=''}}"
|
||||
|
||||
"function save(){"
|
||||
"var fields=['ssid','password','api_key','model','provider','tg_token',"
|
||||
"var fields=['ssid','password','api_key','model','provider','base_url','tg_token',"
|
||||
"'feishu_app_id','feishu_app_secret','proxy_host','proxy_port','proxy_type','search_key','tavily_key'];"
|
||||
"var data={};"
|
||||
"fields.forEach(f=>{data[f]=document.getElementById(f).value.trim()});"
|
||||
|
||||
@@ -220,6 +220,40 @@ static esp_err_t http_get_config(httpd_req_t *req)
|
||||
json_add_effective_config(root, "api_key", MIMI_NVS_LLM, MIMI_NVS_KEY_API_KEY, MIMI_SECRET_API_KEY);
|
||||
json_add_effective_config(root, "model", MIMI_NVS_LLM, MIMI_NVS_KEY_MODEL, MIMI_SECRET_MODEL);
|
||||
json_add_effective_config(root, "provider", MIMI_NVS_LLM, MIMI_NVS_KEY_PROVIDER, MIMI_SECRET_MODEL_PROVIDER);
|
||||
|
||||
/* Provider-specific Base URL (load from current provider's NVS key) */
|
||||
{
|
||||
char base_url[256] = {0};
|
||||
bool found = false;
|
||||
char provider[32] = {0};
|
||||
nvs_handle_t nvs;
|
||||
if (nvs_open(MIMI_NVS_LLM, NVS_READONLY, &nvs) == ESP_OK) {
|
||||
size_t len = sizeof(provider);
|
||||
if (nvs_get_str(nvs, MIMI_NVS_KEY_PROVIDER, provider, &len) != ESP_OK || !provider[0]) {
|
||||
/* Fall back to build-time provider if NVS doesn't have one */
|
||||
strlcpy(provider, MIMI_SECRET_MODEL_PROVIDER, sizeof(provider));
|
||||
}
|
||||
/* Try to load provider-specific base URL from NVS */
|
||||
const char *url_key = NULL;
|
||||
if (strcmp(provider, "anthropic") == 0) url_key = MIMI_NVS_KEY_ANTHROPIC_BASE_URL;
|
||||
else if (strcmp(provider, "openai") == 0) url_key = MIMI_NVS_KEY_OPENAI_BASE_URL;
|
||||
else if (strcmp(provider, "siliconflow") == 0) url_key = MIMI_NVS_KEY_SILICONFLOW_BASE_URL;
|
||||
else if (strcmp(provider, "volcengine") == 0) url_key = MIMI_NVS_KEY_VOLCENGINE_BASE_URL;
|
||||
if (url_key) {
|
||||
len = sizeof(base_url);
|
||||
if (nvs_get_str(nvs, url_key, base_url, &len) == ESP_OK && base_url[0]) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
nvs_close(nvs);
|
||||
}
|
||||
if (!found) {
|
||||
/* Fall back to build-time defaults */
|
||||
if (strcmp(provider, "siliconflow") == 0) strlcpy(base_url, MIMI_SECRET_SILICONFLOW_BASE_URL, sizeof(base_url));
|
||||
else if (strcmp(provider, "volcengine") == 0) strlcpy(base_url, MIMI_SECRET_VOLCENGINE_BASE_URL, sizeof(base_url));
|
||||
}
|
||||
cJSON_AddStringToObject(root, "base_url", base_url);
|
||||
}
|
||||
json_add_effective_config(root, "tg_token", MIMI_NVS_TG, MIMI_NVS_KEY_TG_TOKEN, MIMI_SECRET_TG_TOKEN);
|
||||
json_add_effective_config(root, "feishu_app_id", MIMI_NVS_FEISHU, MIMI_NVS_KEY_FEISHU_APP_ID, MIMI_SECRET_FEISHU_APP_ID);
|
||||
json_add_effective_config(root, "feishu_app_secret", MIMI_NVS_FEISHU, MIMI_NVS_KEY_FEISHU_APP_SECRET, MIMI_SECRET_FEISHU_APP_SECRET);
|
||||
@@ -344,6 +378,37 @@ static esp_err_t http_post_save(httpd_req_t *req)
|
||||
nvs_sync_field(root, "model", MIMI_NVS_LLM, MIMI_NVS_KEY_MODEL);
|
||||
nvs_sync_field(root, "provider", MIMI_NVS_LLM, MIMI_NVS_KEY_PROVIDER);
|
||||
|
||||
/* Save API key and base URL to provider-specific NVS keys */
|
||||
{
|
||||
cJSON *provider_item = cJSON_GetObjectItem(root, "provider");
|
||||
cJSON *api_key_item = cJSON_GetObjectItem(root, "api_key");
|
||||
cJSON *base_url_item = cJSON_GetObjectItem(root, "base_url");
|
||||
if (provider_item && cJSON_IsString(provider_item) && provider_item->valuestring[0]) {
|
||||
const char *provider = provider_item->valuestring;
|
||||
const char *api_key_nvs = NULL;
|
||||
const char *base_url_nvs = NULL;
|
||||
if (strcmp(provider, "anthropic") == 0) {
|
||||
api_key_nvs = MIMI_NVS_KEY_ANTHROPIC_API_KEY;
|
||||
base_url_nvs = MIMI_NVS_KEY_ANTHROPIC_BASE_URL;
|
||||
} else if (strcmp(provider, "openai") == 0) {
|
||||
api_key_nvs = MIMI_NVS_KEY_OPENAI_API_KEY;
|
||||
base_url_nvs = MIMI_NVS_KEY_OPENAI_BASE_URL;
|
||||
} else if (strcmp(provider, "siliconflow") == 0) {
|
||||
api_key_nvs = MIMI_NVS_KEY_SILICONFLOW_API_KEY;
|
||||
base_url_nvs = MIMI_NVS_KEY_SILICONFLOW_BASE_URL;
|
||||
} else if (strcmp(provider, "volcengine") == 0) {
|
||||
api_key_nvs = MIMI_NVS_KEY_VOLCENGINE_API_KEY;
|
||||
base_url_nvs = MIMI_NVS_KEY_VOLCENGINE_BASE_URL;
|
||||
}
|
||||
if (api_key_nvs && api_key_item && cJSON_IsString(api_key_item)) {
|
||||
nvs_sync_field(root, "api_key", MIMI_NVS_LLM, api_key_nvs);
|
||||
}
|
||||
if (base_url_nvs && base_url_item && cJSON_IsString(base_url_item)) {
|
||||
nvs_sync_field(root, "base_url", MIMI_NVS_LLM, base_url_nvs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Telegram */
|
||||
nvs_sync_field(root, "tg_token", MIMI_NVS_TG, MIMI_NVS_KEY_TG_TOKEN);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user