Inital commit
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
import { memo, useState } from "react";
|
||||
import { Pressable, StyleSheet, Text, View } from "react-native";
|
||||
import { colors, monoFont } from "@/lib/theme";
|
||||
|
||||
type Props = {
|
||||
toolName: string;
|
||||
status: "running" | "done" | "error";
|
||||
argsPreview?: string;
|
||||
detail?: string;
|
||||
};
|
||||
|
||||
const STATUS_COLOR: Record<Props["status"], string> = {
|
||||
running: colors.warning,
|
||||
done: colors.success,
|
||||
error: colors.error,
|
||||
};
|
||||
|
||||
function ToolCallCardComponent({ toolName, status, argsPreview, detail }: Props) {
|
||||
const [expanded, setExpanded] = useState(false);
|
||||
const output = detail?.trim() ?? "";
|
||||
const expandable = output.length > 0;
|
||||
|
||||
return (
|
||||
<Pressable
|
||||
style={styles.container}
|
||||
onPress={expandable ? () => setExpanded((value) => !value) : undefined}
|
||||
>
|
||||
<View style={styles.header}>
|
||||
<Text style={[styles.prompt, { color: STATUS_COLOR[status] }]}>
|
||||
{status === "error" ? "✕" : "❯"}
|
||||
</Text>
|
||||
<Text style={styles.name} numberOfLines={1}>
|
||||
{toolName}
|
||||
</Text>
|
||||
{argsPreview ? (
|
||||
<Text style={styles.args} numberOfLines={1}>
|
||||
{argsPreview}
|
||||
</Text>
|
||||
) : (
|
||||
<View style={styles.spacer} />
|
||||
)}
|
||||
{status === "running" ? <Text style={styles.statusLabel}>running…</Text> : null}
|
||||
{expandable ? <Text style={styles.chevron}>{expanded ? "−" : "+"}</Text> : null}
|
||||
</View>
|
||||
|
||||
{expandable ? (
|
||||
<View style={styles.outputWrap}>
|
||||
{expanded ? (
|
||||
<Text style={styles.output} selectable>
|
||||
{output}
|
||||
</Text>
|
||||
) : (
|
||||
<Text style={styles.outputPreview} numberOfLines={2}>
|
||||
{output}
|
||||
</Text>
|
||||
)}
|
||||
</View>
|
||||
) : null}
|
||||
</Pressable>
|
||||
);
|
||||
}
|
||||
|
||||
export const ToolCallCard = memo(ToolCallCardComponent);
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
alignSelf: "stretch",
|
||||
paddingVertical: 2,
|
||||
gap: 4,
|
||||
},
|
||||
header: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
gap: 8,
|
||||
},
|
||||
prompt: {
|
||||
fontFamily: monoFont,
|
||||
fontSize: 12,
|
||||
fontWeight: "700",
|
||||
},
|
||||
name: {
|
||||
color: colors.textSecondary,
|
||||
fontFamily: monoFont,
|
||||
fontSize: 13,
|
||||
fontWeight: "600",
|
||||
},
|
||||
args: {
|
||||
flex: 1,
|
||||
color: colors.textMuted,
|
||||
fontFamily: monoFont,
|
||||
fontSize: 12,
|
||||
},
|
||||
spacer: {
|
||||
flex: 1,
|
||||
},
|
||||
statusLabel: {
|
||||
color: colors.warning,
|
||||
fontFamily: monoFont,
|
||||
fontSize: 11,
|
||||
},
|
||||
chevron: {
|
||||
color: colors.textMuted,
|
||||
fontFamily: monoFont,
|
||||
fontSize: 13,
|
||||
},
|
||||
outputWrap: {
|
||||
borderLeftWidth: 1,
|
||||
borderLeftColor: colors.borderSubtle,
|
||||
marginLeft: 4,
|
||||
paddingLeft: 10,
|
||||
},
|
||||
output: {
|
||||
color: colors.textSecondary,
|
||||
fontFamily: monoFont,
|
||||
fontSize: 12,
|
||||
lineHeight: 17,
|
||||
},
|
||||
outputPreview: {
|
||||
color: colors.textMuted,
|
||||
fontFamily: monoFont,
|
||||
fontSize: 12,
|
||||
lineHeight: 17,
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user