Ver Fonte

feature: chatGPT

ZhangYuYu há 3 anos atrás
pai
commit
6ba94369cc

+ 11 - 10
package.json

@@ -3,8 +3,10 @@
   "version": "0.1.0",
   "private": true,
   "dependencies": {
-    "@ant-design/pro-components": "^2.3.20",
     "@ant-design/icons": "^4.7.0",
+    "@ant-design/pro-components": "^2.3.20",
+    "@codingame/monaco-jsonrpc": "0.3.1",
+    "@codingame/monaco-languageclient": "0.17.4",
     "@dtinsight/molecule": "^1.2.0",
     "@gitbeaker/browser": "^35.7.0",
     "@testing-library/jest-dom": "^5.11.4",
@@ -15,29 +17,28 @@
     "@types/react": "^18.0.15",
     "@types/react-dom": "^18.0.6",
     "@types/redux-logger": "^3.0.9",
-    "@codingame/monaco-jsonrpc": "0.3.1",
-    "@codingame/monaco-languageclient": "0.17.4",
-    "reconnecting-websocket": "4.4.0",
-    "monaco-editor": "0.30.1",
     "antd": "^4.22.3",
     "classnames": "^2.3.1",
+    "monaco-editor": "0.30.1",
+    "normalize-url": "^7.0.3",
+    "openai": "^3.2.1",
     "react": "^18.2.0",
     "react-dom": "^18.2.0",
+    "react-markdown": "^8.0.3",
     "react-redux": "^8.0.2",
     "react-router-dom": "6",
     "react-scripts": "4.0.3",
     "react-scrollbars-custom": "^4.0.25",
+    "reconnecting-websocket": "4.4.0",
     "redux": "^4.2.0",
     "redux-logger": "^3.0.6",
+    "remark-gfm": "^3.0.1",
     "styled-components": "^5.3.3",
     "typescript": "^4.1.2",
     "umi": "^3.5.20",
     "web-vitals": "^1.0.1",
     "whatwg-fetch": "^3.6.2",
-    "xterm-for-react": "^1.0.4",
-    "normalize-url": "^7.0.3",
-    "react-markdown": "^8.0.3",
-    "remark-gfm": "^3.0.1"
+    "xterm-for-react": "^1.0.4"
   },
   "scripts": {
     "start": "cross-env PORT=3000 umi dev",
@@ -63,13 +64,13 @@
     ]
   },
   "devDependencies": {
-    "cross-env": "^7.0.3",
     "@types/lodash": "^4.14.176",
     "@types/styled-components": "^5.1.15",
     "@umijs/fabric": "2.7.0",
     "@umijs/plugin-esbuild": "^1.4.1",
     "@umijs/plugin-sass": "^1.1.1",
     "@umijs/preset-react": "1.x",
+    "cross-env": "^7.0.3",
     "monaco-editor-webpack-plugin": "^6.0.0",
     "react-app-rewired": "^2.1.8",
     "umi-plugin-tailwindcss": "^3.2.1"

+ 24 - 0
src/extensions/chatGPT/base.tsx

@@ -0,0 +1,24 @@
+import { IActivityBarItem, ISidebarPane, } from '@dtinsight/molecule/esm/model';
+import {ChatGPT}  from '@/pages/chatGPT'
+
+export const CHAT_GPT_ID = 'chatGPT';
+
+export const chatGPTSidebar: ISidebarPane = {
+    id: CHAT_GPT_ID,
+    title: 'chatGPTPane',
+    render: () => {
+        return (
+            <div>
+                <ChatGPT/>
+            </div>
+        );
+    },
+};
+
+export const chatGPTActivityBar: IActivityBarItem = {
+    id: CHAT_GPT_ID,
+    sortIndex: 1, // sorting the dataSource to the first position
+    name: 'chatGPT',
+    title: 'chatGPT',
+    icon: 'symbol-snippet',
+};

+ 31 - 0
src/extensions/chatGPT/index.ts

@@ -0,0 +1,31 @@
+import { IExtension } from '@dtinsight/molecule/esm/model/extension';
+import { IExtensionService } from '@dtinsight/molecule/esm/services';
+import molecule from "@dtinsight/molecule";
+import {chatGPTSidebar, chatGPTActivityBar} from "./base";
+
+export class ChatGPTExtension implements IExtension {
+    id: string = '';
+    name: string = '';
+
+    constructor(
+        id: string = 'chatGPTExtension', 
+        name: string = 'chatGPTExtension'
+    ) {
+        this.id = id;
+        this.name = name;
+    }
+
+    activate(extensionCtx: IExtensionService): void {
+        this.initUI();
+    }
+
+    initUI() {
+        molecule.sidebar.add(chatGPTSidebar);
+        molecule.activityBar.add(chatGPTActivityBar);
+    }
+
+    dispose(extensionCtx: IExtensionService): void {
+        molecule.sidebar.remove(chatGPTSidebar.id);
+        molecule.activityBar.remove(chatGPTActivityBar.id);
+    }
+}

+ 3 - 0
src/extensions/index.ts

@@ -7,6 +7,7 @@ import { MenuBarExtension } from './menubar';
 import { ActionExtension } from './action';
 import { GoToGitlabExtension } from './gitlab';
 import InitializeExtension from "./init";
+import {ChatGPTExtension} from './chatGPT'
 
 const extensions: IExtension[] = [
     new FirstExtension(),
@@ -17,6 +18,8 @@ const extensions: IExtension[] = [
     OneDarkPro,
     QuietLight,
     new InitializeExtension(),
+    new ChatGPTExtension(),
+
 ];
 
 export default extensions;

+ 1 - 1
src/extensions/init.tsx

@@ -47,7 +47,7 @@ export default class InitializeExtension implements IExtension {
 
     activate(): void {
         const { CONTEXT_MENU_SEARCH } = molecule.builtin.getConstants();
-        molecule.activityBar.remove([CONTEXT_MENU_SEARCH!]);
+        // molecule.activityBar.remove([CONTEXT_MENU_SEARCH!]);
         initializeColorTheme();
         initMenuBar();
         initLogin();

+ 156 - 0
src/pages/chatGPT/index.tsx

@@ -0,0 +1,156 @@
+import { useRef, useState } from 'react'
+// import './App.less'
+import { Button ,Spin,message} from 'antd';
+import { AudioOutlined ,RedditOutlined} from '@ant-design/icons';
+// import 'antd/dist/reset.css';
+import  { Configuration, OpenAIApi } from "openai";
+
+interface answerListType{
+	type: string,
+	content?: string,
+	isFinshed: number,
+}
+const openai_api_key = "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";
+
+export async function davinciCompletion(prompt:String) {
+	const requestOptions = {
+	  method: 'POST',
+	  headers: {
+		'Content-Type': 'application/json',
+		'Authorization': 'Bearer ' + String(openai_api_key)
+	  },
+	  body: JSON.stringify({
+		"model": "gpt-3.5-turbo",
+		// "prompt": prompt,
+		// "temperature": 0.7,
+		// "max_tokens": 256,
+		// "top_p": 1,
+		// "frequency_penalty": 0,
+		// "presence_penalty": 0
+		"messages": 
+			[
+				{"role": "user", 
+				"content": prompt
+				}
+			]
+	  })
+	};
+	const response = await fetch('https://api.openai.com/v1/chat/completions', requestOptions);
+	const data = await response.json();
+	// const text = data.choices[0].text;
+	console.log(data);
+	const text = data.choices[0].message.content;
+	return text;
+}
+export function ChatGPT() {
+  	const [inputValue, setInputValue] = useState<string>("")
+	const [answerList, setAnswerList] = useState<answerListType[]>([])
+	const preItem = useRef<HTMLDivElement>(null)
+
+	const [messageApi,contextHolder] = message.useMessage();
+	const configuration = new Configuration({
+		apiKey: "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",
+		// apiKey:"FCF62D974F67203BD8"
+	});
+	const openai = new OpenAIApi(configuration);
+
+
+	const quize = ()=>{
+		console.log("提问",inputValue)
+		setAnswerList([...answerList,{
+			type:'question',
+			content:inputValue,
+			isFinshed: 1,
+		},{
+			type: 'answer',
+			content: '正在思考',
+			isFinshed: 0,
+		}])
+		console.log("resf",preItem)
+		preItem?.current?.scrollIntoView()
+		setInputValue("")
+		getMessage(inputValue)
+	}
+
+	const getMessage = async (questionText:string)=>{
+
+		// openai.createCompletion({
+		// 	model: "text-davinci-003",
+		// 	prompt: questionText,
+		// 	max_tokens: 600,
+		// 	temperature: 1,
+		davinciCompletion(questionText
+			).then((response )=>{
+			// 打印 API 返回的结果
+			console.log("我的回答是");
+			console.log(response,answerList);
+			setAnswerList(answerList=>answerList.map((item,index)=>{
+					if(index<answerList.length-1){
+						return item
+					}else{
+						return {
+							type: 'answer',
+							content: response.replace(/\n{2}/, " "),
+							isFinshed: 1,
+						}
+					}
+				}))
+		}).catch((e)=>{
+			messageApi.open({
+				type: 'error',
+				content: '你的 Key 失效了!',
+			  });
+		})
+	}
+
+  return (
+    <div className="ChatGPT">
+		{contextHolder}
+		<div className='input_box'>
+			<input type="text" className='input' value={inputValue} onChange={e=>setInputValue(e.target.value)}></input>
+			<Button 
+				type="primary" 
+				size='large' 
+				className='btn'
+				onClick={quize}
+			>提问</Button>
+		</div>
+		<div className='answer_box'>
+			<div className='answer'>{
+				answerList.map((item,index)=>{
+					if(item.type==='question'){
+						// 问题
+						return (
+							<div className='item' key={index}>
+								<div><AudioOutlined style={{fontSize:'24px',color:'#646cffaa'}}/> </div>
+								<span className='span'>{item.content}</span>
+							</div>
+						)
+					}else{
+						// 回答
+						if(item.isFinshed === 0){
+							// 加载中
+							return (
+								<div className='item' ref={preItem} key={index}>
+									<div><RedditOutlined style={{fontSize:'24px',color:'#42b883aa'}}/> </div>
+									<span className='span'><Spin /></span>
+								</div>
+							)
+						}else{
+							// 回复答案
+							return (
+								<div className='item' key={index}>
+									<div><RedditOutlined style={{fontSize:'24px',color:'#42b883aa'}}/> </div> 
+									<span className='span'><pre> {item.content} </pre></span>
+								</div>
+							)
+						}
+					}
+				})
+			}</div>
+		</div>
+    </div>
+  )
+}
+
+// export default ChatGPT

+ 20 - 0
yarn.lock

@@ -4991,6 +4991,13 @@ axe-core@^4.4.3:
   resolved "https://registry.npmmirror.com/axe-core/-/axe-core-4.4.3.tgz#11c74d23d5013c0fa5d183796729bc3482bd2f6f"
   integrity sha512-32+ub6kkdhhWick/UjvEwRchgoetXqTK14INLqbGm5U2TzBkBNF3nQtLYm8ovxSkQWArjEQvftCKryjZaATu3w==
 
+axios@^0.26.0:
+  version "0.26.1"
+  resolved "https://registry.npmmirror.com/axios/-/axios-0.26.1.tgz#1ede41c51fcf51bbbd6fd43669caaa4f0495aaa9"
+  integrity sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==
+  dependencies:
+    follow-redirects "^1.14.8"
+
 axobject-query@^2.2.0:
   version "2.2.0"
   resolved "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be"
@@ -8696,6 +8703,11 @@ follow-redirects@^1.0.0:
   resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.5.tgz#f09a5848981d3c772b5392309778523f8d85c381"
   integrity sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA==
 
+follow-redirects@^1.14.8:
+  version "1.15.2"
+  resolved "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13"
+  integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==
+
 for-in@^1.0.2:
   version "1.0.2"
   resolved "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80"
@@ -12783,6 +12795,14 @@ open@^7.0.2:
     is-docker "^2.0.0"
     is-wsl "^2.1.1"
 
+openai@^3.2.1:
+  version "3.2.1"
+  resolved "https://registry.npmmirror.com/openai/-/openai-3.2.1.tgz#1fa35bdf979cbde8453b43f2dd3a7d401ee40866"
+  integrity sha512-762C9BNlJPbjjlWZi4WYK9iM2tAVAv0uUp1UmI34vb0CN5T2mjB/qM6RYBmNKMh/dN9fC+bxqPwWJZUTWW052A==
+  dependencies:
+    axios "^0.26.0"
+    form-data "^4.0.0"
+
 opn@^5.5.0:
   version "5.5.0"
   resolved "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz#fc7164fab56d235904c51c3b27da6758ca3b9bfc"