This is an automated email from the ASF dual-hosted git repository.
shuai pushed a commit to branch ai-ui
in repository https://gitbox.apache.org/repos/asf/answer.git
The following commit(s) were added to refs/heads/ai-ui by this push:
new e8875706 fix: add licnese headers
e8875706 is described below
commit e8875706c9a5a0cd24ee072f3d853b35584e95d0
Author: shuai <[email protected]>
AuthorDate: Fri Jan 23 17:02:41 2026 +0800
fix: add licnese headers
---
ui/src/components/BubbleAi/index.tsx | 21 ++++++++++++-
ui/src/components/BubbleUser/index.scss | 19 ++++++++++++
ui/src/components/BubbleUser/index.tsx | 19 ++++++++++++
ui/src/components/Sender/index.scss | 19 ++++++++++++
ui/src/components/Sender/index.tsx | 29 ++++++++++++++----
.../AiAssistant/components/DetailModal/index.tsx | 19 ++++++++++++
ui/src/pages/Admin/AiAssistant/index.tsx | 19 ++++++++++++
ui/src/pages/Admin/AiSettings/index.tsx | 19 ++++++++++++
.../Apikeys/components/AddOrEditModal/index.tsx | 19 ++++++++++++
.../Apikeys/components/CreatedModal/index.tsx | 19 ++++++++++++
ui/src/pages/Admin/Apikeys/components/index.ts | 19 ++++++++++++
ui/src/pages/Admin/Apikeys/index.tsx | 19 ++++++++++++
ui/src/pages/Admin/Mcp/index.tsx | 19 ++++++++++++
ui/src/pages/Admin/QaSettings/index.tsx | 19 ++++++++++++
ui/src/pages/Admin/Security/index.tsx | 19 ++++++++++++
ui/src/pages/Admin/TagsSettings/index.tsx | 19 ++++++++++++
ui/src/pages/Admin/UsersSettings/index.tsx | 19 ++++++++++++
.../components/ConversationList/index.tsx | 18 ++++++++++++
ui/src/pages/AiAssistant/index.tsx | 21 ++++++++++++-
ui/src/services/admin/ai.ts | 19 ++++++++++++
ui/src/services/admin/mcp.ts | 19 ++++++++++++
ui/src/services/client/ai.ts | 19 ++++++++++++
ui/src/utils/requestAi.ts | 34 +++++++++++-----------
23 files changed, 441 insertions(+), 24 deletions(-)
diff --git a/ui/src/components/BubbleAi/index.tsx
b/ui/src/components/BubbleAi/index.tsx
index 52663686..453a61c5 100644
--- a/ui/src/components/BubbleAi/index.tsx
+++ b/ui/src/components/BubbleAi/index.tsx
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
import { FC, useEffect, useState, useRef } from 'react';
import { Button } from 'react-bootstrap';
import { useTranslation } from 'react-i18next';
@@ -46,7 +65,7 @@ const BubbleAi: FC<IProps> = ({
isTyping: false,
});
const fmtContainer = useRef<HTMLDivElement>(null);
- // 添加ref用于ScrollIntoView
+ // add ref for ScrollIntoView
const containerRef = useRef<HTMLDivElement>(null);
const handleCopy = () => {
diff --git a/ui/src/components/BubbleUser/index.scss
b/ui/src/components/BubbleUser/index.scss
index c944c413..6606ac5e 100644
--- a/ui/src/components/BubbleUser/index.scss
+++ b/ui/src/components/BubbleUser/index.scss
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
.bubble-user-wrap {
scroll-margin-top: 88px;
}
diff --git a/ui/src/components/BubbleUser/index.tsx
b/ui/src/components/BubbleUser/index.tsx
index dd68c084..b6c52a74 100644
--- a/ui/src/components/BubbleUser/index.tsx
+++ b/ui/src/components/BubbleUser/index.tsx
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
import { FC } from 'react';
import './index.scss';
diff --git a/ui/src/components/Sender/index.scss
b/ui/src/components/Sender/index.scss
index 64788993..32c12faa 100644
--- a/ui/src/components/Sender/index.scss
+++ b/ui/src/components/Sender/index.scss
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
.sender-wrap {
z-index: 10;
margin-top: auto;
diff --git a/ui/src/components/Sender/index.tsx
b/ui/src/components/Sender/index.tsx
index 9ce342a2..e79cf9b2 100644
--- a/ui/src/components/Sender/index.tsx
+++ b/ui/src/components/Sender/index.tsx
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
import { useEffect, useState, useRef, FC } from 'react';
import { Form, Button } from 'react-bootstrap';
import { useTranslation } from 'react-i18next';
@@ -43,17 +62,17 @@ const Sender: FC<IProps> = ({
textarea.style.height = '32px';
- const minHeight = 32; // 最小高度
- const maxHeight = 96; // 最大高度
+ const minHeight = 32; // minimum height
+ const maxHeight = 96; // maximum height
- // 计算需要的高度
+ // calculate the height needed
const { scrollHeight } = textarea;
const newHeight = Math.min(Math.max(scrollHeight, minHeight), maxHeight);
- // 设置新高度
+ // set the new height
textarea.style.height = `${newHeight}px`;
- // 控制滚动条显示
+ // control the scrollbar display
if (scrollHeight > maxHeight) {
textarea.style.overflowY = 'auto';
} else {
diff --git a/ui/src/pages/Admin/AiAssistant/components/DetailModal/index.tsx
b/ui/src/pages/Admin/AiAssistant/components/DetailModal/index.tsx
index c308c980..ec4bd7d7 100644
--- a/ui/src/pages/Admin/AiAssistant/components/DetailModal/index.tsx
+++ b/ui/src/pages/Admin/AiAssistant/components/DetailModal/index.tsx
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
import { FC, memo } from 'react';
import { Button, Modal } from 'react-bootstrap';
import { useTranslation } from 'react-i18next';
diff --git a/ui/src/pages/Admin/AiAssistant/index.tsx
b/ui/src/pages/Admin/AiAssistant/index.tsx
index f3aabb55..7fc3e9d9 100644
--- a/ui/src/pages/Admin/AiAssistant/index.tsx
+++ b/ui/src/pages/Admin/AiAssistant/index.tsx
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
import { useState } from 'react';
import { Table, Button } from 'react-bootstrap';
import { useTranslation } from 'react-i18next';
diff --git a/ui/src/pages/Admin/AiSettings/index.tsx
b/ui/src/pages/Admin/AiSettings/index.tsx
index 2bc30fef..2270aa5c 100644
--- a/ui/src/pages/Admin/AiSettings/index.tsx
+++ b/ui/src/pages/Admin/AiSettings/index.tsx
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
import { useEffect, useState, useRef } from 'react';
import { Form, InputGroup, Button } from 'react-bootstrap';
import { useTranslation } from 'react-i18next';
diff --git a/ui/src/pages/Admin/Apikeys/components/AddOrEditModal/index.tsx
b/ui/src/pages/Admin/Apikeys/components/AddOrEditModal/index.tsx
index 34a3192a..044a3017 100644
--- a/ui/src/pages/Admin/Apikeys/components/AddOrEditModal/index.tsx
+++ b/ui/src/pages/Admin/Apikeys/components/AddOrEditModal/index.tsx
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
import { useState } from 'react';
import { Modal, Form, Button } from 'react-bootstrap';
import { useTranslation } from 'react-i18next';
diff --git a/ui/src/pages/Admin/Apikeys/components/CreatedModal/index.tsx
b/ui/src/pages/Admin/Apikeys/components/CreatedModal/index.tsx
index 10d16744..83f782a1 100644
--- a/ui/src/pages/Admin/Apikeys/components/CreatedModal/index.tsx
+++ b/ui/src/pages/Admin/Apikeys/components/CreatedModal/index.tsx
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
import { Modal, Form, Button } from 'react-bootstrap';
import { useTranslation } from 'react-i18next';
diff --git a/ui/src/pages/Admin/Apikeys/components/index.ts
b/ui/src/pages/Admin/Apikeys/components/index.ts
index 539b7d79..46bda3f5 100644
--- a/ui/src/pages/Admin/Apikeys/components/index.ts
+++ b/ui/src/pages/Admin/Apikeys/components/index.ts
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
import Action from './Action';
import AddOrEditModal from './AddOrEditModal';
import CreatedModal from './CreatedModal';
diff --git a/ui/src/pages/Admin/Apikeys/index.tsx
b/ui/src/pages/Admin/Apikeys/index.tsx
index 30a994c7..a143cfa8 100644
--- a/ui/src/pages/Admin/Apikeys/index.tsx
+++ b/ui/src/pages/Admin/Apikeys/index.tsx
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
import { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Button, Table } from 'react-bootstrap';
diff --git a/ui/src/pages/Admin/Mcp/index.tsx b/ui/src/pages/Admin/Mcp/index.tsx
index 118612b7..39d5375d 100644
--- a/ui/src/pages/Admin/Mcp/index.tsx
+++ b/ui/src/pages/Admin/Mcp/index.tsx
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
import { FormEvent, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Form, Button } from 'react-bootstrap';
diff --git a/ui/src/pages/Admin/QaSettings/index.tsx
b/ui/src/pages/Admin/QaSettings/index.tsx
index 0c2636ea..17834ab0 100644
--- a/ui/src/pages/Admin/QaSettings/index.tsx
+++ b/ui/src/pages/Admin/QaSettings/index.tsx
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
import { useState, useEffect } from 'react';
import { useTranslation } from 'react-i18next';
diff --git a/ui/src/pages/Admin/Security/index.tsx
b/ui/src/pages/Admin/Security/index.tsx
index 07eaeb5b..35d7f2f6 100644
--- a/ui/src/pages/Admin/Security/index.tsx
+++ b/ui/src/pages/Admin/Security/index.tsx
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
import { useState, useEffect } from 'react';
import { useTranslation } from 'react-i18next';
diff --git a/ui/src/pages/Admin/TagsSettings/index.tsx
b/ui/src/pages/Admin/TagsSettings/index.tsx
index f2ab2f5b..b857d989 100644
--- a/ui/src/pages/Admin/TagsSettings/index.tsx
+++ b/ui/src/pages/Admin/TagsSettings/index.tsx
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
import { useState, useEffect } from 'react';
import { useTranslation } from 'react-i18next';
diff --git a/ui/src/pages/Admin/UsersSettings/index.tsx
b/ui/src/pages/Admin/UsersSettings/index.tsx
index 769c9f0a..55a3e784 100644
--- a/ui/src/pages/Admin/UsersSettings/index.tsx
+++ b/ui/src/pages/Admin/UsersSettings/index.tsx
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
import { useState, useEffect } from 'react';
import { useTranslation } from 'react-i18next';
diff --git a/ui/src/pages/AiAssistant/components/ConversationList/index.tsx
b/ui/src/pages/AiAssistant/components/ConversationList/index.tsx
index 29cf4cf3..4dbc6129 100644
--- a/ui/src/pages/AiAssistant/components/ConversationList/index.tsx
+++ b/ui/src/pages/AiAssistant/components/ConversationList/index.tsx
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
import { FC, memo } from 'react';
import { Card, ListGroup } from 'react-bootstrap';
import { Link } from 'react-router-dom';
diff --git a/ui/src/pages/AiAssistant/index.tsx
b/ui/src/pages/AiAssistant/index.tsx
index cad6d478..e2329f85 100644
--- a/ui/src/pages/AiAssistant/index.tsx
+++ b/ui/src/pages/AiAssistant/index.tsx
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
import { useEffect, useState } from 'react';
import { Row, Col, Spinner, Button } from 'react-bootstrap';
import { useTranslation } from 'react-i18next';
@@ -108,7 +127,7 @@ const Index = () => {
],
}));
- // 在页面高度稳定后再滚动到用户消息
+ // scroll to user message after the page height is stable
requestAnimationFrame(() => {
const userBubbles = document.querySelectorAll('.bubble-user-wrap');
const lastUserBubble = userBubbles[userBubbles.length - 1];
diff --git a/ui/src/services/admin/ai.ts b/ui/src/services/admin/ai.ts
index 2d723a31..e20da7ac 100644
--- a/ui/src/services/admin/ai.ts
+++ b/ui/src/services/admin/ai.ts
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
import useSWR from 'swr';
import qs from 'qs';
diff --git a/ui/src/services/admin/mcp.ts b/ui/src/services/admin/mcp.ts
index ab86e6db..6fbbd735 100644
--- a/ui/src/services/admin/mcp.ts
+++ b/ui/src/services/admin/mcp.ts
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
import request from '@/utils/request';
type McpConfig = {
diff --git a/ui/src/services/client/ai.ts b/ui/src/services/client/ai.ts
index 9b798b26..28cc6398 100644
--- a/ui/src/services/client/ai.ts
+++ b/ui/src/services/client/ai.ts
@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
import qs from 'qs';
import request from '@/utils/request';
diff --git a/ui/src/utils/requestAi.ts b/ui/src/utils/requestAi.ts
index ad7e6562..444bbe6d 100644
--- a/ui/src/utils/requestAi.ts
+++ b/ui/src/utils/requestAi.ts
@@ -18,14 +18,14 @@ interface RequestAiOptions extends RequestInit {
passingError?: boolean;
}
-// 创建一个跟踪当前请求的状态对象
+// create a object to track the current request state
const requestState = {
currentReader: null as ReadableStreamDefaultReader<Uint8Array> | null,
abortController: null as AbortController | null,
isProcessing: false,
};
-// HTTP 错误处理函数(基于 request.ts 的逻辑)
+// HTTP error handling function (based on request.ts logic)
const handleHttpError = async (
response: Response,
options: RequestAiOptions,
@@ -162,22 +162,22 @@ const handleHttpError = async (
};
const requestAi = async (url: string, options: RequestAiOptions) => {
try {
- // 如果有之前的请求正在处理,取消它
+ // if there is a previous request being processed, cancel it
if (requestState.isProcessing && requestState.abortController) {
requestState.abortController.abort();
}
- // 创建新的AbortController
+ // create a new AbortController
const abortController = new AbortController();
requestState.abortController = abortController;
- // 合并传入的signal与新创建的signal
+ // merge the incoming signal with the new created signal
const combinedSignal = options.signal || abortController.signal;
- // 标记为正在处理
+ // mark as being processed
requestState.isProcessing = true;
- // 获取认证信息和语言设置(与 request.ts 保持一致)
+ // get the authentication information and language settings (consistent
with request.ts)
const token = Storage.get(LOGGED_TOKEN_STORAGE_KEY) || '';
console.log(token);
const lang = getCurrentLang();
@@ -194,7 +194,7 @@ const requestAi = async (url: string, options:
RequestAiOptions) => {
},
});
- // 统一错误处理(基于 request.ts 的逻辑)
+ // unified error handling (based on request.ts logic)
if (!response.ok) {
await handleHttpError(response, options);
return;
@@ -205,7 +205,7 @@ const requestAi = async (url: string, options:
RequestAiOptions) => {
throw new Error('ReadableStream not supported');
}
- // 存储当前reader以便稍后可以取消
+ // store the current reader so it can be cancelled later
requestState.currentReader = reader;
const decoder = new TextDecoder();
@@ -231,10 +231,10 @@ const requestAi = async (url: string, options:
RequestAiOptions) => {
lines.forEach((line) => {
if (line.trim()) {
try {
- // 处理特殊的 [DONE] 信号
+ // handle the special [DONE] signal
const cleanedLine = line.replace(/^data: /, '').trim();
if (cleanedLine === '[DONE]') {
- return; // 跳过 [DONE] 信号的处理
+ return; // skip the [DONE] signal processing
}
if (cleanedLine) {
@@ -247,7 +247,7 @@ const requestAi = async (url: string, options:
RequestAiOptions) => {
}
});
- // 检查是否已取消
+ // check if it has been cancelled
if (combinedSignal.aborted) {
requestState.isProcessing = false;
requestState.currentReader = null;
@@ -257,9 +257,9 @@ const requestAi = async (url: string, options:
RequestAiOptions) => {
await processStream();
} catch (error) {
if ((error as Error).message === 'Request was aborted') {
- options.onComplete?.(); // 取消也视为完成
+ options.onComplete?.();
} else {
- throw error; // 重新抛出其他错误
+ throw error; // rethrow other errors
}
}
};
@@ -269,7 +269,7 @@ const requestAi = async (url: string, options:
RequestAiOptions) => {
const errorMessage =
error instanceof Error ? error.message : 'Unknown error';
- // 如果是取消导致的错误,不作为错误处理
+ // if the error is caused by cancellation, do not treat it as an error
if (
errorMessage !== 'The user aborted a request' &&
errorMessage !== 'Request was aborted'
@@ -278,7 +278,7 @@ const requestAi = async (url: string, options:
RequestAiOptions) => {
options.onError?.(new Error(errorMessage));
} else {
console.log('Request was cancelled by user');
- options.onComplete?.(); // 取消也视为完成
+ options.onComplete?.(); // cancellation is also considered complete
}
} finally {
requestState.isProcessing = false;
@@ -286,7 +286,7 @@ const requestAi = async (url: string, options:
RequestAiOptions) => {
}
};
-// 添加一个取消当前请求的函数
+// add a function to cancel the current request
const cancelCurrentRequest = () => {
if (requestState.abortController) {
requestState.abortController.abort();