發佈 0.1.6:速度固定 Fast,移除選項與 footer 顯示
摘要: 速度(service tier)固定為 priority(Fast 1.5x):表單移除速度下拉、 footer 不再顯示 Fast 字樣;舊設定檔存空值也會矯正回 priority。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "telegram-codex-bot",
|
"name": "telegram-codex-bot",
|
||||||
"version": "0.1.5",
|
"version": "0.1.6",
|
||||||
"description": "Telegram bot powered by the local Codex CLI — zero-dependency, pm2-managed, with a built-in PM2 web viewer",
|
"description": "Telegram bot powered by the local Codex CLI — zero-dependency, pm2-managed, with a built-in PM2 web viewer",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"type": "commonjs",
|
"type": "commonjs",
|
||||||
|
|||||||
+2
-7
@@ -32,7 +32,7 @@ function loadCodexDefaults() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// — ✅ 16:06:32 | ctx 24% +1.2k | gpt-5.6-sol / high / Fast
|
// — ✅ 16:06:32 | ctx 24% +1.2k | gpt-5.6-sol / high
|
||||||
function buildFooter(config, usage, modelMeta, codexDefaults) {
|
function buildFooter(config, usage, modelMeta, codexDefaults) {
|
||||||
const time = new Date().toLocaleTimeString('zh-TW', { hour12: false });
|
const time = new Date().toLocaleTimeString('zh-TW', { hour12: false });
|
||||||
const parts = [`— ✅ ${time}`];
|
const parts = [`— ✅ ${time}`];
|
||||||
@@ -50,12 +50,7 @@ function buildFooter(config, usage, modelMeta, codexDefaults) {
|
|||||||
|
|
||||||
if (model) {
|
if (model) {
|
||||||
const effort = config.reasoningEffort || codexDefaults.effort || meta?.default_reasoning_level || '';
|
const effort = config.reasoningEffort || codexDefaults.effort || meta?.default_reasoning_level || '';
|
||||||
const tier = config.serviceTier || codexDefaults.tier || '';
|
parts.push(effort ? `${model} / ${effort}` : model);
|
||||||
// 顯示速度層級的名稱(priority → Fast),對照模型快取
|
|
||||||
const tierName = tier
|
|
||||||
? (meta?.service_tiers?.find((t) => t.id === tier)?.name || tier)
|
|
||||||
: '';
|
|
||||||
parts.push([model, effort, tierName].filter(Boolean).join(' / '));
|
|
||||||
}
|
}
|
||||||
return `\n\n${parts.join(' | ')}`;
|
return `\n\n${parts.join(' | ')}`;
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-2
@@ -18,8 +18,8 @@ const DEFAULTS = {
|
|||||||
model: '',
|
model: '',
|
||||||
// 推理強度(low/medium/high/xhigh/max/ultra…依模型而定);空字串 = codex 預設
|
// 推理強度(low/medium/high/xhigh/max/ultra…依模型而定);空字串 = codex 預設
|
||||||
reasoningEffort: '',
|
reasoningEffort: '',
|
||||||
// 速度(service tier,如 priority = Fast 1.5x);空字串 = codex 預設
|
// 速度固定 Fast(priority = 1.5x);要改只能手動編輯設定檔
|
||||||
serviceTier: '',
|
serviceTier: 'priority',
|
||||||
// 單次回應逾時(分鐘)
|
// 單次回應逾時(分鐘)
|
||||||
timeoutMinutes: 30,
|
timeoutMinutes: 30,
|
||||||
// pm2 程序名稱(web 檢視工具會叫 <pm2Name>-web)
|
// pm2 程序名稱(web 檢視工具會叫 <pm2Name>-web)
|
||||||
@@ -80,6 +80,9 @@ function loadConfig(explicitPath) {
|
|||||||
}
|
}
|
||||||
cfg.web.port = port;
|
cfg.web.port = port;
|
||||||
}
|
}
|
||||||
|
// 速度政策固定 Fast:舊設定檔存了空值也矯正回 priority
|
||||||
|
if (!cfg.serviceTier) cfg.serviceTier = 'priority';
|
||||||
|
|
||||||
const minutes = Number(cfg.timeoutMinutes);
|
const minutes = Number(cfg.timeoutMinutes);
|
||||||
if (!(minutes > 0)) throw new Error(`timeoutMinutes 必須是正數:${cfg.timeoutMinutes}`);
|
if (!(minutes > 0)) throw new Error(`timeoutMinutes 必須是正數:${cfg.timeoutMinutes}`);
|
||||||
cfg.timeoutMinutes = minutes;
|
cfg.timeoutMinutes = minutes;
|
||||||
|
|||||||
+2
-3
@@ -112,7 +112,7 @@ function validateBotInput({ name, token, workDir, sandbox }, { isCreate }) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createBot({ name, token, workDir, sandbox, model, reasoningEffort, serviceTier, timeoutMinutes }) {
|
async function createBot({ name, token, workDir, sandbox, model, reasoningEffort, timeoutMinutes }) {
|
||||||
validateBotInput({ name, token, workDir, sandbox }, { isCreate: true });
|
validateBotInput({ name, token, workDir, sandbox }, { isCreate: true });
|
||||||
const reg = loadRegistry();
|
const reg = loadRegistry();
|
||||||
if (reg.bots[name]) throw new Error(`已有同名 bot:${name}`);
|
if (reg.bots[name]) throw new Error(`已有同名 bot:${name}`);
|
||||||
@@ -128,7 +128,7 @@ async function createBot({ name, token, workDir, sandbox, model, reasoningEffort
|
|||||||
sandbox: sandbox || 'workspace-write',
|
sandbox: sandbox || 'workspace-write',
|
||||||
model: model || '',
|
model: model || '',
|
||||||
reasoningEffort: reasoningEffort || '',
|
reasoningEffort: reasoningEffort || '',
|
||||||
serviceTier: serviceTier || '',
|
serviceTier: 'priority', // 速度固定 Fast 1.5x
|
||||||
timeoutMinutes: Number(timeoutMinutes) || 30,
|
timeoutMinutes: Number(timeoutMinutes) || 30,
|
||||||
pm2Name: name,
|
pm2Name: name,
|
||||||
// UI 建的 bot 不各自開 web,統一由控制台管理
|
// UI 建的 bot 不各自開 web,統一由控制台管理
|
||||||
@@ -158,7 +158,6 @@ async function updateBot(name, patch) {
|
|||||||
}
|
}
|
||||||
if (patch.model !== undefined) raw.model = patch.model;
|
if (patch.model !== undefined) raw.model = patch.model;
|
||||||
if (patch.reasoningEffort !== undefined) raw.reasoningEffort = patch.reasoningEffort;
|
if (patch.reasoningEffort !== undefined) raw.reasoningEffort = patch.reasoningEffort;
|
||||||
if (patch.serviceTier !== undefined) raw.serviceTier = patch.serviceTier;
|
|
||||||
if (patch.timeoutMinutes !== undefined && Number(patch.timeoutMinutes) > 0) {
|
if (patch.timeoutMinutes !== undefined && Number(patch.timeoutMinutes) > 0) {
|
||||||
raw.timeoutMinutes = Number(patch.timeoutMinutes);
|
raw.timeoutMinutes = Number(patch.timeoutMinutes);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -217,10 +217,7 @@
|
|||||||
<div class="field">
|
<div class="field">
|
||||||
<label>推理強度</label>
|
<label>推理強度</label>
|
||||||
<select id="f-effort"></select>
|
<select id="f-effort"></select>
|
||||||
</div>
|
<div class="hint">速度固定為 Fast(1.5x)</div>
|
||||||
<div class="field">
|
|
||||||
<label>速度</label>
|
|
||||||
<select id="f-tier"></select>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label>逾時(分鐘)</label>
|
<label>逾時(分鐘)</label>
|
||||||
@@ -314,7 +311,7 @@ async function loadModels() {
|
|||||||
} catch { modelsCache = []; }
|
} catch { modelsCache = []; }
|
||||||
}
|
}
|
||||||
// 下拉沒有「預設」空選項:直接把真實預設值選起來
|
// 下拉沒有「預設」空選項:直接把真實預設值選起來
|
||||||
function populateModelSelects(selModel, selEffort, selTier) {
|
function populateModelSelects(selModel, selEffort) {
|
||||||
const mSel = document.getElementById('f-model');
|
const mSel = document.getElementById('f-model');
|
||||||
let opts = modelsCache.map(m => '<option value="' + esc(m.slug) + '">' + esc(m.label) + '</option>').join('');
|
let opts = modelsCache.map(m => '<option value="' + esc(m.slug) + '">' + esc(m.label) + '</option>').join('');
|
||||||
// 設定檔裡有但快取沒有的模型(手填過的)也要能顯示
|
// 設定檔裡有但快取沒有的模型(手填過的)也要能顯示
|
||||||
@@ -326,9 +323,9 @@ function populateModelSelects(selModel, selEffort, selTier) {
|
|||||||
const wanted = selModel || modelDefaults.model;
|
const wanted = selModel || modelDefaults.model;
|
||||||
mSel.value = wanted;
|
mSel.value = wanted;
|
||||||
if (mSel.value !== wanted || !mSel.value) mSel.selectedIndex = 0;
|
if (mSel.value !== wanted || !mSel.value) mSel.selectedIndex = 0;
|
||||||
syncEffortTier(selEffort, selTier);
|
syncEffortTier(selEffort);
|
||||||
}
|
}
|
||||||
function syncEffortTier(selEffort, selTier) {
|
function syncEffortTier(selEffort) {
|
||||||
const slug = document.getElementById('f-model').value;
|
const slug = document.getElementById('f-model').value;
|
||||||
const m = modelsCache.find(x => x.slug === slug);
|
const m = modelsCache.find(x => x.slug === slug);
|
||||||
let efforts = m ? m.efforts.slice() : ['low', 'medium', 'high', 'xhigh', 'max'];
|
let efforts = m ? m.efforts.slice() : ['low', 'medium', 'high', 'xhigh', 'max'];
|
||||||
@@ -341,22 +338,6 @@ function syncEffortTier(selEffort, selTier) {
|
|||||||
: efforts.includes(modelDefaults.effort) ? modelDefaults.effort
|
: efforts.includes(modelDefaults.effort) ? modelDefaults.effort
|
||||||
: (m && efforts.includes(m.defaultEffort)) ? m.defaultEffort
|
: (m && efforts.includes(m.defaultEffort)) ? m.defaultEffort
|
||||||
: efforts[0];
|
: efforts[0];
|
||||||
|
|
||||||
const tiers = m ? m.tiers.slice() : [];
|
|
||||||
const tSel = document.getElementById('f-tier');
|
|
||||||
const prevT = (selTier !== undefined && selTier !== '') ? selTier : tSel.value;
|
|
||||||
if (!tiers.length) {
|
|
||||||
tSel.innerHTML = '<option value="">標準</option>';
|
|
||||||
tSel.value = '';
|
|
||||||
} else {
|
|
||||||
// 模型快取只列「額外」的速度層級,補一個標準選項在前面
|
|
||||||
tSel.innerHTML = '<option value="">標準</option>' +
|
|
||||||
tiers.map(t => '<option value="' + esc(t.id) + '">' + esc(t.name) + (t.description ? '(' + esc(t.description) + ')' : '') + '</option>').join('');
|
|
||||||
tSel.value = tiers.some(t => t.id === prevT) ? prevT
|
|
||||||
: tiers.some(t => t.id === modelDefaults.tier) ? modelDefaults.tier
|
|
||||||
: tiers.some(t => t.id === (m && m.defaultTier)) ? m.defaultTier
|
|
||||||
: '';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------- Bot 管理 ----------
|
// ---------- Bot 管理 ----------
|
||||||
@@ -393,8 +374,8 @@ function renderBots(bots) {
|
|||||||
'<td>' + statusBadge(b.status) + '</td>' +
|
'<td>' + statusBadge(b.status) + '</td>' +
|
||||||
'<td><span class="mono" title="' + esc(b.workDir) + '">' + esc(shortPath(b.workDir)) + '</span></td>' +
|
'<td><span class="mono" title="' + esc(b.workDir) + '">' + esc(shortPath(b.workDir)) + '</span></td>' +
|
||||||
'<td class="mono">' + esc(b.sandbox || '-') +
|
'<td class="mono">' + esc(b.sandbox || '-') +
|
||||||
((b.model || b.reasoningEffort || b.serviceTier)
|
((b.model || b.reasoningEffort)
|
||||||
? '<br><span class="script-name">' + esc([b.model, b.reasoningEffort, b.serviceTier].filter(Boolean).join(' / ')) + '</span>'
|
? '<br><span class="script-name">' + esc([b.model, b.reasoningEffort].filter(Boolean).join(' / ')) + '</span>'
|
||||||
: '') + '</td>' +
|
: '') + '</td>' +
|
||||||
'<td class="mono">' + esc(b.tokenMasked || '-') + '</td>' +
|
'<td class="mono">' + esc(b.tokenMasked || '-') + '</td>' +
|
||||||
'<td>' + fmtBytes(b.memory) + '</td>' +
|
'<td>' + fmtBytes(b.memory) + '</td>' +
|
||||||
@@ -462,7 +443,7 @@ function openCreate() {
|
|||||||
document.getElementById('f-token-hint').textContent = '跟 @BotFather 申請;儲存時會自動驗證';
|
document.getElementById('f-token-hint').textContent = '跟 @BotFather 申請;儲存時會自動驗證';
|
||||||
document.getElementById('f-workdir').value = '';
|
document.getElementById('f-workdir').value = '';
|
||||||
document.getElementById('f-sandbox').value = 'workspace-write';
|
document.getElementById('f-sandbox').value = 'workspace-write';
|
||||||
populateModelSelects('', '', '');
|
populateModelSelects('', '');
|
||||||
document.getElementById('f-timeout').value = '30';
|
document.getElementById('f-timeout').value = '30';
|
||||||
document.getElementById('f-autostart-wrap').style.display = '';
|
document.getElementById('f-autostart-wrap').style.display = '';
|
||||||
document.getElementById('f-autostart').checked = true;
|
document.getElementById('f-autostart').checked = true;
|
||||||
@@ -483,7 +464,7 @@ function openEdit(name) {
|
|||||||
document.getElementById('f-token-hint').textContent = '留空表示沿用現有 token';
|
document.getElementById('f-token-hint').textContent = '留空表示沿用現有 token';
|
||||||
document.getElementById('f-workdir').value = b.workDir || '';
|
document.getElementById('f-workdir').value = b.workDir || '';
|
||||||
document.getElementById('f-sandbox').value = b.sandbox || 'workspace-write';
|
document.getElementById('f-sandbox').value = b.sandbox || 'workspace-write';
|
||||||
populateModelSelects(b.model || '', b.reasoningEffort || '', b.serviceTier || '');
|
populateModelSelects(b.model || '', b.reasoningEffort || '');
|
||||||
document.getElementById('f-timeout').value = b.timeoutMinutes || 30;
|
document.getElementById('f-timeout').value = b.timeoutMinutes || 30;
|
||||||
document.getElementById('f-autostart-wrap').style.display = 'none';
|
document.getElementById('f-autostart-wrap').style.display = 'none';
|
||||||
document.getElementById('bot-modal').classList.add('show');
|
document.getElementById('bot-modal').classList.add('show');
|
||||||
@@ -504,7 +485,6 @@ async function saveBot() {
|
|||||||
sandbox: document.getElementById('f-sandbox').value,
|
sandbox: document.getElementById('f-sandbox').value,
|
||||||
model: document.getElementById('f-model').value,
|
model: document.getElementById('f-model').value,
|
||||||
reasoningEffort: document.getElementById('f-effort').value,
|
reasoningEffort: document.getElementById('f-effort').value,
|
||||||
serviceTier: document.getElementById('f-tier').value,
|
|
||||||
timeoutMinutes: document.getElementById('f-timeout').value,
|
timeoutMinutes: document.getElementById('f-timeout').value,
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in New Issue
Block a user