Fix repeated local replies
This commit is contained in:
@@ -361,7 +361,6 @@ export class GuildVoiceSession extends EventEmitter {
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.options.logger.info("Transcript committed", this.guildId, hydratedUtterance.speakerName, hydratedUtterance.text);
|
this.options.logger.info("Transcript committed", this.guildId, hydratedUtterance.speakerName, hydratedUtterance.text);
|
||||||
this.memory.addUserTurn(hydratedUtterance);
|
|
||||||
|
|
||||||
if (this.options.config.DEBUG_TEXT_EVENTS) {
|
if (this.options.config.DEBUG_TEXT_EVENTS) {
|
||||||
await this.announce(`🗣️ ${hydratedUtterance.speakerName}: ${hydratedUtterance.text}`);
|
await this.announce(`🗣️ ${hydratedUtterance.speakerName}: ${hydratedUtterance.text}`);
|
||||||
@@ -375,6 +374,7 @@ export class GuildVoiceSession extends EventEmitter {
|
|||||||
reply = "지금은 답변 생성에 실패했습니다. 잠시 후 다시 말씀해 주세요.";
|
reply = "지금은 답변 생성에 실패했습니다. 잠시 후 다시 말씀해 주세요.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.memory.addUserTurn(hydratedUtterance);
|
||||||
this.memory.addAssistantTurn(reply);
|
this.memory.addAssistantTurn(reply);
|
||||||
if (this.options.config.DEBUG_TEXT_EVENTS) {
|
if (this.options.config.DEBUG_TEXT_EVENTS) {
|
||||||
await this.announce(`🤖 ${reply}`);
|
await this.announce(`🤖 ${reply}`);
|
||||||
|
|||||||
@@ -362,7 +362,6 @@ export class LocalVoiceSession {
|
|||||||
}
|
}
|
||||||
|
|
||||||
utterance.text = transcript.trim();
|
utterance.text = transcript.trim();
|
||||||
this.memory.addUserTurn(utterance);
|
|
||||||
this.options.logger.info("Local transcript", utterance.text);
|
this.options.logger.info("Local transcript", utterance.text);
|
||||||
if (this.options.config.DEBUG_TEXT_EVENTS) {
|
if (this.options.config.DEBUG_TEXT_EVENTS) {
|
||||||
console.log(`\n[you] ${utterance.text}`);
|
console.log(`\n[you] ${utterance.text}`);
|
||||||
@@ -376,6 +375,7 @@ export class LocalVoiceSession {
|
|||||||
reply = "지금은 답변 생성에 실패했습니다. 잠시 후 다시 말씀해 주세요.";
|
reply = "지금은 답변 생성에 실패했습니다. 잠시 후 다시 말씀해 주세요.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.memory.addUserTurn(utterance);
|
||||||
this.memory.addAssistantTurn(reply);
|
this.memory.addAssistantTurn(reply);
|
||||||
this.options.logger.info("Local reply", reply);
|
this.options.logger.info("Local reply", reply);
|
||||||
if (this.options.config.DEBUG_TEXT_EVENTS) {
|
if (this.options.config.DEBUG_TEXT_EVENTS) {
|
||||||
|
|||||||
@@ -12,6 +12,14 @@ export interface UserUtterance {
|
|||||||
text: string;
|
text: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function renderSpeakerLabel(speakerName?: string): string {
|
||||||
|
const normalized = speakerName?.trim();
|
||||||
|
if (!normalized || normalized === "unknown" || normalized === "local-user") {
|
||||||
|
return "사용자";
|
||||||
|
}
|
||||||
|
return `사용자(${normalized})`;
|
||||||
|
}
|
||||||
|
|
||||||
export class ConversationMemory {
|
export class ConversationMemory {
|
||||||
private readonly turns: ConversationTurn[] = [];
|
private readonly turns: ConversationTurn[] = [];
|
||||||
|
|
||||||
@@ -50,9 +58,9 @@ export class ConversationMemory {
|
|||||||
.slice(-this.maxTurns)
|
.slice(-this.maxTurns)
|
||||||
.map((turn) => {
|
.map((turn) => {
|
||||||
if (turn.role === "assistant") {
|
if (turn.role === "assistant") {
|
||||||
return `[assistant]\n${turn.text}`;
|
return `비서: ${turn.text}`;
|
||||||
}
|
}
|
||||||
return `[user speaker_id=${turn.speakerId ?? "unknown"} speaker_name=${turn.speakerName ?? "unknown"}]\n${turn.text}`;
|
return `${renderSpeakerLabel(turn.speakerName)}: ${turn.text}`;
|
||||||
})
|
})
|
||||||
.join("\n\n");
|
.join("\n\n");
|
||||||
|
|
||||||
@@ -62,9 +70,10 @@ export class ConversationMemory {
|
|||||||
"최근 대화:",
|
"최근 대화:",
|
||||||
historyBlock,
|
historyBlock,
|
||||||
"",
|
"",
|
||||||
"이번 발화:",
|
"지금 방금 들은 말:",
|
||||||
`[user speaker_id=${currentUtterance.speakerId} speaker_name=${currentUtterance.speakerName}]`,
|
`${renderSpeakerLabel(currentUtterance.speakerName)}: ${currentUtterance.text}`,
|
||||||
currentUtterance.text,
|
"",
|
||||||
|
"위 마지막 말에 자연스럽게 바로 답변해라. speaker_id나 speaker_name 같은 메타 정보를 자기소개처럼 반복하지 마라.",
|
||||||
].join("\n");
|
].join("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ const ASSISTANT_INSTRUCTIONS = [
|
|||||||
"기본은 한 문장, 길어도 두 문장을 넘기지 않는다.",
|
"기본은 한 문장, 길어도 두 문장을 넘기지 않는다.",
|
||||||
"말투는 자연스러운 한국어로 유지한다.",
|
"말투는 자연스러운 한국어로 유지한다.",
|
||||||
"speaker_id와 speaker_name은 화자 구분용이므로 필요할 때만 자연스럽게 반영한다.",
|
"speaker_id와 speaker_name은 화자 구분용이므로 필요할 때만 자연스럽게 반영한다.",
|
||||||
|
"자기소개를 반복하지 말고, 사용자가 정체를 물었을 때만 짧게 소개한다.",
|
||||||
|
"\"저는 화자입니다\" 같은 어색한 메타 응답은 하지 않는다.",
|
||||||
"잘 못 들었거나 의미가 불명확하면 짧게 다시 물어본다.",
|
"잘 못 들었거나 의미가 불명확하면 짧게 다시 물어본다.",
|
||||||
"목록, 마크다운, 코드블록은 쓰지 않는다.",
|
"목록, 마크다운, 코드블록은 쓰지 않는다.",
|
||||||
"생각 과정을 드러내지 말고 최종 답변만 말한다.",
|
"생각 과정을 드러내지 말고 최종 답변만 말한다.",
|
||||||
|
|||||||
Reference in New Issue
Block a user