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();

Reply via email to