Skip to content

Commit b78a51e

Browse files
author
weiesky.wangc
committed
fix(system-prompt): bare k3 resolves to the Kimi entry (1.7.18)
Third-party proxies normalize k3[1m] → bare k3 at spawn, which never matched KIMI / KIMI-K3 entries (the match is id.includes(entryName), and "k3" contains neither). matchModelPrompt now expands a small alias table (k3 → k3 / kimi-k3 / kimi) before substring matching, so the Kimi preset actually injects for kimi-profile sessions; non-alias ids are untouched. Also ships the merged PR #139 composer polish as 1.7.18.
1 parent 73e4b44 commit b78a51e

5 files changed

Lines changed: 53 additions & 5 deletions

File tree

history.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## Unreleased
44

55
- ui(chat): **PC composer polish** — the composer card is capped at 1000px and centered on wide screens (shrinks responsively below); the card sits on its own input strip (`--bg-input-strip`, light gray `#F9F9F9` in the light theme) as a pure-white surface with a soft 8px drop shadow; and focusing the desktop textarea animates it to two lines (`height 0.2s ease`), collapsing back to content height (min one line) on blur. Autosize moved to a shared content-box helper (`resizeChatTextarea`) so an empty input snaps to exactly one line; mobile metrics/behavior unchanged.
6+
- fix(system-prompt): **bare `k3` resolves to the Kimi entry** — third-party proxies normalize `k3[1m]` → bare `k3` at spawn, which never matched `KIMI` / `KIMI-K3` entries (the match is `id.includes(entryName)`, and `"k3"` contains neither). `matchModelPrompt` now expands a small alias table (`k3``k3` / `kimi-k3` / `kimi`) before substring matching, so the Kimi preset actually injects for kimi-profile sessions; non-alias ids are untouched.
67

78
## 1.7.17 (2026-08-05)
89

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "cc-viewer",
3-
"version": "1.7.17",
3+
"version": "1.7.18",
44
"description": "Claude Code logging, visualization, and management toolkit — launch a web viewer alongside Claude Code with full request/response tracing, proxy, and mobile support",
55
"license": "MIT",
66
"main": "server.js",

server/lib/model-system-prompts.js

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,13 +241,36 @@ export function deleteModelPrompt(dir, name) {
241241
* @param {Array<{ dir: string, scope: 'workspace'|'global' }>} candidates
242242
* @returns {{ path: string, fileName: string, name: string, mode: 'override'|'append', scope: 'workspace'|'global' } | null}
243243
*/
244+
// 模型 id 别名表:第三方代理常把模型名归一化成不带厂商前缀的简写(kimi profile 把
245+
// `k3[1m]` 剥后缀后得到裸 `k3`),而条目名通常带前缀(KIMI / KIMI-K3)。别名在子串
246+
// 匹配前把解析名展开成「所有等价拼写」,任一变体命中即算命中。key 与变体都是小写
247+
// 完整词(精确等值,非子串),只在解析名**恰好等于** key 时展开,避免误放大。
248+
// Model id aliases: third-party proxies often normalize model names to a bare
249+
// shorthand (the kimi profile strips `k3[1m]` → `k3`), while entry names carry the
250+
// vendor prefix (KIMI / KIMI-K3). Aliases expand the resolved id into every
251+
// equivalent spelling before substring matching. Keys and variants are lowercase
252+
// full words (exact equality, not substrings), so expansion only fires when the
253+
// resolved id IS the bare shorthand — no accidental widening.
254+
const MODEL_ID_ALIASES = {
255+
k3: ['k3', 'kimi-k3', 'kimi'],
256+
};
257+
258+
// 展开模型 id 的全部等价小写拼写(无别名时就是单元素数组)。
259+
// Expand a model id into every equivalent lowercase spelling.
260+
function modelIdVariants(id) {
261+
return MODEL_ID_ALIASES[id] || [id];
262+
}
263+
244264
export function matchModelPrompt(modelId, candidates) {
245265
if (!modelId || typeof modelId !== 'string') return null;
246266
if (!Array.isArray(candidates)) return null;
247-
const id = modelId.toLowerCase();
267+
const variants = modelIdVariants(modelId.toLowerCase());
248268
for (const cand of candidates) {
249269
if (!cand || !cand.dir) continue;
250-
const hits = listModelPrompts(cand.dir).filter((e) => id.includes(e.name.toLowerCase()));
270+
const hits = listModelPrompts(cand.dir).filter((e) => {
271+
const entryName = e.name.toLowerCase();
272+
return variants.some((v) => v.includes(entryName));
273+
});
251274
if (!hits.length) continue;
252275
hits.sort((a, b) => b.name.length - a.name.length || a.name.localeCompare(b.name));
253276
const e = hits[0];

test/model-system-prompts.test.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,4 +201,28 @@ describe('model-system-prompts: 读写/列表/匹配', () => {
201201
assert.equal(matchModelPrompt('claude-opus-4-8', [{ scope: 'global' }]), null);
202202
assert.equal(matchModelPrompt('claude-opus-4-8', [null, { dir, scope: 'global' }])?.name, 'OPUS');
203203
});
204+
205+
it('match: 裸 k3 经别名展开命中 KIMI 与 KIMI-K3(最长名字优先)', () => {
206+
const dir = join(mkTmp(), MODEL_PROMPT_DIR);
207+
writeModelPrompt(dir, 'kimi', 'override', 'kimi');
208+
writeModelPrompt(dir, 'kimi-k3', 'override', 'kimi-k3');
209+
const r = matchModelPrompt('k3', [{ dir, scope: 'global' }]);
210+
// 两个条目都能命中(kimi-k3 ⊃ kimi 都被裸 k3 的别名展开覆盖),最长名字胜出
211+
assert.equal(r.name, 'KIMI-K3');
212+
assert.equal(r.mode, 'override');
213+
});
214+
215+
it('match: 裸 k3 只命中 kimi 家族,不误中 opus / sonnet', () => {
216+
const dir = join(mkTmp(), MODEL_PROMPT_DIR);
217+
writeModelPrompt(dir, 'opus', 'override', 'x');
218+
writeModelPrompt(dir, 'sonnet', 'override', 'y');
219+
assert.equal(matchModelPrompt('k3', [{ dir, scope: 'global' }]), null);
220+
});
221+
222+
it('match: 完整拼写 kimi-k3 行为不变(别名不破坏正向匹配)', () => {
223+
const dir = join(mkTmp(), MODEL_PROMPT_DIR);
224+
writeModelPrompt(dir, 'kimi', 'override', 'x');
225+
const r = matchModelPrompt('kimi-k3', [{ dir, scope: 'global' }]);
226+
assert.equal(r.name, 'KIMI');
227+
});
204228
});

0 commit comments

Comments
 (0)