Skip to content

Commit

Permalink
fix bug
Browse files Browse the repository at this point in the history
  • Loading branch information
nohairblingbling committed Sep 19, 2024
1 parent e726d90 commit f78f0cc
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 23 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Interview Assistant 相比其他面试辅助工具有以下优势:

本项目基于 Electron 和 React 开发。请按以下步骤操作:

1. 克隆仓库: `git clone [仓库地址]`
1. 克隆仓库: `git clone https://github.com/nohairblingbling/Interview-Assistant`
2. 安装依赖: `npm install`
3. 安装 Electron: `npm install electron`
4. 启动开发服务器: `npm start`
Expand Down
16 changes: 13 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -348,16 +348,23 @@ ipcMain.handle("test-api-config", async (event, config) => {
}
});

ipcMain.handle("callOpenAI", async (event, { config, messages }) => {
ipcMain.handle("callOpenAI", async (event, { config, messages, signal }) => {
try {
const openai = new OpenAI({
apiKey: config.openai_key,
baseURL: normalizeApiBaseUrl(config.api_base),
});

const abortController = new AbortController();
if (signal) {
signal.addEventListener('abort', () => abortController.abort());
}

const response = await openai.chat.completions.create({
model: config.gpt_model || "gpt-3.5-turbo",
messages: messages,
});
}, { signal: abortController.signal });

if (
!response.choices ||
!response.choices[0] ||
Expand All @@ -367,6 +374,9 @@ ipcMain.handle("callOpenAI", async (event, { config, messages }) => {
}
return { content: response.choices[0].message.content };
} catch (error) {
if (error.name === "AbortError") {
return { error: "AbortError" };
}
return { error: error.message || "Unknown error occurred" };
}
});
Expand Down Expand Up @@ -413,7 +423,7 @@ ipcMain.handle("start-deepgram", async (event, config) => {
language: config.primaryLanguage || "en",
encoding: "linear16",
sample_rate: 16000,
endpointing: 1000,
endpointing: 1500,
});

deepgramConnection.addListener(LiveTranscriptionEvents.Open, () => {
Expand Down
40 changes: 24 additions & 16 deletions src/pages/InterviewPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { useInterview } from "../contexts/InterviewContext";
import ReactMarkdown from 'react-markdown';

const InterviewPage: React.FC = () => {
const { knowledgeBase, conversations, addConversation } = useKnowledgeBase();
const { knowledgeBase, conversations, addConversation, clearConversations } = useKnowledgeBase();
const { error, setError, clearError } = useError();
const {
currentText,
Expand Down Expand Up @@ -83,7 +83,7 @@ const InterviewPage: React.FC = () => {
const messages = [
{
role: "system",
content: "You are an interview preparation assistant now. Use the following previous conversation and file to assist in answering questions in the first person:",
content: "",
},
...knowledgeBase.map((item: string) => ({
role: "user",
Expand All @@ -109,35 +109,35 @@ const InterviewPage: React.FC = () => {
throw new Error("Unexpected API response structure");
}

const formattedResponse = `\n\nA: ${response.content.trim()}`;
setAiResult((prev: string) => prev + formattedResponse);
simulateTyping(formattedResponse);
addConversation({ role: "assistant", content: response.content });
const formattedResponse = response.content.trim();
setAiResult(prev => prev + (prev ? '\n\n' : '') + formattedResponse);
addConversation({ role: "assistant", content: formattedResponse });
setLastProcessedIndex(currentText.length);
simulateTyping(formattedResponse, true);
} catch (err) {
console.error("Detailed error in handleAskGPT:", err);
setError("Failed to get GPT response. Please try again.");
} finally {
setIsLoading(false);
}
}, [currentText, lastProcessedIndex, knowledgeBase, conversations, addConversation, setError, setAiResult, setLastProcessedIndex]);

const simulateTyping = (text: string) => {
const simulateTyping = (text: string, isNewMessage: boolean = false) => {
let i = 0;
if (isNewMessage) {
setDisplayedAiResult(prev => prev + (prev ? '\n\n' : ''));
}
const interval = setInterval(() => {
if (i < text.length) {
setDisplayedAiResult((prev: string) => prev + (text[i] || ''));
if (i <= text.length) {
setDisplayedAiResult(prev => prev + (i === 0 ? text[i] || '' : text[i - 1] || ''));
i++;
if (aiResponseRef.current) {
aiResponseRef.current.scrollTop = aiResponseRef.current.scrollHeight;
}
} else {
clearInterval(interval);

setTimeout(() => {
setDisplayedAiResult((prev: string) => prev + '\n\n');
}, 500);
}
}, 35);
}, 10);
};

const handleAskGPTStable = useCallback(async (newContent: string) => {
Expand Down Expand Up @@ -272,8 +272,11 @@ const InterviewPage: React.FC = () => {
};

useEffect(() => {
loadConfig();
return () => {
setLastProcessedIndex(0);
if (isRecording) {
stopRecording();
}
};
}, []);

Expand Down Expand Up @@ -321,7 +324,11 @@ const InterviewPage: React.FC = () => {
className="flex-1 overflow-auto bg-base-100 p-2 rounded mb-1 min-h-[80px]"
>
<h2 className="text-lg font-bold mb-1">AI Response:</h2>
<ReactMarkdown>{displayedAiResult || ''}</ReactMarkdown>
<ReactMarkdown className="whitespace-pre-wrap markdown-body" components={{
p: ({node, ...props}) => <p style={{whiteSpace: 'pre-wrap'}} {...props} />
}}>
{displayedAiResult}
</ReactMarkdown>
</div>
<div className="flex justify-between mt-1">
<button
Expand All @@ -334,6 +341,7 @@ const InterviewPage: React.FC = () => {
<button onClick={() => {
setAiResult("");
setDisplayedAiResult("");
clearConversations();
}} className="btn btn-ghost">
Clear AI Result
</button>
Expand Down
4 changes: 2 additions & 2 deletions src/pages/KnowledgeBase.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const KnowledgeBase: React.FC = () => {
setDisplayedAiResult((prev) => prev + '\n\n');
}, 500);
}
}, 35);
}, 10);
};

const handleChatSubmit = async (e: React.FormEvent) => {
Expand Down Expand Up @@ -123,7 +123,7 @@ const KnowledgeBase: React.FC = () => {
messages: messages
});

if (response.error) {
if ('error' in response) {
throw new Error(response.error);
}

Expand Down
6 changes: 5 additions & 1 deletion src/renderer.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ export interface ElectronAPI {
on(channel: string, listener: (event: any, ...args: any[]) => void): void;
removeListener(channel: string, listener: (...args: any[]) => void): void;
};
callOpenAI: (params: { config: any, messages: any[] }) => Promise<{ content?: string, error?: string }>;
callOpenAI: (params: {
config: any;
messages: any[];
signal?: AbortSignal;
}) => Promise<{ content: string } | { error: string }>;
transcribeAudio: (audioBuffer: ArrayBuffer, config: any) => Promise<TranscriptionResult>;
}

Expand Down

0 comments on commit f78f0cc

Please sign in to comment.