refactor(types): update ProviderId type definition for better compatibility

- Changed ProviderId type from a union of keyof ExtensibleProviderSettingsMap and string to an intersection, enhancing type safety.
- Renamed appendTrace method to appendMessageTrace in SpanManagerService for clarity and consistency.
- Updated references to appendTrace in useMessageOperations and ApiService to use the new method name.
- Added a new appendTrace method in SpanManagerService to bind existing traces, improving trace management.
- Adjusted topicId handling in fetchMessagesSummary to default to an empty string for better consistency.
This commit is contained in:
MyPrototypeWhat 2025-08-15 18:04:24 +08:00
parent 628919b562
commit b099c9b0b3
5 changed files with 39 additions and 9 deletions

View File

@ -65,7 +65,7 @@ export class ProviderError extends Error {
}
// 动态ProviderId类型 - 支持运行时扩展
export type ProviderId = keyof ExtensibleProviderSettingsMap | string
export type ProviderId = keyof ExtensibleProviderSettingsMap & string
// Provider类型注册工具
export interface ProviderTypeRegistrar {

View File

@ -1,7 +1,7 @@
import { loggerService } from '@logger'
import { createSelector } from '@reduxjs/toolkit'
import { EVENT_NAMES, EventEmitter } from '@renderer/services/EventService'
import { appendTrace, pauseTrace, restartTrace } from '@renderer/services/SpanManagerService'
import { appendMessageTrace, pauseTrace, restartTrace } from '@renderer/services/SpanManagerService'
import { estimateUserPromptUsage } from '@renderer/services/TokenService'
import store, { type RootState, useAppDispatch, useAppSelector } from '@renderer/store'
import { updateOneBlock } from '@renderer/store/messageBlock'
@ -178,7 +178,7 @@ export function useMessageOperations(topic: Topic) {
*/
const appendAssistantResponse = useCallback(
async (existingAssistantMessage: Message, newModel: Model, assistant: Assistant) => {
await appendTrace(existingAssistantMessage, newModel)
await appendMessageTrace(existingAssistantMessage, newModel)
if (existingAssistantMessage.role !== 'assistant') {
logger.error('appendAssistantResponse should only be called for an existing assistant message.')
return

View File

@ -89,8 +89,6 @@ export async function fetchChatCompletion({
}
onChunkReceived: (chunk: Chunk) => void
topicId?: string // 添加 topicId 参数
// TODO
// onChunkStatus: (status: 'searching' | 'processing' | 'success' | 'error') => void
}) {
logger.info('fetchChatCompletion called with detailed context', {
messageCount: messages?.length || 0,
@ -287,7 +285,6 @@ export async function fetchMessagesSummary({ messages, assistant }: { messages:
// 总结上下文总是取最后5条消息
const contextMessages = takeRight(messages, 5)
const provider = getProviderByModel(model)
if (!hasApiKey(provider)) {
@ -296,7 +293,7 @@ export async function fetchMessagesSummary({ messages, assistant }: { messages:
const AI = new AiProviderNew(model)
const topicId = messages?.find((message) => message.topicId)?.topicId || undefined
const topicId = messages?.find((message) => message.topicId)?.topicId || ''
// LLM对多条消息的总结有问题用单条结构化的消息表示会话内容会更好
const structredMessages = contextMessages.map((message) => {
@ -355,6 +352,15 @@ export async function fetchMessagesSummary({ messages, assistant }: { messages:
mcpTools: []
}
try {
// 从 messages 中找到有 traceId 的助手消息,用于绑定现有 trace
const messageWithTrace = messages.find((m) => m.role === 'assistant' && m.traceId)
if (messageWithTrace && messageWithTrace.traceId) {
// 导入并调用 appendTrace 来绑定现有 trace传入summary使用的模型名
const { appendTrace } = await import('@renderer/services/SpanManagerService')
await appendTrace({ topicId, traceId: messageWithTrace.traceId, model })
}
const { getText } = await AI.completionsForTrace(model.id, llmMessages, {
...middlewareConfig,
assistant: summaryAssistant,

View File

@ -97,7 +97,7 @@ class SpanManagerService {
window.api.trace.openWindow(message.topicId, message.traceId, false, modelName)
}
async appendTrace(message: Message, model: Model) {
async appendMessageTrace(message: Message, model: Model) {
if (!getEnableDeveloperMode()) {
return
}
@ -113,6 +113,29 @@ class SpanManagerService {
window.api.trace.openWindow(message.topicId, message.traceId, false, model.name)
}
async appendTrace({ topicId, traceId, model }: { topicId: string; traceId: string; model: Model }) {
if (!getEnableDeveloperMode()) {
return
}
if (!traceId) {
return
}
await window.api.trace.cleanHistory(topicId, traceId, model.name)
// const input = await this._getContentFromMessage(message)
await window.api.trace.bindTopic(topicId, traceId)
// 不使用 _addModelRootSpan直接创建简单的 span 来避免额外的模型层级
const entity = this.getModelSpanEntity(topicId, model.name)
const span = webTracer.startSpan('')
span['_spanContext'].traceId = traceId
entity.addSpan(span, true)
this._updateContext(span, topicId, traceId)
window.api.trace.openWindow(topicId, traceId, false, model.name)
}
private async _getContentFromMessage(message: Message, content?: string): Promise<StartSpanParams> {
let _content = content
if (!_content) {
@ -349,6 +372,7 @@ export const currentSpan = spanManagerService.getCurrentSpan.bind(spanManagerSer
export const addTokenUsage = spanManagerService.addTokenUsage.bind(spanManagerService)
export const pauseTrace = spanManagerService.finishModelTrace.bind(spanManagerService)
export const appendTrace = spanManagerService.appendTrace.bind(spanManagerService)
export const appendMessageTrace = spanManagerService.appendMessageTrace.bind(spanManagerService)
export const restartTrace = spanManagerService.restartTrace.bind(spanManagerService)
EventEmitter.on(EVENT_NAMES.SEND_MESSAGE, ({ topicId, traceId }) => {

View File

@ -1,6 +1,6 @@
import { TokenUsage } from '@mcp-trace/trace-core'
import { Span } from '@opentelemetry/api'
import { CompletionsResult } from '@renderer/aiCore/middleware/schemas'
import { CompletionsResult } from '@renderer/aiCore/legacy/middleware/schemas'
import { endSpan } from '@renderer/services/SpanManagerService'
export class CompletionsResultHandler {