mirror of
https://github.com/simstudioai/sim.git
synced 2026-04-28 03:00:29 -04:00
Add req id
This commit is contained in:
@@ -10,6 +10,7 @@ import {
|
||||
ModalContent,
|
||||
ModalFooter,
|
||||
ModalHeader,
|
||||
TagIcon,
|
||||
Textarea,
|
||||
ThumbsDown,
|
||||
ThumbsUp,
|
||||
@@ -46,13 +47,16 @@ interface MessageActionsProps {
|
||||
content: string
|
||||
chatId?: string
|
||||
userQuery?: string
|
||||
requestId?: string
|
||||
}
|
||||
|
||||
export function MessageActions({ content, chatId, userQuery }: MessageActionsProps) {
|
||||
export function MessageActions({ content, chatId, userQuery, requestId }: MessageActionsProps) {
|
||||
const [copied, setCopied] = useState(false)
|
||||
const [copiedRequestId, setCopiedRequestId] = useState(false)
|
||||
const [pendingFeedback, setPendingFeedback] = useState<'up' | 'down' | null>(null)
|
||||
const [feedbackText, setFeedbackText] = useState('')
|
||||
const resetTimeoutRef = useRef<number | null>(null)
|
||||
const requestIdTimeoutRef = useRef<number | null>(null)
|
||||
const submitFeedback = useSubmitCopilotFeedback()
|
||||
|
||||
useEffect(() => {
|
||||
@@ -60,6 +64,9 @@ export function MessageActions({ content, chatId, userQuery }: MessageActionsPro
|
||||
if (resetTimeoutRef.current !== null) {
|
||||
window.clearTimeout(resetTimeoutRef.current)
|
||||
}
|
||||
if (requestIdTimeoutRef.current !== null) {
|
||||
window.clearTimeout(requestIdTimeoutRef.current)
|
||||
}
|
||||
}
|
||||
}, [])
|
||||
|
||||
@@ -79,6 +86,20 @@ export function MessageActions({ content, chatId, userQuery }: MessageActionsPro
|
||||
}
|
||||
}, [content])
|
||||
|
||||
const copyRequestId = useCallback(async () => {
|
||||
if (!requestId) return
|
||||
try {
|
||||
await navigator.clipboard.writeText(requestId)
|
||||
setCopiedRequestId(true)
|
||||
if (requestIdTimeoutRef.current !== null) {
|
||||
window.clearTimeout(requestIdTimeoutRef.current)
|
||||
}
|
||||
requestIdTimeoutRef.current = window.setTimeout(() => setCopiedRequestId(false), 1500)
|
||||
} catch {
|
||||
/* clipboard unavailable */
|
||||
}
|
||||
}, [requestId])
|
||||
|
||||
const handleFeedbackClick = useCallback(
|
||||
(type: 'up' | 'down') => {
|
||||
if (chatId && userQuery) {
|
||||
@@ -144,6 +165,21 @@ export function MessageActions({ content, chatId, userQuery }: MessageActionsPro
|
||||
>
|
||||
<ThumbsDown className={ICON_CLASS} />
|
||||
</button>
|
||||
{requestId && (
|
||||
<button
|
||||
type='button'
|
||||
aria-label='Copy request ID'
|
||||
onClick={copyRequestId}
|
||||
className={BUTTON_CLASS}
|
||||
title={copiedRequestId ? 'Copied!' : 'Copy request ID'}
|
||||
>
|
||||
{copiedRequestId ? (
|
||||
<Check className={ICON_CLASS} />
|
||||
) : (
|
||||
<TagIcon className={ICON_CLASS} />
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<Modal open={pendingFeedback !== null} onOpenChange={handleModalClose}>
|
||||
|
||||
@@ -182,6 +182,7 @@ export function MothershipChat({
|
||||
content={msg.content}
|
||||
chatId={chatId}
|
||||
userQuery={precedingUserMsg?.content}
|
||||
requestId={msg.requestId}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -158,6 +158,10 @@ export interface StreamLoopOptions extends OrchestratorOptions {
|
||||
* Return true to skip the default handler for this event.
|
||||
*/
|
||||
onBeforeDispatch?: (event: StreamEvent, context: StreamingContext) => boolean | undefined
|
||||
/**
|
||||
* Called when the Go backend's trace ID (go_trace_id) is first received via SSE.
|
||||
*/
|
||||
onGoTraceId?: (goTraceId: string) => void
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -234,8 +238,12 @@ export async function runStreamLoop(
|
||||
|
||||
const streamEvent = eventToStreamEvent(raw)
|
||||
if (raw.trace?.requestId) {
|
||||
const prev = context.requestId
|
||||
context.requestId = raw.trace.requestId
|
||||
context.trace.setGoTraceId(raw.trace.requestId)
|
||||
if (raw.trace.requestId !== prev) {
|
||||
options.onGoTraceId?.(raw.trace.requestId)
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldSkipToolCallEvent(streamEvent) || shouldSkipToolResultEvent(streamEvent)) {
|
||||
|
||||
@@ -43,6 +43,7 @@ export interface CopilotLifecycleOptions extends OrchestratorOptions {
|
||||
goRoute?: string
|
||||
trace?: TraceCollector
|
||||
simRequestId?: string
|
||||
onGoTraceId?: (goTraceId: string) => void
|
||||
}
|
||||
|
||||
export async function runCopilotLifecycle(
|
||||
|
||||
@@ -143,6 +143,9 @@ export function createSSEStream(params: StreamingOrchestrationParams): ReadableS
|
||||
trace: collector,
|
||||
simRequestId: requestId,
|
||||
abortSignal: abortController.signal,
|
||||
onGoTraceId: (goTraceId) => {
|
||||
publisher.updateRequestId(goTraceId)
|
||||
},
|
||||
onEvent: async (event) => {
|
||||
await publisher.publish(event)
|
||||
},
|
||||
|
||||
@@ -22,7 +22,7 @@ export interface StreamWriterOptions {
|
||||
export class StreamWriter {
|
||||
private readonly streamId: string
|
||||
private readonly chatId: string | undefined
|
||||
private readonly requestId: string
|
||||
private requestId: string
|
||||
private readonly keepaliveMs: number
|
||||
private readonly flushIntervalMs: number
|
||||
private readonly flushMaxBatch: number
|
||||
@@ -55,6 +55,10 @@ export class StreamWriter {
|
||||
return this._sawComplete
|
||||
}
|
||||
|
||||
updateRequestId(id: string): void {
|
||||
this.requestId = id
|
||||
}
|
||||
|
||||
attach(controller: ReadableStreamDefaultController): void {
|
||||
this.controller = controller
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user