build_pack.py 產生對白索引(放在使用者資料目錄);render_skill.py 把人格卡渲染成 角色 skill 並檢查精選對白逐字來自索引;插件改成執行期從資料目錄讀索引。 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
352ce7dcad
commit
697ed6a0b9
@@ -0,0 +1,46 @@
|
||||
import { MAX_LINE } from './examples'
|
||||
import type { IndexEntry } from './retrieval'
|
||||
import { isFunctionTag } from './tags'
|
||||
|
||||
const DEFAULT_DIR = '.claude/anime-companion'
|
||||
|
||||
// 對白索引由建置流水線產生,放在使用者資料目錄(不在插件裡、不入版本控制)。
|
||||
// dataDir 留空時用 ~/.claude/anime-companion;找不到家目錄就回傳 null。
|
||||
export function indexPath(dataDir: string, home: string | undefined, code: string): string | null {
|
||||
const base = dataDir.trim() !== '' ? dataDir.trim() : home ? `${home}/${DEFAULT_DIR}` : null
|
||||
return base === null ? null : `${base.replace(/\/+$/, '')}/${code}/index.jsonl`
|
||||
}
|
||||
|
||||
// 一行一筆;格式不對的行略過,不讓壞掉的資料擋住載入。
|
||||
export function parseIndex(text: string): IndexEntry[] {
|
||||
const out: IndexEntry[] = []
|
||||
for (const line of text.split('\n')) {
|
||||
if (line.trim() === '') continue
|
||||
try {
|
||||
const e = JSON.parse(line) as Record<string, unknown>
|
||||
if (
|
||||
typeof e.id === 'string' &&
|
||||
isFunctionTag(e.function) &&
|
||||
typeof e.emotion === 'string' &&
|
||||
(e.mode === null || typeof e.mode === 'string') &&
|
||||
typeof e.text === 'string' &&
|
||||
e.text.length > 0 &&
|
||||
e.text.length <= MAX_LINE
|
||||
) {
|
||||
out.push({ id: e.id, function: e.function, emotion: e.emotion, mode: e.mode, text: e.text })
|
||||
}
|
||||
} catch {
|
||||
// 略過壞行
|
||||
}
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
export async function loadIndex(read: (path: string) => Promise<string>, path: string | null): Promise<IndexEntry[]> {
|
||||
if (path === null) return []
|
||||
try {
|
||||
return parseIndex(await read(path))
|
||||
} catch {
|
||||
return []
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user