* feat: add tracing modules * Initial commit * fix: problem * fix: update trace web * fix: trace view * fix: trace view * fix: fix some problem * fix: knowledge and mcp trace * feat: save trace to user home dir * feat: open trace with electron browser window * fix: root trace outputs * feat: trace internationalization and add trace icon * feat: add trace title * feat: update * package.json添加windows运行script * feat: update window title * fix: mcp trace param * fix: error show * fix: listTool result * fix: merge error * feat: add stream usage and response * feat: change trace stream * fix: change stream adapter * fix: span detail show problem * fix: process show by time * fix: stream outputs * fix: merge problem * fix: stream outputs * fix: output text * fix: EDAS support text * fix: change trace footer style * fix: topicId is loaded multiple times * fix: span reload problem & attribute with cache * fix: refresh optimization * Change Powered by text. * resolve upstream conflicts * fix: build-time type exception * fix: exceptions not used when building * fix: recend no trace * fix: resend trace list * fix: delete temporary files * feat: trace for resend * fix: trace for resend message with edit * fix: directory structure and construction method of mcp-trace * fix: change CRLF to LF * fix: add function call outputs * Revert "fix: change CRLF to LF" * fix: reorganize multi-model display * fix: append model trace binding topic * fix: some problems * fix: code optimization * fix: delete async * fix: UI optimization * fix: sort import --------- Co-authored-by: 崔顺发 <csf01409784@alibaba-inc.com> Co-authored-by: 管鑫荣 <gxr01409783@alibaba-inc.com>
76 lines
2.0 KiB
TypeScript
76 lines
2.0 KiB
TypeScript
import { Context, ContextManager, ROOT_CONTEXT } from '@opentelemetry/api'
|
||
|
||
export class TopicContextManager implements ContextManager {
|
||
private topicContextStack: Map<string, Context[]>
|
||
private _topicContexts: Map<string, Context>
|
||
|
||
constructor() {
|
||
// topicId -> context
|
||
this.topicContextStack = new Map()
|
||
this._topicContexts = new Map()
|
||
}
|
||
|
||
// 绑定一个context到topicId
|
||
startContextForTopic(topicId, context: Context) {
|
||
const currentContext = this.getCurrentContext(topicId)
|
||
this._topicContexts.set(topicId, context)
|
||
if (!this.topicContextStack.has(topicId) && !this.topicContextStack.get(topicId)) {
|
||
this.topicContextStack.set(topicId, [currentContext])
|
||
} else {
|
||
this.topicContextStack.get(topicId)?.push(currentContext)
|
||
}
|
||
}
|
||
|
||
// 获取topicId对应的context
|
||
getContextForTopic(topicId) {
|
||
return this.getCurrentContext(topicId)
|
||
}
|
||
|
||
endContextForTopic(topicId) {
|
||
const context = this.getHistoryContext(topicId)
|
||
this._topicContexts.set(topicId, context)
|
||
}
|
||
|
||
cleanContextForTopic(topicId) {
|
||
this.topicContextStack.delete(topicId)
|
||
this._topicContexts.delete(topicId)
|
||
}
|
||
|
||
private getHistoryContext(topicId): Context {
|
||
const hasContext = this.topicContextStack.has(topicId) && this.topicContextStack.get(topicId)
|
||
const context = hasContext && hasContext.length > 0 && hasContext.pop()
|
||
return context ? context : ROOT_CONTEXT
|
||
}
|
||
|
||
private getCurrentContext(topicId): Context {
|
||
const hasContext = this._topicContexts.has(topicId) && this._topicContexts.get(topicId)
|
||
return hasContext || ROOT_CONTEXT
|
||
}
|
||
|
||
// OpenTelemetry接口实现
|
||
active() {
|
||
// 不支持全局active,必须显式传递
|
||
return ROOT_CONTEXT
|
||
}
|
||
|
||
with(_, fn, thisArg, ...args) {
|
||
// 直接调用fn,不做全局active切换
|
||
return fn.apply(thisArg, args)
|
||
}
|
||
|
||
bind(target, context) {
|
||
// 显式绑定
|
||
target.__ot_context = context
|
||
return target
|
||
}
|
||
|
||
enable() {
|
||
return this
|
||
}
|
||
|
||
disable() {
|
||
this._topicContexts.clear()
|
||
return this
|
||
}
|
||
}
|