refactor: 清理 P1 类型债与 React key 债
- 消除 useChat.ts 中 13 处 (message as any).timestamp,改用已收窄变量的 .timestamp
- 给 ExecutionCancelled 接口补 timestamp?: number 字段,与后端对齐
- 修复 MessageInput 附件列表 key={index}: 给 FileAttachment 加 id 字段(crypto.randomUUID())
- 修复 ConfigPage TagEditor key={i} → key={t}(tag 值唯一)
- 修复 ConfigPage SourceEditor customPaths key={i} → key={p}(路径值唯一)
This commit is contained in:
parent
7eb2933ca5
commit
f8d5f0253a
@ -16,6 +16,7 @@ interface MessageInputProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface FileAttachment {
|
interface FileAttachment {
|
||||||
|
id: string
|
||||||
file: File
|
file: File
|
||||||
attachment: Attachment
|
attachment: Attachment
|
||||||
preview?: string // 用于图片预览
|
preview?: string // 用于图片预览
|
||||||
@ -92,6 +93,7 @@ export function MessageInput({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const fileAttachment: FileAttachment = {
|
const fileAttachment: FileAttachment = {
|
||||||
|
id: crypto.randomUUID(),
|
||||||
file,
|
file,
|
||||||
attachment,
|
attachment,
|
||||||
preview: mediaType === 'image' ? base64 : undefined,
|
preview: mediaType === 'image' ? base64 : undefined,
|
||||||
@ -170,6 +172,7 @@ export function MessageInput({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const fileAttachment: FileAttachment = {
|
const fileAttachment: FileAttachment = {
|
||||||
|
id: crypto.randomUUID(),
|
||||||
file,
|
file,
|
||||||
attachment,
|
attachment,
|
||||||
preview: mediaType === 'image' ? base64 : undefined,
|
preview: mediaType === 'image' ? base64 : undefined,
|
||||||
@ -295,7 +298,7 @@ export function MessageInput({
|
|||||||
<div className="mb-2 flex flex-wrap gap-2">
|
<div className="mb-2 flex flex-wrap gap-2">
|
||||||
{attachments.map((att, index) => (
|
{attachments.map((att, index) => (
|
||||||
<div
|
<div
|
||||||
key={index}
|
key={att.id}
|
||||||
className="flex items-center gap-2 rounded-lg border border-[var(--border-color)] bg-[var(--bg-tertiary)] px-2 py-1.5 text-sm"
|
className="flex items-center gap-2 rounded-lg border border-[var(--border-color)] bg-[var(--bg-tertiary)] px-2 py-1.5 text-sm"
|
||||||
>
|
>
|
||||||
{att.preview ? (
|
{att.preview ? (
|
||||||
|
|||||||
@ -192,7 +192,7 @@ function TagEditor({ tags, onChange }: { tags: string[]; onChange: (t: string[])
|
|||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<div className="flex flex-wrap gap-1.5">
|
<div className="flex flex-wrap gap-1.5">
|
||||||
{tags.map((t, i) => (
|
{tags.map((t, i) => (
|
||||||
<span key={i} className="inline-flex items-center gap-1 px-2 py-0.5 rounded-md bg-[var(--accent-cyan)]/10 border border-[var(--accent-cyan)]/20 text-xs text-[var(--accent-cyan)]">
|
<span key={t} className="inline-flex items-center gap-1 px-2 py-0.5 rounded-md bg-[var(--accent-cyan)]/10 border border-[var(--accent-cyan)]/20 text-xs text-[var(--accent-cyan)]">
|
||||||
{t}
|
{t}
|
||||||
<button onClick={() => onChange(tags.filter((_, j) => j !== i))} className="hover:text-white transition-colors"><X className="h-3 w-3" /></button>
|
<button onClick={() => onChange(tags.filter((_, j) => j !== i))} className="hover:text-white transition-colors"><X className="h-3 w-3" /></button>
|
||||||
</span>
|
</span>
|
||||||
@ -286,8 +286,8 @@ function SourceEditor({
|
|||||||
<div className="text-xs font-medium text-[var(--text-muted)] uppercase tracking-wider">自定义路径</div>
|
<div className="text-xs font-medium text-[var(--text-muted)] uppercase tracking-wider">自定义路径</div>
|
||||||
{customPaths.length > 0 && (
|
{customPaths.length > 0 && (
|
||||||
<div className="flex flex-wrap gap-1.5">
|
<div className="flex flex-wrap gap-1.5">
|
||||||
{customPaths.map((p, i) => (
|
{customPaths.map((p) => (
|
||||||
<span key={i} className="inline-flex items-center gap-1 px-2 py-0.5 rounded-md bg-[var(--accent-cyan)]/10 border border-[var(--accent-cyan)]/20 text-xs text-[var(--accent-cyan)] font-mono">
|
<span key={p} className="inline-flex items-center gap-1 px-2 py-0.5 rounded-md bg-[var(--accent-cyan)]/10 border border-[var(--accent-cyan)]/20 text-xs text-[var(--accent-cyan)] font-mono">
|
||||||
{p}
|
{p}
|
||||||
<button onClick={() => removeCustom(p)} className="hover:text-white transition-colors"><X className="h-3 w-3" /></button>
|
<button onClick={() => removeCustom(p)} className="hover:text-white transition-colors"><X className="h-3 w-3" /></button>
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@ -236,7 +236,7 @@ export function useChat(): UseChatReturn {
|
|||||||
id: msg.id,
|
id: msg.id,
|
||||||
role: role as ChatMessage['role'],
|
role: role as ChatMessage['role'],
|
||||||
content: msg.content,
|
content: msg.content,
|
||||||
timestamp: (message as any).timestamp ?? Math.floor(Date.now() / 1000),
|
timestamp: msg.timestamp ?? Math.floor(Date.now() / 1000),
|
||||||
type: 'message',
|
type: 'message',
|
||||||
attachments: msg.attachments,
|
attachments: msg.attachments,
|
||||||
subagentTaskId: msg.subagent_task_id,
|
subagentTaskId: msg.subagent_task_id,
|
||||||
@ -249,7 +249,7 @@ export function useChat(): UseChatReturn {
|
|||||||
id: msg.id,
|
id: msg.id,
|
||||||
role: 'tool',
|
role: 'tool',
|
||||||
content: msg.content,
|
content: msg.content,
|
||||||
timestamp: (message as any).timestamp ?? Math.floor(Date.now() / 1000),
|
timestamp: msg.timestamp ?? Math.floor(Date.now() / 1000),
|
||||||
type: 'tool_call',
|
type: 'tool_call',
|
||||||
toolName: msg.tool_name,
|
toolName: msg.tool_name,
|
||||||
toolCallId: msg.tool_call_id,
|
toolCallId: msg.tool_call_id,
|
||||||
@ -264,7 +264,7 @@ export function useChat(): UseChatReturn {
|
|||||||
id: msg.id,
|
id: msg.id,
|
||||||
role: 'tool',
|
role: 'tool',
|
||||||
content: msg.content,
|
content: msg.content,
|
||||||
timestamp: (message as any).timestamp ?? Math.floor(Date.now() / 1000),
|
timestamp: msg.timestamp ?? Math.floor(Date.now() / 1000),
|
||||||
type: 'tool_result',
|
type: 'tool_result',
|
||||||
toolName: msg.tool_name,
|
toolName: msg.tool_name,
|
||||||
toolCallId: msg.tool_call_id,
|
toolCallId: msg.tool_call_id,
|
||||||
@ -278,7 +278,7 @@ export function useChat(): UseChatReturn {
|
|||||||
id: msg.id,
|
id: msg.id,
|
||||||
role: 'tool',
|
role: 'tool',
|
||||||
content: `${msg.content}\n\n${msg.resume_hint}`,
|
content: `${msg.content}\n\n${msg.resume_hint}`,
|
||||||
timestamp: (message as any).timestamp ?? Math.floor(Date.now() / 1000),
|
timestamp: msg.timestamp ?? Math.floor(Date.now() / 1000),
|
||||||
type: 'tool_pending',
|
type: 'tool_pending',
|
||||||
toolName: msg.tool_name,
|
toolName: msg.tool_name,
|
||||||
toolCallId: msg.tool_call_id,
|
toolCallId: msg.tool_call_id,
|
||||||
@ -302,7 +302,7 @@ export function useChat(): UseChatReturn {
|
|||||||
id: generateMessageId(),
|
id: generateMessageId(),
|
||||||
role: 'assistant',
|
role: 'assistant',
|
||||||
content: `Error: ${message.message}`,
|
content: `Error: ${message.message}`,
|
||||||
timestamp: (message as any).timestamp ?? Math.floor(Date.now() / 1000),
|
timestamp: message.timestamp ?? Math.floor(Date.now() / 1000),
|
||||||
type: 'message',
|
type: 'message',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -362,7 +362,7 @@ export function useChat(): UseChatReturn {
|
|||||||
id: generateMessageId(),
|
id: generateMessageId(),
|
||||||
role: 'assistant',
|
role: 'assistant',
|
||||||
content: `Error: ${errMsg.message}`,
|
content: `Error: ${errMsg.message}`,
|
||||||
timestamp: (message as any).timestamp ?? Math.floor(Date.now() / 1000),
|
timestamp: errMsg.timestamp ?? Math.floor(Date.now() / 1000),
|
||||||
type: 'message',
|
type: 'message',
|
||||||
}
|
}
|
||||||
setSubAgentStack((prev) => {
|
setSubAgentStack((prev) => {
|
||||||
@ -423,7 +423,7 @@ export function useChat(): UseChatReturn {
|
|||||||
id: generateMessageId(),
|
id: generateMessageId(),
|
||||||
role: 'assistant',
|
role: 'assistant',
|
||||||
content: `Error: ${errMsg.message}`,
|
content: `Error: ${errMsg.message}`,
|
||||||
timestamp: (message as any).timestamp ?? Math.floor(Date.now() / 1000),
|
timestamp: errMsg.timestamp ?? Math.floor(Date.now() / 1000),
|
||||||
type: 'message',
|
type: 'message',
|
||||||
}
|
}
|
||||||
const newStack = [...prev]
|
const newStack = [...prev]
|
||||||
@ -800,7 +800,7 @@ export function useChat(): UseChatReturn {
|
|||||||
id: msg.id,
|
id: msg.id,
|
||||||
role,
|
role,
|
||||||
content: msg.content,
|
content: msg.content,
|
||||||
timestamp: (message as any).timestamp ?? Math.floor(Date.now() / 1000),
|
timestamp: msg.timestamp ?? Math.floor(Date.now() / 1000),
|
||||||
type: 'message',
|
type: 'message',
|
||||||
attachments: msg.attachments,
|
attachments: msg.attachments,
|
||||||
reasoningContent: msg.reasoning_content,
|
reasoningContent: msg.reasoning_content,
|
||||||
@ -833,7 +833,7 @@ export function useChat(): UseChatReturn {
|
|||||||
id: msg.id,
|
id: msg.id,
|
||||||
role: 'tool',
|
role: 'tool',
|
||||||
content: msg.content,
|
content: msg.content,
|
||||||
timestamp: (message as any).timestamp ?? Math.floor(Date.now() / 1000),
|
timestamp: msg.timestamp ?? Math.floor(Date.now() / 1000),
|
||||||
type: 'tool_call',
|
type: 'tool_call',
|
||||||
toolName: msg.tool_name,
|
toolName: msg.tool_name,
|
||||||
toolCallId: msg.tool_call_id,
|
toolCallId: msg.tool_call_id,
|
||||||
@ -856,7 +856,7 @@ export function useChat(): UseChatReturn {
|
|||||||
id: msg.id,
|
id: msg.id,
|
||||||
role: 'tool',
|
role: 'tool',
|
||||||
content: msg.content,
|
content: msg.content,
|
||||||
timestamp: (message as any).timestamp ?? Math.floor(Date.now() / 1000),
|
timestamp: msg.timestamp ?? Math.floor(Date.now() / 1000),
|
||||||
type: 'tool_result',
|
type: 'tool_result',
|
||||||
toolName: msg.tool_name,
|
toolName: msg.tool_name,
|
||||||
toolCallId: msg.tool_call_id,
|
toolCallId: msg.tool_call_id,
|
||||||
@ -877,7 +877,7 @@ export function useChat(): UseChatReturn {
|
|||||||
id: msg.id,
|
id: msg.id,
|
||||||
role: 'tool',
|
role: 'tool',
|
||||||
content: `${msg.content}\n\n${msg.resume_hint}`,
|
content: `${msg.content}\n\n${msg.resume_hint}`,
|
||||||
timestamp: (message as any).timestamp ?? Math.floor(Date.now() / 1000),
|
timestamp: msg.timestamp ?? Math.floor(Date.now() / 1000),
|
||||||
type: 'tool_pending',
|
type: 'tool_pending',
|
||||||
toolName: msg.tool_name,
|
toolName: msg.tool_name,
|
||||||
toolCallId: msg.tool_call_id,
|
toolCallId: msg.tool_call_id,
|
||||||
@ -893,7 +893,7 @@ export function useChat(): UseChatReturn {
|
|||||||
id: generateMessageId(),
|
id: generateMessageId(),
|
||||||
role: 'assistant',
|
role: 'assistant',
|
||||||
content: (message as { type: 'execution_cancelled'; message: string }).message,
|
content: (message as { type: 'execution_cancelled'; message: string }).message,
|
||||||
timestamp: (message as any).timestamp ?? Math.floor(Date.now() / 1000),
|
timestamp: message.timestamp ?? Math.floor(Date.now() / 1000),
|
||||||
type: 'message',
|
type: 'message',
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
@ -910,7 +910,7 @@ export function useChat(): UseChatReturn {
|
|||||||
id: generateMessageId(),
|
id: generateMessageId(),
|
||||||
role: 'assistant',
|
role: 'assistant',
|
||||||
content: `Error: ${message.message}`,
|
content: `Error: ${message.message}`,
|
||||||
timestamp: (message as any).timestamp ?? Math.floor(Date.now() / 1000),
|
timestamp: message.timestamp ?? Math.floor(Date.now() / 1000),
|
||||||
type: 'message',
|
type: 'message',
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
|||||||
@ -260,6 +260,7 @@ export interface TaskMessagesLoaded {
|
|||||||
export interface ExecutionCancelled {
|
export interface ExecutionCancelled {
|
||||||
type: 'execution_cancelled'
|
type: 'execution_cancelled'
|
||||||
message: string
|
message: string
|
||||||
|
timestamp?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface StreamDelta {
|
export interface StreamDelta {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user