fix(stage-ui): cannot send message

This commit is contained in:
Neko Ayaka
2026-03-23 17:52:00 +08:00
parent a41b710154
commit b399308626
3 changed files with 33 additions and 12 deletions
@@ -18,5 +18,14 @@ export function createDatetimeContext(): ContextMessage {
strategy: ContextUpdateStrategy.ReplaceSelf,
text: `Current datetime: ${now.toISOString()} (${now.toLocaleString()})`,
createdAt: Date.now(),
metadata: {
source: {
id: DATETIME_CONTEXT_ID,
kind: 'plugin',
plugin: {
id: 'airi:system:datetime',
},
},
},
}
}
@@ -1,7 +1,7 @@
import type { ChatProvider } from '@xsai-ext/providers/utils'
import type { UserMessage } from '@xsai/shared-chat'
import type { ChatStreamEvent, ContextMessage } from '../../../types/chat'
import type { ChatStreamEvent, ChatStreamEventContext, ContextMessage } from '../../../types/chat'
import { isStageTamagotchi, isStageWeb } from '@proj-airi/stage-shared'
import { useBroadcastChannel } from '@vueuse/core'
@@ -19,6 +19,20 @@ import { useConsciousnessStore } from '../../modules/consciousness'
import { useProvidersStore } from '../../providers'
import { useModsServerChannelStore } from './channel-server'
export function normalizeContextSnapshot<C extends Pick<ChatStreamEventContext, 'contexts'>>(contexts: C): C {
return {
...contexts,
contexts: Object.fromEntries(
Object
.entries(toRaw(contexts.contexts))
.map(([key, ctx]) => [
key,
ctx.map(c => toRaw(c)),
]),
),
}
}
export const useContextBridgeStore = defineStore('mods:api:context-bridge', () => {
const mutex = new Mutex()
@@ -156,49 +170,49 @@ export const useContextBridgeStore = defineStore('mods:api:context-bridge', () =
if (isProcessingRemoteStream)
return
broadcastStreamEvent({ type: 'before-compose', message, sessionId: chatSession.activeSessionId, context: structuredClone(toRaw(context)) })
broadcastStreamEvent({ type: 'before-compose', message, sessionId: chatSession.activeSessionId, context: structuredClone(normalizeContextSnapshot(context)) })
}),
chatOrchestrator.onAfterMessageComposed(async (message, context) => {
if (isProcessingRemoteStream)
return
broadcastStreamEvent({ type: 'after-compose', message, sessionId: chatSession.activeSessionId, context: structuredClone(toRaw(context)) })
broadcastStreamEvent({ type: 'after-compose', message, sessionId: chatSession.activeSessionId, context: structuredClone(normalizeContextSnapshot(context)) })
}),
chatOrchestrator.onBeforeSend(async (message, context) => {
if (isProcessingRemoteStream)
return
broadcastStreamEvent({ type: 'before-send', message, sessionId: chatSession.activeSessionId, context: structuredClone(toRaw(context)) })
broadcastStreamEvent({ type: 'before-send', message, sessionId: chatSession.activeSessionId, context: structuredClone(normalizeContextSnapshot(context)) })
}),
chatOrchestrator.onAfterSend(async (message, context) => {
if (isProcessingRemoteStream)
return
broadcastStreamEvent({ type: 'after-send', message, sessionId: chatSession.activeSessionId, context: structuredClone(toRaw(context)) })
broadcastStreamEvent({ type: 'after-send', message, sessionId: chatSession.activeSessionId, context: structuredClone(normalizeContextSnapshot(context)) })
}),
chatOrchestrator.onTokenLiteral(async (literal, context) => {
if (isProcessingRemoteStream)
return
broadcastStreamEvent({ type: 'token-literal', literal, sessionId: chatSession.activeSessionId, context: structuredClone(toRaw(context)) })
broadcastStreamEvent({ type: 'token-literal', literal, sessionId: chatSession.activeSessionId, context: structuredClone(normalizeContextSnapshot(context)) })
}),
chatOrchestrator.onTokenSpecial(async (special, context) => {
if (isProcessingRemoteStream)
return
broadcastStreamEvent({ type: 'token-special', special, sessionId: chatSession.activeSessionId, context: structuredClone(toRaw(context)) })
broadcastStreamEvent({ type: 'token-special', special, sessionId: chatSession.activeSessionId, context: structuredClone(normalizeContextSnapshot(context)) })
}),
chatOrchestrator.onStreamEnd(async (context) => {
if (isProcessingRemoteStream)
return
broadcastStreamEvent({ type: 'stream-end', sessionId: chatSession.activeSessionId, context: structuredClone(toRaw(context)) })
broadcastStreamEvent({ type: 'stream-end', sessionId: chatSession.activeSessionId, context: structuredClone(normalizeContextSnapshot(context)) })
}),
chatOrchestrator.onAssistantResponseEnd(async (message, context) => {
if (isProcessingRemoteStream)
return
broadcastStreamEvent({ type: 'assistant-end', message, sessionId: chatSession.activeSessionId, context: structuredClone(toRaw(context)) })
broadcastStreamEvent({ type: 'assistant-end', message, sessionId: chatSession.activeSessionId, context: structuredClone(normalizeContextSnapshot(context)) })
}),
chatOrchestrator.onAssistantMessage(async (message, _messageText, context) => {
+1 -3
View File
@@ -3,7 +3,6 @@ import type { MetadataEventSource } from '@proj-airi/server-sdk'
interface EventSourcePayload {
source?: string
metadata?: { source?: MetadataEventSource }
eventMetadata?: { source?: MetadataEventSource }
}
function formatMetadataSource(source?: MetadataEventSource) {
@@ -18,8 +17,7 @@ function formatMetadataSource(source?: MetadataEventSource) {
export function getEventSourceKey(event: EventSourcePayload, fallback = 'unknown') {
return (
formatMetadataSource(event.eventMetadata?.source)
?? formatMetadataSource(event.metadata?.source)
formatMetadataSource(event.metadata?.source)
?? event.source
?? fallback
)