Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Pangea-Agent
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
2
Merge Requests
2
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Gavin-Group
Pangea-Agent
Commits
7211c835
Commit
7211c835
authored
Dec 22, 2025
by
王舵
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'main' into feature/take-road
parents
c107c059
e87c7566
Changes
12
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
1010 additions
and
344 deletions
+1010
-344
WorkPanel和Event模块优化方案.md
WorkPanel和Event模块优化方案.md
+0
-0
TimelineContainer.vue
frontend/src/components/TimelineContainer.vue
+124
-0
TimelinePanel.vue
frontend/src/components/TimelinePanel.vue
+148
-344
EventDeduplicationService.ts
frontend/src/services/EventDeduplicationService.ts
+71
-0
EventProcessingService.ts
frontend/src/services/EventProcessingService.ts
+100
-0
ObjectPoolService.ts
frontend/src/services/ObjectPoolService.ts
+53
-0
OptimizedEventProcessingService.ts
frontend/src/services/OptimizedEventProcessingService.ts
+167
-0
README.md
frontend/src/services/README.md
+85
-0
UnifiedEventProcessor.ts
frontend/src/services/UnifiedEventProcessor.ts
+108
-0
timeline.ts
frontend/src/types/timeline.ts
+60
-0
timelineUtils.ts
frontend/src/utils/timelineUtils.ts
+39
-0
typeGuards.ts
frontend/src/utils/typeGuards.ts
+55
-0
No files found.
WorkPanel和Event模块优化方案.md
0 → 100644
View file @
7211c835
This diff is collapsed.
Click to expand it.
frontend/src/components/TimelineContainer.vue
0 → 100644
View file @
7211c835
<
template
>
<TimelinePanel
:events=
"events"
:getEventTypeLabel=
"getEventTypeLabel"
:formatTime=
"formatTime"
:getExpandedState=
"getExpandedState"
:toggleExpand=
"toggleExpand"
:isToolEventType=
"isToolEventType"
:hasValidToolInput=
"hasValidToolInput"
:hasValidToolOutput=
"hasValidToolOutput"
:onClearTimeline=
"handleClearTimeline"
/>
</
template
>
<
script
setup
lang=
"ts"
>
import
{
ref
,
onUnmounted
,
onMounted
}
from
'vue'
import
TimelinePanel
from
'./TimelinePanel.vue'
import
{
TimelineEventStateManager
}
from
'../services/timelineEventStateManager'
import
{
CacheService
}
from
'../services/CacheService'
import
type
{
TimelineEvent
}
from
'../types/timeline'
import
{
eventTypeLabels
}
from
'../types/timeline'
import
{
isToolEventType
,
hasValidToolInput
,
hasValidToolOutput
}
from
'../utils/timelineUtils'
import
{
UnifiedEventProcessor
}
from
'../services/UnifiedEventProcessor'
// 状态管理器
const
stateManager
=
new
TimelineEventStateManager
();
// 缓存服务
const
cacheService
=
new
CacheService
();
// 统一事件处理器
const
eventProcessor
=
new
UnifiedEventProcessor
();
// 事件数据
const
events
=
ref
<
TimelineEvent
[]
>
([]);
// 注册事件处理器
eventProcessor
.
registerHandler
((
event
:
TimelineEvent
)
=>
{
// 添加事件到列表
events
.
value
.
push
(
event
);
console
.
log
(
'[TimelineContainer] 成功添加事件:'
,
event
.
type
,
event
.
title
);
});
// 添加时间轴事件
const
addEvent
=
(
event
:
any
)
=>
{
// 使用统一事件处理器处理并分发事件
eventProcessor
.
processAndDispatch
(
event
);
};
// 获取事件类型标签
const
getEventTypeLabel
=
(
type
:
string
):
string
=>
{
return
cacheService
.
getCachedEventTypeLabel
(
type
,
eventTypeLabels
,
(
labels
,
t
)
=>
labels
[
t
]
||
t
);
};
// 格式化时间
const
formatTime
=
(
timestamp
:
number
):
string
=>
{
return
cacheService
.
getCachedFormattedTime
(
timestamp
,
(
t
)
=>
{
const
date
=
new
Date
(
t
);
const
hours
=
String
(
date
.
getHours
()).
padStart
(
2
,
'0'
);
const
minutes
=
String
(
date
.
getMinutes
()).
padStart
(
2
,
'0'
);
const
seconds
=
String
(
date
.
getSeconds
()).
padStart
(
2
,
'0'
);
return
`
${
hours
}
:
${
minutes
}
:
${
seconds
}
`
;
});
};
// 获取事件的展开状态
const
getExpandedState
=
(
index
:
number
):
boolean
=>
{
return
stateManager
.
getExpandedState
(
index
);
};
// 切换事件详细信息的展开状态
const
toggleExpand
=
(
index
:
number
)
=>
{
stateManager
.
toggleExpand
(
index
);
};
// 清除时间轴
const
handleClearTimeline
=
()
=>
{
events
.
value
=
[];
eventProcessor
.
clearProcessedEvents
();
stateManager
.
clearAllStates
();
cacheService
.
clearAllCaches
();
};
// 显示性能统计信息
const
showPerformanceStats
=
()
=>
{
const
stats
=
eventProcessor
.
getPerformanceStats
();
console
.
log
(
'[TimelineContainer] 性能统计:'
,
stats
);
alert
(
`总处理事件数:
${
stats
.
totalProcessed
}
\n重用事件数:
${
stats
.
totalReused
}
\n重用率:
${
stats
.
reuseRate
}
%`
);
};
// 暴露方法供父组件调用
defineExpose
({
addEvent
,
clearTimeline
:
handleClearTimeline
,
showPerformanceStats
});
// 组件卸载时清理资源
onUnmounted
(()
=>
{
stateManager
.
clearAllStates
();
cacheService
.
clearAllCaches
();
});
// 组件挂载时启动定期性能监控
onMounted
(()
=>
{
// 每30秒输出一次性能统计
const
perfInterval
=
setInterval
(()
=>
{
const
stats
=
eventProcessor
.
getPerformanceStats
();
console
.
log
(
'[TimelineContainer] 定期性能统计:'
,
stats
);
},
30000
);
// 组件卸载时清除定时器
onUnmounted
(()
=>
{
clearInterval
(
perfInterval
);
});
});
</
script
>
<
style
scoped
>
.timeline-container-wrapper
{
height
:
100%
;
}
</
style
>
\ No newline at end of file
frontend/src/components/TimelinePanel.vue
View file @
7211c835
This diff is collapsed.
Click to expand it.
frontend/src/services/EventDeduplicationService.ts
0 → 100644
View file @
7211c835
// 事件去重服务
export
class
EventDeduplicationService
{
// 用于跟踪已添加的事件的Set,防止重复
private
eventHashSet
:
Set
<
string
>
=
new
Set
();
/**
* 检查是否为重复事件
* @param event 当前事件
* @returns 是否为重复事件
*/
isDuplicateEvent
(
event
:
any
):
boolean
{
// 对于某些关键事件类型,我们允许重复显示(如错误事件)
const
criticalEventTypes
=
[
'error'
,
'result'
];
if
(
criticalEventTypes
.
includes
(
event
.
type
))
{
return
false
;
}
// 生成事件的唯一标识符
const
eventHash
=
this
.
generateEventHash
(
event
);
if
(
this
.
eventHashSet
.
has
(
eventHash
))
{
return
true
;
}
// 将事件哈希添加到Set中
this
.
eventHashSet
.
add
(
eventHash
);
// 限制Set大小以避免内存泄漏
if
(
this
.
eventHashSet
.
size
>
1000
)
{
// 删除最早的100个条目
const
iterator
=
this
.
eventHashSet
.
values
();
for
(
let
i
=
0
;
i
<
100
;
i
++
)
{
const
value
=
iterator
.
next
();
if
(
!
value
.
done
)
{
this
.
eventHashSet
.
delete
(
value
.
value
);
}
}
}
return
false
;
}
/**
* 生成事件的唯一标识符
* @param event 事件对象
* @returns 事件哈希值
*/
private
generateEventHash
(
event
:
any
):
string
{
// 确保有时间戳
const
timestamp
=
event
.
timestamp
||
Date
.
now
();
// 对于工具事件,使用类型+工具名+工具操作+时间戳作为标识
if
(
event
.
type
&&
event
.
type
.
startsWith
(
'tool_'
)
&&
event
.
toolName
&&
event
.
toolAction
)
{
return
`
${
event
.
type
}
-
${
event
.
toolName
}
-
${
event
.
toolAction
}
-
${
timestamp
}
`
;
}
// 对于嵌入事件,使用URL+时间戳作为标识
if
(
event
.
type
===
'embed'
&&
event
.
embedUrl
)
{
return
`embed-
${
event
.
embedUrl
}
-
${
timestamp
}
`
;
}
// 对于其他事件,使用类型+标题+时间戳作为标识
return
`
${
event
.
type
}
-
${
event
.
title
||
''
}
-
${
timestamp
}
`
;
}
/**
* 清除事件哈希集合
*/
clearEventHashSet
():
void
{
this
.
eventHashSet
.
clear
();
}
}
\ No newline at end of file
frontend/src/services/EventProcessingService.ts
0 → 100644
View file @
7211c835
// 统一的事件处理服务
import
type
{
TimelineEvent
}
from
'../types/timeline'
;
export
class
EventProcessingService
{
/**
* 标准化事件对象
* @param event 原始事件数据
* @returns 标准化的事件对象
*/
normalizeEvent
(
event
:
any
):
TimelineEvent
{
// 确保时间戳存在
const
timestamp
=
event
.
timestamp
||
Date
.
now
();
// 根据事件类型创建相应类型的事件对象
switch
(
event
.
type
)
{
case
'thought'
:
return
{
type
:
'thought'
,
title
:
event
.
title
||
'思考事件'
,
content
:
event
.
content
||
''
,
thinkingType
:
event
.
thinkingType
,
metadata
:
event
.
metadata
,
timestamp
};
case
'tool_call'
:
return
{
type
:
'tool_call'
,
title
:
event
.
title
||
'工具调用'
,
toolName
:
event
.
toolName
||
''
,
toolAction
:
event
.
toolAction
||
''
,
toolInput
:
event
.
toolInput
,
toolStatus
:
event
.
toolStatus
,
metadata
:
event
.
metadata
,
timestamp
};
case
'tool_result'
:
return
{
type
:
'tool_result'
,
title
:
event
.
title
||
'工具结果'
,
toolName
:
event
.
toolName
||
''
,
toolAction
:
event
.
toolAction
||
''
,
toolOutput
:
event
.
toolOutput
,
toolStatus
:
event
.
toolStatus
,
executionTime
:
event
.
executionTime
,
metadata
:
event
.
metadata
,
timestamp
};
case
'tool_error'
:
return
{
type
:
'tool_error'
,
title
:
event
.
title
||
'工具错误'
,
toolName
:
event
.
toolName
||
''
,
errorMessage
:
event
.
errorMessage
||
''
,
errorCode
:
event
.
errorCode
,
metadata
:
event
.
metadata
,
timestamp
};
case
'embed'
:
return
{
type
:
'embed'
,
title
:
event
.
title
||
'嵌入内容'
,
embedUrl
:
event
.
embedUrl
||
''
,
embedType
:
event
.
embedType
,
embedTitle
:
event
.
embedTitle
,
embedHtmlContent
:
event
.
embedHtmlContent
,
metadata
:
event
.
metadata
,
timestamp
};
default
:
return
{
type
:
event
.
type
||
'thought'
,
title
:
event
.
title
||
'未命名事件'
,
metadata
:
event
.
metadata
,
timestamp
};
}
}
/**
* 处理事件类型转换
* @param event 事件对象
* @returns 处理后的事件对象
*/
processEventType
(
event
:
any
):
any
{
// 处理thinking类型的事件,如果是final_answer则转换为result类型
const
processedEvent
=
{
...
event
};
if
(
processedEvent
.
type
===
'thought'
&&
processedEvent
.
title
===
'最终答案'
)
{
processedEvent
.
type
=
'result'
;
}
return
processedEvent
;
}
}
\ No newline at end of file
frontend/src/services/ObjectPoolService.ts
0 → 100644
View file @
7211c835
// 对象池服务
export
class
ObjectPoolService
<
T
>
{
private
pool
:
T
[]
=
[];
private
factory
:
()
=>
T
;
private
resetter
?:
(
obj
:
T
)
=>
void
;
private
maxSize
:
number
;
constructor
(
factory
:
()
=>
T
,
resetter
?:
(
obj
:
T
)
=>
void
,
maxSize
:
number
=
100
)
{
this
.
factory
=
factory
;
this
.
resetter
=
resetter
;
this
.
maxSize
=
maxSize
;
}
/**
* 从对象池获取对象
* @returns 对象实例
*/
acquire
():
T
{
if
(
this
.
pool
.
length
>
0
)
{
return
this
.
pool
.
pop
()
!
;
}
return
this
.
factory
();
}
/**
* 将对象归还到对象池
* @param obj 对象实例
*/
release
(
obj
:
T
):
void
{
if
(
this
.
resetter
)
{
this
.
resetter
(
obj
);
}
if
(
this
.
pool
.
length
<
this
.
maxSize
)
{
this
.
pool
.
push
(
obj
);
}
}
/**
* 清空对象池
*/
clear
():
void
{
this
.
pool
=
[];
}
/**
* 获取对象池当前大小
* @returns 对象池大小
*/
size
():
number
{
return
this
.
pool
.
length
;
}
}
\ No newline at end of file
frontend/src/services/OptimizedEventProcessingService.ts
0 → 100644
View file @
7211c835
// 优化的事件处理服务
import
{
ObjectPoolService
}
from
'./ObjectPoolService'
;
import
type
{
TimelineEvent
}
from
'../types/timeline'
;
export
class
OptimizedEventProcessingService
{
private
eventObjectPool
:
ObjectPoolService
<
Record
<
string
,
any
>>
;
private
MAX_POOL_SIZE
:
number
=
100
;
private
totalEventsProcessed
:
number
=
0
;
private
totalEventsReused
:
number
=
0
;
constructor
()
{
// 创建对象池用于事件对象
this
.
eventObjectPool
=
new
ObjectPoolService
<
Record
<
string
,
any
>>
(
()
=>
({}),
// 工厂函数创建空对象
(
obj
)
=>
{
// 重置函数清空对象属性
for
(
const
key
in
obj
)
{
if
(
obj
.
hasOwnProperty
(
key
))
{
delete
obj
[
key
];
}
}
},
this
.
MAX_POOL_SIZE
);
}
/**
* 标准化事件对象(使用对象池优化)
* @param event 原始事件数据
* @returns 标准化的事件对象
*/
normalizeEvent
(
event
:
any
):
TimelineEvent
{
// 从对象池获取对象
const
normalizedEvent
=
this
.
eventObjectPool
.
acquire
();
try
{
// 确保时间戳存在
const
timestamp
=
event
.
timestamp
||
Date
.
now
();
// 根据事件类型创建相应类型的事件对象
switch
(
event
.
type
)
{
case
'thought'
:
Object
.
assign
(
normalizedEvent
,
{
type
:
'thought'
,
title
:
event
.
title
||
'思考事件'
,
content
:
event
.
content
||
''
,
thinkingType
:
event
.
thinkingType
,
metadata
:
event
.
metadata
,
timestamp
});
break
;
case
'tool_call'
:
Object
.
assign
(
normalizedEvent
,
{
type
:
'tool_call'
,
title
:
event
.
title
||
'工具调用'
,
toolName
:
event
.
toolName
||
''
,
toolAction
:
event
.
toolAction
||
''
,
toolInput
:
event
.
toolInput
,
toolStatus
:
event
.
toolStatus
,
metadata
:
event
.
metadata
,
timestamp
});
break
;
case
'tool_result'
:
Object
.
assign
(
normalizedEvent
,
{
type
:
'tool_result'
,
title
:
event
.
title
||
'工具结果'
,
toolName
:
event
.
toolName
||
''
,
toolAction
:
event
.
toolAction
||
''
,
toolOutput
:
event
.
toolOutput
,
toolStatus
:
event
.
toolStatus
,
executionTime
:
event
.
executionTime
,
metadata
:
event
.
metadata
,
timestamp
});
break
;
case
'tool_error'
:
Object
.
assign
(
normalizedEvent
,
{
type
:
'tool_error'
,
title
:
event
.
title
||
'工具错误'
,
toolName
:
event
.
toolName
||
''
,
errorMessage
:
event
.
errorMessage
||
''
,
errorCode
:
event
.
errorCode
,
metadata
:
event
.
metadata
,
timestamp
});
break
;
case
'embed'
:
Object
.
assign
(
normalizedEvent
,
{
type
:
'embed'
,
title
:
event
.
title
||
'嵌入内容'
,
embedUrl
:
event
.
embedUrl
||
''
,
embedType
:
event
.
embedType
,
embedTitle
:
event
.
embedTitle
,
embedHtmlContent
:
event
.
embedHtmlContent
,
metadata
:
event
.
metadata
,
timestamp
});
break
;
default
:
Object
.
assign
(
normalizedEvent
,
{
type
:
event
.
type
||
'thought'
,
title
:
event
.
title
||
'未命名事件'
,
metadata
:
event
.
metadata
,
timestamp
});
break
;
}
this
.
totalEventsProcessed
++
;
return
normalizedEvent
as
TimelineEvent
;
}
catch
(
error
)
{
// 如果出现错误,将对象归还到池中
this
.
eventObjectPool
.
release
(
normalizedEvent
);
throw
error
;
}
}
/**
* 处理完事件后,将对象归还到池中
* @param obj 事件对象
*/
releaseEventObject
(
obj
:
Record
<
string
,
any
>
):
void
{
if
(
obj
&&
typeof
obj
===
'object'
)
{
// 清空对象属性
for
(
const
key
in
obj
)
{
if
(
obj
.
hasOwnProperty
(
key
))
{
delete
obj
[
key
];
}
}
// 如果对象池未满,将对象放回池中
if
(
this
.
eventObjectPool
.
size
()
<
this
.
MAX_POOL_SIZE
)
{
this
.
eventObjectPool
.
release
(
obj
);
this
.
totalEventsReused
++
;
}
}
}
/**
* 获取性能统计信息
* @returns 性能统计信息
*/
getPerformanceStats
():
{
totalProcessed
:
number
;
totalReused
:
number
;
reuseRate
:
number
}
{
const
reuseRate
=
this
.
totalEventsProcessed
>
0
?
(
this
.
totalEventsReused
/
this
.
totalEventsProcessed
)
*
100
:
0
;
return
{
totalProcessed
:
this
.
totalEventsProcessed
,
totalReused
:
this
.
totalEventsReused
,
reuseRate
:
parseFloat
(
reuseRate
.
toFixed
(
2
))
};
}
/**
* 清空统计信息
*/
clearStats
():
void
{
this
.
totalEventsProcessed
=
0
;
this
.
totalEventsReused
=
0
;
}
}
\ No newline at end of file
frontend/src/services/README.md
0 → 100644
View file @
7211c835
# 前端服务层优化说明
## 概述
本文档介绍了前端服务层的一系列优化措施,旨在提高代码质量、可维护性和性能。
## 优化内容
### 1. 统一类型定义
-
**文件**
:
`types/timeline.ts`
-
**功能**
: 统一定义了所有时间轴相关的事件类型和标签映射
-
**优势**
: 避免类型重复定义,提高类型安全性
### 2. 工具函数库
-
**文件**
:
`utils/timelineUtils.ts`
-
**功能**
: 包含时间轴相关的工具函数,如事件类型判断、输入输出验证等
-
**优势**
: 集中管理工具函数,避免重复实现
### 3. 类型守卫函数
-
**文件**
:
`utils/typeGuards.ts`
-
**功能**
: 提供类型守卫函数,用于精确的类型检查
-
**优势**
: 提高类型安全性,减少运行时错误
### 4. 事件去重服务
-
**文件**
:
`services/EventDeduplicationService.ts`
-
**功能**
: 统一处理事件去重逻辑
-
**优势**
: 避免重复事件处理,节省资源
### 5. 对象池服务
-
**文件**
:
`services/ObjectPoolService.ts`
-
**功能**
: 提供通用的对象池实现
-
**优势**
: 减少对象创建和垃圾回收压力,提高性能
### 6. 优化的事件处理服务
-
**文件**
:
`services/OptimizedEventProcessingService.ts`
-
**功能**
: 使用对象池优化事件对象的创建和管理
-
**优势**
: 提高性能,减少内存分配
### 7. 统一事件处理器
-
**文件**
:
`services/UnifiedEventProcessor.ts`
-
**功能**
: 整合所有事件处理逻辑
-
**优势**
: 统一事件处理流程,便于维护
## 使用方法
### 1. 类型和工具函数使用
```
typescript
import
type
{
TimelineEvent
}
from
'../types/timeline'
;
import
{
isToolEventType
,
hasValidToolInput
}
from
'../utils/timelineUtils'
;
import
{
isThoughtEvent
}
from
'../utils/typeGuards'
;
```
### 2. 事件处理服务使用
```
typescript
import
{
UnifiedEventProcessor
}
from
'../services/UnifiedEventProcessor'
;
const
eventProcessor
=
new
UnifiedEventProcessor
();
eventProcessor
.
registerHandler
((
event
:
TimelineEvent
)
=>
{
// 处理事件
});
```
### 3. 性能监控
在TimelineContainer组件中提供了性能监控功能:
```
typescript
// 显示性能统计信息
showPerformanceStats
();
// 定期输出性能统计(每30秒)
// 在控制台查看: [TimelineContainer] 定期性能统计
```
## 性能优化效果
通过对象池和事件去重等优化措施,预期可以获得以下性能提升:
1.
减少对象创建次数,降低垃圾回收压力
2.
避免重复事件处理,节省CPU资源
3.
提高事件处理速度,改善用户体验
## 维护建议
1.
定期查看性能监控数据,评估优化效果
2.
新增事件类型时,需在
`types/timeline.ts`
中定义相应类型
3.
新增工具函数时,应添加到
`utils/timelineUtils.ts`
中
4.
保持服务层的单一职责原则,避免功能交叉
\ No newline at end of file
frontend/src/services/UnifiedEventProcessor.ts
0 → 100644
View file @
7211c835
// 统一事件处理器
import
type
{
TimelineEvent
}
from
'../types/timeline'
import
{
EventProcessingService
}
from
'./EventProcessingService'
import
{
EventDeduplicationService
}
from
'./EventDeduplicationService'
import
{
OptimizedEventProcessingService
}
from
'./OptimizedEventProcessingService'
export
class
UnifiedEventProcessor
{
private
eventProcessingService
:
EventProcessingService
private
eventDeduplicationService
:
EventDeduplicationService
private
optimizedEventProcessingService
:
OptimizedEventProcessingService
private
eventHandlers
:
Array
<
(
event
:
TimelineEvent
)
=>
void
>
=
[]
private
processedEvents
:
TimelineEvent
[]
=
[]
constructor
()
{
this
.
eventProcessingService
=
new
EventProcessingService
()
this
.
eventDeduplicationService
=
new
EventDeduplicationService
()
this
.
optimizedEventProcessingService
=
new
OptimizedEventProcessingService
()
}
/**
* 处理接收到的原始事件数据
* @param rawData 原始事件数据
* @returns 处理后的标准化事件对象
*/
processRawEvent
(
rawData
:
any
):
TimelineEvent
|
null
{
try
{
// 验证数据
if
(
!
rawData
||
typeof
rawData
!==
'object'
)
{
console
.
warn
(
'[UnifiedEventProcessor] 无效的事件数据:'
,
rawData
)
return
null
}
// 检查是否为重复事件
if
(
this
.
eventDeduplicationService
.
isDuplicateEvent
(
rawData
))
{
console
.
log
(
'[UnifiedEventProcessor] 跳过重复事件:'
,
rawData
.
type
,
rawData
.
title
)
return
null
}
// 处理事件类型转换
const
processedEvent
=
this
.
eventProcessingService
.
processEventType
(
rawData
)
// 标准化事件对象(使用优化的服务)
const
normalizedEvent
=
this
.
optimizedEventProcessingService
.
normalizeEvent
(
processedEvent
)
// 添加到已处理事件列表
this
.
processedEvents
.
push
(
normalizedEvent
)
// 限制已处理事件列表大小以避免内存泄漏
if
(
this
.
processedEvents
.
length
>
1000
)
{
this
.
processedEvents
.
shift
()
}
return
normalizedEvent
}
catch
(
error
)
{
console
.
error
(
'[UnifiedEventProcessor] 处理事件数据时发生错误:'
,
error
,
'原始数据:'
,
rawData
)
return
null
}
}
/**
* 注册事件处理器
* @param handler 事件处理器函数
*/
registerHandler
(
handler
:
(
event
:
TimelineEvent
)
=>
void
):
void
{
this
.
eventHandlers
.
push
(
handler
)
}
/**
* 分发事件给所有注册的处理器
* @param event 事件对象
*/
dispatchEvent
(
event
:
TimelineEvent
):
void
{
this
.
eventHandlers
.
forEach
(
handler
=>
{
try
{
handler
(
event
)
}
catch
(
error
)
{
console
.
error
(
'[UnifiedEventProcessor] 事件处理器执行错误:'
,
error
)
}
})
}
/**
* 处理并分发事件
* @param rawData 原始事件数据
*/
processAndDispatch
(
rawData
:
any
):
void
{
const
event
=
this
.
processRawEvent
(
rawData
)
if
(
event
)
{
this
.
dispatchEvent
(
event
)
}
}
/**
* 清除已处理事件列表
*/
clearProcessedEvents
():
void
{
this
.
processedEvents
=
[]
this
.
eventDeduplicationService
.
clearEventHashSet
()
}
/**
* 获取性能统计信息
* @returns 性能统计信息
*/
getPerformanceStats
():
{
totalProcessed
:
number
;
totalReused
:
number
;
reuseRate
:
number
}
{
return
this
.
optimizedEventProcessingService
.
getPerformanceStats
();
}
}
\ No newline at end of file
frontend/src/types/timeline.ts
0 → 100644
View file @
7211c835
// 统一的时间轴事件类型定义
export
interface
BaseTimelineEvent
{
type
:
string
;
title
:
string
;
timestamp
:
number
;
metadata
?:
Record
<
string
,
any
>
;
}
export
interface
ThoughtEvent
extends
BaseTimelineEvent
{
content
:
string
;
thinkingType
?:
string
;
}
export
interface
ToolCallEvent
extends
BaseTimelineEvent
{
toolName
:
string
;
toolAction
?:
string
;
toolInput
?:
any
;
toolStatus
:
string
;
}
export
interface
ToolResultEvent
extends
BaseTimelineEvent
{
toolName
:
string
;
toolAction
?:
string
;
toolOutput
?:
any
;
toolStatus
:
string
;
executionTime
?:
number
;
}
export
interface
ToolErrorEvent
extends
BaseTimelineEvent
{
toolName
:
string
;
errorMessage
:
string
;
errorCode
?:
string
;
}
export
interface
EmbedEvent
extends
BaseTimelineEvent
{
embedUrl
:
string
;
embedType
?:
string
;
embedTitle
:
string
;
embedHtmlContent
?:
string
;
}
export
type
TimelineEvent
=
|
ThoughtEvent
|
ToolCallEvent
|
ToolResultEvent
|
ToolErrorEvent
|
EmbedEvent
|
BaseTimelineEvent
;
// 事件类型标签映射
export
const
eventTypeLabels
:
Record
<
string
,
string
>
=
{
thought
:
'🧠 思考'
,
tool_call
:
'🔧 工具调用'
,
tool_result
:
'✅ 工具结果'
,
tool_error
:
'❌ 工具错误'
,
embed
:
'🌐 网页预览'
,
log
:
'📝 日志'
,
result
:
'🎯 最终答案'
,
observation
:
'🔍 观察'
};
\ No newline at end of file
frontend/src/utils/timelineUtils.ts
0 → 100644
View file @
7211c835
// 时间轴工具函数库
/**
* 检查是否为工具事件类型
* @param type 事件类型
* @returns 是否为工具事件类型
*/
export
function
isToolEventType
(
type
:
string
):
boolean
{
return
[
'tool_call'
,
'tool_result'
,
'tool_error'
].
includes
(
type
);
}
/**
* 检查工具输入是否有效
* @param event 事件对象
* @returns 工具输入是否有效
*/
export
function
hasValidToolInput
(
event
:
any
):
boolean
{
return
event
.
type
===
'tool_call'
&&
event
.
toolInput
!==
null
&&
event
.
toolInput
!==
undefined
;
}
/**
* 检查工具输出是否有效
* @param event 事件对象
* @returns 工具输出是否有效
*/
export
function
hasValidToolOutput
(
event
:
any
):
boolean
{
return
event
.
type
===
'tool_result'
&&
event
.
toolOutput
!==
null
&&
event
.
toolOutput
!==
undefined
;
}
/**
* 截断标题
* @param title 标题
* @param maxLength 最大长度
* @returns 截断后的标题
*/
export
function
truncateTitle
(
title
:
string
,
maxLength
:
number
=
30
):
string
{
if
(
!
title
)
return
''
;
return
title
.
length
>
maxLength
?
title
.
substring
(
0
,
maxLength
)
+
'...'
:
title
;
}
\ No newline at end of file
frontend/src/utils/typeGuards.ts
0 → 100644
View file @
7211c835
// 类型守卫函数
import
type
{
TimelineEvent
,
ThoughtEvent
,
ToolCallEvent
,
ToolResultEvent
,
ToolErrorEvent
,
EmbedEvent
}
from
'../types/timeline'
;
/**
* 检查是否为思考事件
* @param event 事件对象
* @returns 是否为思考事件
*/
export
function
isThoughtEvent
(
event
:
TimelineEvent
):
event
is
ThoughtEvent
{
return
event
.
type
===
'thought'
;
}
/**
* 检查是否为工具调用事件
* @param event 事件对象
* @returns 是否为工具调用事件
*/
export
function
isToolCallEvent
(
event
:
TimelineEvent
):
event
is
ToolCallEvent
{
return
event
.
type
===
'tool_call'
;
}
/**
* 检查是否为工具结果事件
* @param event 事件对象
* @returns 是否为工具结果事件
*/
export
function
isToolResultEvent
(
event
:
TimelineEvent
):
event
is
ToolResultEvent
{
return
event
.
type
===
'tool_result'
;
}
/**
* 检查是否为工具错误事件
* @param event 事件对象
* @returns 是否为工具错误事件
*/
export
function
isToolErrorEvent
(
event
:
TimelineEvent
):
event
is
ToolErrorEvent
{
return
event
.
type
===
'tool_error'
;
}
/**
* 检查是否为嵌入事件
* @param event 事件对象
* @returns 是否为嵌入事件
*/
export
function
isEmbedEvent
(
event
:
TimelineEvent
):
event
is
EmbedEvent
{
return
event
.
type
===
'embed'
;
}
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment