Files
learn-languages/src/lib/bigmodel/dictionary/orchestrator.ts
goddonebianu 3652e350e6 fix(dictionary): 修复 AI 编排系统的错误处理和超时控制
- 修复 orchestrator 中 throw 字符串的问题,改为 throw LookUpError
- 为 zhipu.ts 添加 30 秒超时控制,防止 LLM 调用卡死
- stage1 添加 isEmpty 和 isNaturalLanguage 字段验证
- stage2 改为降级处理而非直接失败,提升用户体验
- types.ts 添加 canMap 字段
- AGENTS.md 添加禁止擅自运行 pnpm dev 的说明
2026-03-09 17:19:12 +08:00

88 lines
3.2 KiB
TypeScript

import { ServiceOutputLookUp } from "@/modules/dictionary/dictionary-service-dto";
import { analyzeInput } from "./stage1-inputAnalysis";
import { determineSemanticMapping } from "./stage2-semanticMapping";
import { generateStandardForm } from "./stage3-standardForm";
import { generateEntries } from "./stage4-entriesGeneration";
import { LookUpError } from "@/lib/errors";
import { createLogger } from "@/lib/logger";
const log = createLogger("dictionary-orchestrator");
export async function executeDictionaryLookup(
text: string,
queryLang: string,
definitionLang: string
): Promise<ServiceOutputLookUp> {
try {
log.debug("[Stage 1] Starting input analysis");
const analysis = await analyzeInput(text);
if (!analysis.isValid) {
log.debug("[Stage 1] Invalid input", { reason: analysis.reason });
throw new LookUpError(analysis.reason || "无效输入");
}
if (analysis.isEmpty) {
log.debug("[Stage 1] Empty input");
throw new LookUpError("输入为空");
}
log.debug("[Stage 1] Analysis complete", { analysis });
log.debug("[Stage 2] Starting semantic mapping");
const semanticMapping = await determineSemanticMapping(
text,
queryLang,
analysis.inputLanguage ?? text
);
log.debug("[Stage 2] Semantic mapping complete", { semanticMapping });
log.debug("[Stage 3] Generating standard form");
// 如果进行了语义映射,标准形式要基于映射后的结果
// 同时传递原始输入作为语义参考
const shouldUseMapping = semanticMapping.shouldMap && semanticMapping.mappedQuery;
const inputForStandardForm = shouldUseMapping ? semanticMapping.mappedQuery! : text;
const standardFormResult = await generateStandardForm(
inputForStandardForm,
queryLang,
shouldUseMapping ? text : undefined // 如果进行了映射,传递原始输入作为语义参考
);
if (!standardFormResult.standardForm) {
log.error("[Stage 3] Standard form is empty");
throw new LookUpError("无法生成标准形式");
}
log.debug("[Stage 3] Standard form complete", { standardFormResult });
log.debug("[Stage 4] Generating entries");
const entriesResult = await generateEntries(
standardFormResult.standardForm,
queryLang,
definitionLang,
analysis.inputType === "unknown"
? (standardFormResult.standardForm.includes(" ") ? "phrase" : "word")
: analysis.inputType
);
log.debug("[Stage 4] Entries complete", { entriesResult });
const finalResult: ServiceOutputLookUp = {
standardForm: standardFormResult.standardForm,
entries: entriesResult.entries,
};
log.info("Dictionary lookup completed successfully");
return finalResult;
} catch (error) {
log.error("Dictionary lookup failed", { error });
const errorMessage = error instanceof Error ? error.message : "未知错误";
throw new LookUpError(errorMessage);
}
}