0.0.1 前后端开发完成
This commit is contained in:
parent
ddea65cc8b
commit
8bba879ce6
@ -1,8 +1,8 @@
|
||||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 4870215 */
|
||||
src: url('iconfont.woff2?t=1744276722320') format('woff2'),
|
||||
url('iconfont.woff?t=1744276722320') format('woff'),
|
||||
url('iconfont.ttf?t=1744276722320') format('truetype');
|
||||
src: url('iconfont.woff2?t=1744289078529') format('woff2'),
|
||||
url('iconfont.woff?t=1744289078529') format('woff'),
|
||||
url('iconfont.ttf?t=1744289078529') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
@ -13,6 +13,10 @@
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-openmcp:before {
|
||||
content: "\e666";
|
||||
}
|
||||
|
||||
.icon-double-loading:before {
|
||||
content: "\e8fc";
|
||||
}
|
||||
|
Binary file not shown.
@ -5,7 +5,7 @@
|
||||
<div v-for="(message, index) in renderMessages" :key="index"
|
||||
:class="['message-item', message.role.split('/')[0]]">
|
||||
<div class="message-avatar" v-if="message.role.split('/')[0] === 'assistant'">
|
||||
<span class="iconfont icon-chat"></span>
|
||||
<span class="iconfont icon-robot"></span>
|
||||
</div>
|
||||
|
||||
<!-- 用户输入的部分 -->
|
||||
@ -90,7 +90,14 @@
|
||||
<span class="iconfont icon-chat"></span>
|
||||
</div>
|
||||
<div class="message-content">
|
||||
<div class="message-role">Agent</div>
|
||||
<div class="message-role">
|
||||
Agent
|
||||
<span class="message-reminder">
|
||||
正在生成答案
|
||||
<span class="tool-loading iconfont icon-double-loading">
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="message-text">
|
||||
<span v-html="waitingMarkdownToHtml(streamingContent)"></span>
|
||||
</div>
|
||||
@ -268,6 +275,12 @@ watch(streamingContent, () => {
|
||||
}
|
||||
}, { deep: true });
|
||||
|
||||
watch(streamingToolCalls, () => {
|
||||
if (autoScroll.value) {
|
||||
scrollToBottom();
|
||||
}
|
||||
}, { deep: true });
|
||||
|
||||
let loop: TaskLoop | undefined = undefined;
|
||||
|
||||
const handleSend = () => {
|
||||
@ -278,11 +291,9 @@ const handleSend = () => {
|
||||
|
||||
const userMessage = userInput.value.trim();
|
||||
|
||||
loop = new TaskLoop(
|
||||
streamingContent,
|
||||
streamingToolCalls,
|
||||
// onerror
|
||||
(msg) => {
|
||||
loop = new TaskLoop(streamingContent, streamingToolCalls);
|
||||
|
||||
loop.registerOnError((msg) => {
|
||||
ElMessage({
|
||||
message: msg,
|
||||
type: 'error',
|
||||
@ -295,19 +306,22 @@ const handleSend = () => {
|
||||
});
|
||||
|
||||
isLoading.value = false;
|
||||
},
|
||||
// onchunk
|
||||
(chunk) => {
|
||||
});
|
||||
|
||||
loop.registerOnChunk((chunk) => {
|
||||
scrollToBottom();
|
||||
},
|
||||
// ondone
|
||||
() => {
|
||||
});
|
||||
|
||||
loop.registerOnDone(() => {
|
||||
isLoading.value = false;
|
||||
scrollToBottom();
|
||||
});
|
||||
|
||||
loop.registerOnEpoch(() => {
|
||||
isLoading.value = true;
|
||||
scrollToBottom();
|
||||
});
|
||||
|
||||
loop = undefined;
|
||||
}
|
||||
);
|
||||
|
||||
loop.start(tabStorage, userMessage);
|
||||
userInput.value = '';
|
||||
|
@ -22,9 +22,10 @@ export class TaskLoop {
|
||||
constructor(
|
||||
private readonly streamingContent: Ref<string>,
|
||||
private readonly streamingToolCalls: Ref<ToolCall[]>,
|
||||
private readonly onError: (msg: string) => void = (msg) => {},
|
||||
private readonly onChunk: (chunk: ChatCompletionChunk) => void = (chunk) => {},
|
||||
private readonly onDone: () => void = () => {},
|
||||
private onError: (msg: string) => void = (msg) => {},
|
||||
private onChunk: (chunk: ChatCompletionChunk) => void = (chunk) => {},
|
||||
private onDone: () => void = () => {},
|
||||
private onEpoch: () => void = () => {},
|
||||
private readonly taskOptions: TaskLoopOptions = { maxEpochs: 20 },
|
||||
) {}
|
||||
|
||||
@ -166,6 +167,21 @@ export class TaskLoop {
|
||||
this.streamingToolCalls.value = [];
|
||||
}
|
||||
|
||||
public registerOnError(handler: (msg: string) => void) {
|
||||
this.onError = handler;
|
||||
}
|
||||
|
||||
public registerOnChunk(handler: (chunk: ChatCompletionChunk) => void) {
|
||||
this.onChunk = handler;
|
||||
}
|
||||
|
||||
public registerOnDone(handler: () => void) {
|
||||
this.onDone = handler;
|
||||
}
|
||||
|
||||
public registerOnEpoch(handler: () => void) {
|
||||
this.onEpoch = handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 开启循环,异步更新 DOM
|
||||
@ -176,6 +192,8 @@ export class TaskLoop {
|
||||
|
||||
for (let i = 0; i < this.taskOptions.maxEpochs; ++ i) {
|
||||
|
||||
this.onEpoch();
|
||||
|
||||
// 初始累计清空
|
||||
this.streamingContent.value = '';
|
||||
this.streamingToolCalls.value = [];
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"currentIndex": 1,
|
||||
"currentIndex": 2,
|
||||
"tabs": [
|
||||
{
|
||||
"name": "交互测试",
|
||||
@ -115,17 +115,100 @@
|
||||
{
|
||||
"name": "multiply",
|
||||
"description": "对两个数字进行实数域的乘法运算",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"name": "is_even",
|
||||
"description": "判断一个整数是否为偶数",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"name": "capitalize",
|
||||
"description": "将字符串首字母大写",
|
||||
"enabled": false
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"enableWebSearch": false,
|
||||
"temperature": 0.7,
|
||||
"contextLength": 10,
|
||||
"systemPrompt": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "交互测试",
|
||||
"icon": "icon-robot",
|
||||
"type": "blank",
|
||||
"componentIndex": 3,
|
||||
"storage": {
|
||||
"messages": [
|
||||
{
|
||||
"role": "user",
|
||||
"content": "什么是斐波那契数列?"
|
||||
},
|
||||
{
|
||||
"role": "assistant",
|
||||
"content": "斐波那契数列(Fibonacci sequence)是以意大利数学家**列昂纳多·斐波那契**(Leonardo Fibonacci)命名的一个经典数列。其定义如下:\n\n### **定义**\n- **前两项**: \n \\( F_0 = 0 \\), \\( F_1 = 1 \\)(部分定义从 \\( F_1 = 1 \\), \\( F_2 = 1 \\) 开始)。\n- **递推关系**: \n 从第三项开始,每一项等于前两项之和: \n \\( F_n = F_{n-1} + F_{n-2} \\) (\\( n \\geq 2 \\))。\n\n### **数列示例**\n前几项为: \n0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ...\n\n### **关键特性**\n1. **黄金分割**: \n 当 \\( n \\) 趋近于无穷大时,相邻两项的比值 \\( \\frac{F_{n+1}}{F_n} \\) 趋近于**黄金比例** \\( \\phi \\approx 1.618 \\)。\n\n2. **通项公式(比奈公式)**: \n \\[\n F_n = \\frac{\\phi^n - (-\\phi)^{-n}}{\\sqrt{5}}, \\quad \\phi = \\frac{1+\\sqrt{5}}{2}\n \\]\n 该公式通过无理数精确计算整数项。\n\n3. **应用领域**: \n - 自然界:如花瓣排列、松果螺旋、鹦鹉螺壳的生长模式。 \n - 计算机科学:动态规划、递归算法(需注意重复计算的优化)。 \n - 金融:斐波那契回调线用于技术分析。\n\n### **扩展知识**\n- **负数项**:递推关系可反向延伸,如 \\( F_{-n} = (-1)^{n+1}F_n \\)。\n- **变体**:卢卡斯数列(Lucas sequence)以 \\( L_0=2 \\), \\( L_1=1 \\) 开始,同样满足递推关系。\n\n斐波那契数列因其简洁的递推定义与广泛的自然关联性,成为数学和科学中的经典研究对象。"
|
||||
},
|
||||
{
|
||||
"role": "user",
|
||||
"content": "add 1 2"
|
||||
},
|
||||
{
|
||||
"role": "assistant",
|
||||
"content": "",
|
||||
"tool_calls": [
|
||||
{
|
||||
"id": "call_0_4eeb1c2f-8345-4b75-b002-af252af0728f",
|
||||
"index": 0,
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "add",
|
||||
"arguments": "{\"a\":1,\"b\":2}"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"role": "tool",
|
||||
"tool_call_id": "call_0_4eeb1c2f-8345-4b75-b002-af252af0728f",
|
||||
"content": "[{\"type\":\"text\",\"text\":\"3\"}]"
|
||||
},
|
||||
{
|
||||
"role": "assistant",
|
||||
"content": "1 + 2 = 3"
|
||||
},
|
||||
{
|
||||
"role": "user",
|
||||
"content": "nihao"
|
||||
},
|
||||
{
|
||||
"role": "assistant",
|
||||
"content": "你好!有什么可以帮您的吗?😊"
|
||||
}
|
||||
],
|
||||
"settings": {
|
||||
"modelIndex": 0,
|
||||
"enableTools": [
|
||||
{
|
||||
"name": "add",
|
||||
"description": "对两个数字进行实数域的加法",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"name": "multiply",
|
||||
"description": "对两个数字进行实数域的乘法运算",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"name": "is_even",
|
||||
"description": "判断一个整数是否为偶数",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"name": "capitalize",
|
||||
"description": "将字符串首字母大写",
|
||||
"enabled": true
|
||||
}
|
||||
],
|
||||
"enableWebSearch": false,
|
||||
|
Loading…
x
Reference in New Issue
Block a user