refactor: replace any types with proper TypeScript types across gateway client, hooks, and components
- Add GatewayMessage and JsonPayload interfaces to gateway.ts - Type WebSocket message parsing with GatewayMessage instead of any - Use ReturnType<typeof setTimeout> for timer refs - Type chat event payload destructuring explicitly - Add ChatPayloadMessage interface for extractText() - Replace any casts in loadSessions/loadHistory with typed assertions - Add str() helper in ToolCall.tsx for safe unknown→string extraction - Use Extract<MessageBlock, ...> type guards instead of `as any` casts - Type CodeBlock children prop properly
This commit is contained in:
@@ -148,7 +148,7 @@ function renderTextBlocks(blocks: MessageBlock[]) {
|
||||
return getTextBlocks(blocks).map((block, i) => (
|
||||
<div key={`text-${i}`} className="markdown-body">
|
||||
<ReactMarkdown remarkPlugins={[remarkGfm, remarkBreaks]} rehypePlugins={[rehypeHighlight]} components={markdownComponents}>
|
||||
{autoFormatText((block as any).text)}
|
||||
{autoFormatText((block as Extract<MessageBlock, { type: 'text' }>).text)}
|
||||
</ReactMarkdown>
|
||||
</div>
|
||||
));
|
||||
@@ -238,7 +238,7 @@ function CopyButton({ text }: { text: string }) {
|
||||
/** Extract plain text from message blocks for clipboard copy */
|
||||
function getPlainText(message: ChatMessageType): string {
|
||||
if (message.blocks.length > 0) {
|
||||
return getTextBlocks(message.blocks).map(b => (b as any).text).join('\n\n');
|
||||
return getTextBlocks(message.blocks).map(b => (b as Extract<MessageBlock, { type: 'text' }>).text).join('\n\n');
|
||||
}
|
||||
return message.content;
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ export function CodeBlock(props: HTMLAttributes<HTMLPreElement>) {
|
||||
|
||||
const handleCopy = useCallback(() => {
|
||||
// Extract text from the nested <code> element
|
||||
const code = (props.children as any)?.props?.children;
|
||||
const code = (props.children as React.ReactElement<{ children?: string }> | undefined)?.props?.children;
|
||||
if (typeof code === 'string') {
|
||||
navigator.clipboard.writeText(code).then(() => {
|
||||
setCopied(true);
|
||||
|
||||
@@ -122,33 +122,40 @@ export function HighlightedPre({ text, className }: { text: string; className: s
|
||||
return <pre className={className}>{text}</pre>;
|
||||
}
|
||||
|
||||
function getContextHint(name: string, input: any): string | null {
|
||||
function str(v: unknown): string | null {
|
||||
return typeof v === 'string' ? v : null;
|
||||
}
|
||||
|
||||
function getContextHint(name: string, input: Record<string, unknown> | undefined): string | null {
|
||||
if (!input || typeof input !== 'object') return null;
|
||||
switch (name) {
|
||||
case 'exec':
|
||||
return input.command ? truncate(input.command, 60) : null;
|
||||
return str(input.command) ? truncate(str(input.command)!, 60) : null;
|
||||
case 'Read': case 'read':
|
||||
case 'Write': case 'write':
|
||||
case 'Edit': case 'edit':
|
||||
return input.file_path || input.path || null;
|
||||
return str(input.file_path) || str(input.path) || null;
|
||||
case 'web_search':
|
||||
return input.query ? truncate(input.query, 50) : null;
|
||||
return str(input.query) ? truncate(str(input.query)!, 50) : null;
|
||||
case 'web_fetch':
|
||||
return input.url ? truncate(input.url, 60) : null;
|
||||
return str(input.url) ? truncate(str(input.url)!, 60) : null;
|
||||
case 'browser':
|
||||
return input.action || null;
|
||||
case 'message':
|
||||
return input.action ? `${input.action}${input.target ? ' → ' + input.target : ''}` : null;
|
||||
return str(input.action) || null;
|
||||
case 'message': {
|
||||
const action = str(input.action);
|
||||
const target = str(input.target);
|
||||
return action ? `${action}${target ? ' → ' + target : ''}` : null;
|
||||
}
|
||||
case 'memory_search':
|
||||
return input.query ? truncate(input.query, 50) : null;
|
||||
return str(input.query) ? truncate(str(input.query)!, 50) : null;
|
||||
case 'memory_get':
|
||||
return input.path || null;
|
||||
return str(input.path) || null;
|
||||
case 'cron':
|
||||
return input.action || null;
|
||||
return str(input.action) || null;
|
||||
case 'sessions_spawn':
|
||||
return input.task ? truncate(input.task, 50) : null;
|
||||
return str(input.task) ? truncate(str(input.task)!, 50) : null;
|
||||
case 'image':
|
||||
return input.prompt ? truncate(input.prompt, 50) : null;
|
||||
return str(input.prompt) ? truncate(str(input.prompt)!, 50) : null;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
@@ -184,7 +191,7 @@ function extractImageFromResult(result: string): { src: string; remaining: strin
|
||||
return null;
|
||||
}
|
||||
|
||||
export function ToolCall({ name, input, result }: { name: string; input?: any; result?: string }) {
|
||||
export function ToolCall({ name, input, result }: { name: string; input?: Record<string, unknown>; result?: string }) {
|
||||
const t = useT();
|
||||
const [open, setOpen] = useState(false);
|
||||
const c = getColor(name);
|
||||
|
||||
Reference in New Issue
Block a user