[Haik]: pt3 of going thru knip errors

This commit is contained in:
haikdc
2026-03-30 23:51:05 -07:00
parent 0dd56bb599
commit 30a0dc5a6f
23 changed files with 75 additions and 725 deletions
@@ -2,7 +2,7 @@ import React from 'react';
import Box from '@mui/material/Box';
import Tooltip from '@mui/material/Tooltip';
export function formatTokenCount(n: number): string {
function formatTokenCount(n: number): string {
if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;
if (n >= 1_000) return `${(n / 1_000).toFixed(1)}K`;
return String(n);
@@ -10,7 +10,7 @@ import { useComposerAttachments } from './useComposerAttachments';
import { MentionSelectOverride, MentionPopover, ComposerAttachmentChips } from './ComposerParts';
import ModelModeSelector from '../ModelModeSelector';
export interface OpenSwarmComposerProps {
interface OpenSwarmComposerProps {
composerExtrasRef: MutableRefObject<ComposerExtras>;
mode: string;
onModeChange: (mode: string) => void;
@@ -2,19 +2,19 @@ import { useState, useCallback, useRef } from 'react';
import { API_BASE } from '@/shared/config';
import type { ContextPath } from '@/app/components/DirectoryBrowser';
export interface AttachedImage {
interface AttachedImage {
data: string;
media_type: string;
preview: string;
}
export interface ForcedToolGroup {
interface ForcedToolGroup {
label: string;
tools: string[];
iconKey?: string;
}
export interface AttachedSkill {
interface AttachedSkill {
id: string;
name: string;
content: string;
@@ -1,58 +0,0 @@
import { useMemo, type MutableRefObject } from 'react';
import { useAui } from '@assistant-ui/react';
import type { ContextPath } from '@/app/components/DirectoryBrowser';
import type { ComposerExtras } from '../runtime/useOpenSwarmRuntime';
export interface ForcedToolGroup {
label: string;
tools: string[];
iconKey?: string;
}
export interface ComposerHandle {
getConfig: () => {
prompt: string;
contextPaths: ContextPath[];
forcedTools: ForcedToolGroup[];
};
setContent: (
prompt: string,
contextPaths?: ContextPath[],
forcedTools?: ForcedToolGroup[],
) => void;
}
/**
* Provides a ChatInputHandle-compatible interface backed by the assistant-ui
* ComposerRuntime and a shared ComposerExtras ref.
*
* Agent 7 can wire this into useAgentChat to replace the old chatInputRef.
*/
export function useComposerHandle(
composerExtrasRef: MutableRefObject<ComposerExtras>,
): ComposerHandle {
const aui = useAui();
return useMemo<ComposerHandle>(
() => ({
getConfig: () => {
const text = aui.composer().getState().text;
const extras = composerExtrasRef.current;
const contextPaths: ContextPath[] = (extras.contextPaths ?? []) as ContextPath[];
const forcedTools: ForcedToolGroup[] = extras.forcedTools
? extras.forcedTools.map((t) => ({ label: t, tools: [t] }))
: [];
return { prompt: text, contextPaths, forcedTools };
},
setContent: (prompt, contextPaths, forcedTools) => {
aui.composer().setText(prompt);
composerExtrasRef.current = {
...composerExtrasRef.current,
contextPaths: contextPaths as ComposerExtras['contextPaths'],
forcedTools: forcedTools?.flatMap((g) => g.tools),
};
},
}),
[aui, composerExtrasRef],
);
}
@@ -12,7 +12,7 @@ import {
import type { AttachedImage } from '../ImageAttachments';
import type { ForcedToolGroup } from '../AttachmentChips';
export interface ChatSubmitParams {
interface ChatSubmitParams {
editorRef: React.RefObject<HTMLDivElement | null>; attachedSkillsRef: React.MutableRefObject<Record<string, AttachedSkill>>;
generalFileInputRef: React.RefObject<HTMLInputElement | null>;
disabled?: boolean; autoRunMode?: boolean; images: AttachedImage[]; contextPaths: ContextPath[];
@@ -30,7 +30,7 @@ export interface DispatchableMessage {
selectedBrowserIds?: string[];
}
export interface RuntimeOptions {
interface RuntimeOptions {
composerExtrasRef?: MutableRefObject<ComposerExtras>;
dispatchMessage?: (msg: DispatchableMessage) => void;
}
@@ -20,7 +20,7 @@ const BranchChatContext = createContext<
>(undefined);
export const useBranchChatCallback = () => useContext(BranchChatContext);
export interface OpenSwarmThreadProps {
interface OpenSwarmThreadProps {
sessionId?: string;
onBranchChat?: (newSessionId: string) => void;
children?: ReactNode;
@@ -1,54 +1,16 @@
import type { ReactNode } from 'react';
import type { Toolkit } from '@assistant-ui/react';
import { MessageDraft } from '@/components/tool-ui/message-draft';
import { DataTable } from '@/components/tool-ui/data-table';
import { DataTable } from '@/components/tool-ui/data-table/data-table';
import {
parseMcpToolName, getGmailHeader, formatTimestamp, stripHtml,
getGmailHeader, formatTimestamp, stripHtml,
} from '../toolCallUtils';
export { BrowserFeedTracker } from './mcp-browser-feed';
// -- Helpers ----------------------------------------------------------------
/** Unwrap MCP result (string / content-block array / object) into data. */
export function extractMcpData(result: unknown): Record<string, any> {
if (result == null) return {};
let text: string | undefined;
if (typeof result === 'string') {
text = result;
} else if (typeof result === 'object') {
const r = result as Record<string, unknown>;
for (const k of ['text', 'output', 'content', 'result']) {
if (typeof r[k] === 'string') { text = r[k] as string; break; }
}
if (text === undefined) return result as Record<string, any>;
} else {
return {};
}
if (!text) return {};
try {
let parsed = JSON.parse(text);
if (
Array.isArray(parsed) &&
parsed.some((b: any) => b?.type === 'text' && typeof b?.text === 'string')
) {
const joined = parsed
.filter((b: any) => b?.type === 'text')
.map((b: any) => b.text)
.join('\n');
try { parsed = JSON.parse(joined); } catch { return {}; }
}
if (typeof parsed === 'object' && parsed !== null) return parsed;
} catch { /* not JSON */ }
return {};
}
export function extractEmailFields(msg: any) {
function extractEmailFields(msg: any) {
const subject = msg.subject || getGmailHeader(msg, 'Subject') || '(no subject)';
const from = msg.from || msg.sender || getGmailHeader(msg, 'From') || '';
const to = msg.to || msg.recipient || getGmailHeader(msg, 'To') || '';
@@ -210,15 +172,6 @@ export function renderParsedMcpData(
}
}
/** Full MCP dispatch — parses raw tool name + result, routes to renderer. */
export function renderMcpResult(
toolName: string, result: unknown, toolCallId: string,
): ReactNode | null {
const mcpInfo = parseMcpToolName(toolName);
const data = extractMcpData(result);
return renderParsedMcpData(mcpInfo.service, mcpInfo.action, data, toolCallId);
}
// -- Exported toolkit (empty — MCP tool names are dynamic; Agent 7 wires) ---
export const mcpToolkit: Partial<Toolkit> = {};
+4 -4
View File
@@ -14,14 +14,14 @@ import DeleteOutlineIcon from '@mui/icons-material/DeleteOutline';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
import { useClaudeTokens } from '@/shared/styles/ThemeContext';
export interface FileTreeNode {
interface FileTreeNode {
name: string;
path: string;
isDir: boolean;
children?: FileTreeNode[];
}
export function getFileIcon(filename: string): React.ReactNode {
function getFileIcon(filename: string): React.ReactNode {
const ext = filename.split('.').pop()?.toLowerCase();
const size = 15;
switch (ext) {
@@ -74,7 +74,7 @@ export function buildFileTree(filePaths: string[]): FileTreeNode[] {
return root;
}
export interface FileTreeItemProps {
interface FileTreeItemProps {
node: FileTreeNode;
depth: number;
activeFile: string;
@@ -83,7 +83,7 @@ export interface FileTreeItemProps {
c: ReturnType<typeof useClaudeTokens>;
}
export const PROTECTED_FILES = new Set(['index.html', 'schema.json', 'meta.json', 'SKILL.md']);
const PROTECTED_FILES = new Set(['index.html', 'schema.json', 'meta.json', 'SKILL.md']);
export const FileTreeItem: React.FC<FileTreeItemProps> = ({ node, depth, activeFile, onSelect, onDelete, c }) => {
const [open, setOpen] = useState(true);