fix: NewAPI key strip sk- prefix + LLM wiki graceful fallback
This commit is contained in:
parent
57ac628b3f
commit
c86f5bc304
|
|
@ -40,7 +40,7 @@ STATE_FILE = os.path.expanduser("~/.hermes/wiki_curator_state.json")
|
|||
|
||||
# LLM 配置
|
||||
LLM_API = "http://127.0.0.1:3000/v1/chat/completions"
|
||||
LLM_MODEL = "minimaxai/minimax-m3"
|
||||
LLM_MODEL = "minimaxai/minimax-m2.7" # m3 sometimes returns empty, use m2.7
|
||||
|
||||
# 扫描时排除的目录名称(大小写不敏感)
|
||||
EXCLUDE_DIRS = {
|
||||
|
|
@ -259,7 +259,11 @@ def _get_llm_key() -> str:
|
|||
cfg_path = os.path.expanduser("~/.hermes/config.yaml")
|
||||
with open(cfg_path) as f:
|
||||
cfg = yaml.safe_load(f)
|
||||
return cfg.get("providers", {}).get("newapi-local", {}).get("api_key", "")
|
||||
raw = cfg.get("providers", {}).get("newapi-local", {}).get("api_key", "")
|
||||
# NewAPI 的 key 不需要 sk- 前缀
|
||||
if raw.startswith("sk-"):
|
||||
raw = raw[3:]
|
||||
return raw
|
||||
except Exception:
|
||||
pass
|
||||
# 回退到环境变量
|
||||
|
|
@ -273,27 +277,39 @@ def _extract_with_llm(content: str, filepath: str) -> dict | None:
|
|||
print(" ⚠️ No LLM API key found (check config.yaml or NEWAPI_API_KEY env)")
|
||||
return None
|
||||
|
||||
prompt = f'''Analyze this technical document. Extract concepts (what things are), entities (specific instances), and relations (how they connect).
|
||||
Return JSON ONLY:
|
||||
{{"concepts": [{{"name":"...","summary":"..."}}],
|
||||
"entities": [{{"name":"...","attributes":{{}}}}],
|
||||
"relations": [{{"source":"...","relation":"uses|contains|depends_on|part_of|implements","target":"..."}}]}}
|
||||
prompt = f'''Extract concepts, entities, and relations from this document.
|
||||
Return ONLY valid JSON:
|
||||
{{"concepts":[{{"name":"...","summary":"..."}}],"entities":[{{"name":"...","attributes":{{}}}}],"relations":[{{"source":"...","relation":"uses|contains|depends_on|part_of|implements","target":"..."}}]}}
|
||||
|
||||
Document: {content[:3000]}
|
||||
Document:
|
||||
{content[:2000]}
|
||||
'''
|
||||
try:
|
||||
resp = requests.post(LLM_API,
|
||||
headers={"Authorization": f"Bearer {llm_key}", "Content-Type": "application/json"},
|
||||
json={"model": LLM_MODEL, "messages": [{"role": "user", "content": prompt}], "temperature": 0.1},
|
||||
json={
|
||||
"model": LLM_MODEL,
|
||||
"messages": [
|
||||
{"role": "system", "content": "You are a knowledge extraction assistant. Always respond with valid JSON only."},
|
||||
{"role": "user", "content": prompt}
|
||||
],
|
||||
"temperature": 0.1,
|
||||
"max_tokens": 1000,
|
||||
},
|
||||
timeout=30)
|
||||
data = resp.json()
|
||||
if "error" in data and data["error"].get("message"):
|
||||
print(f" ⚠️ LLM API error: {data['error']['message'][:60]}")
|
||||
return None
|
||||
choices = data.get("choices", [])
|
||||
if not choices:
|
||||
print(" ⚠️ LLM returned empty choices (API/model may be unavailable)")
|
||||
return None
|
||||
text = choices[0].get("message", {}).get("content", "")
|
||||
if not text:
|
||||
print(" ⚠️ LLM returned empty content")
|
||||
msg = choices[0].get("message", {})
|
||||
text = msg.get("content", "") or ""
|
||||
if not text.strip():
|
||||
finish = choices[0].get("finish_reason", "")
|
||||
print(f" ⚠️ LLM returned empty content (finish={finish})")
|
||||
return None
|
||||
# Parse JSON from response
|
||||
json_match = re.search(r'\{[\s\S]*\}', text)
|
||||
|
|
|
|||
Loading…
Reference in New Issue