import React, { useEffect, useState } from 'react';
import { View, Text, TextInput, Button, ScrollView } from 'react-native';
import { useLLM } from 'react-native-executorch';
import { LLAMA3_2_3B } from 'react-native-executorch/constants';
function CalculatorAssistant() {
const [input, setInput] = useState('');
const llm = useLLM({ model: LLAMA3_2_3B });
useEffect(() => {
if (llm.isReady) {
llm.configure({
chatConfig: {
systemPrompt: 'You are a helpful math assistant. Use the calculator tool to perform precise calculations.',
},
toolsConfig: {
tools: [
{
type: 'function',
function: {
name: 'calculate',
description: 'Perform a mathematical calculation',
parameters: {
type: 'object',
properties: {
expression: {
type: 'string',
description: 'Mathematical expression to evaluate, e.g. "2 + 2" or "sqrt(16)"',
},
},
required: ['expression'],
},
},
},
{
type: 'function',
function: {
name: 'get_constant',
description: 'Get the value of a mathematical constant',
parameters: {
type: 'object',
properties: {
constant: {
type: 'string',
enum: ['pi', 'e', 'phi', 'sqrt2'],
description: 'The mathematical constant to retrieve',
},
},
required: ['constant'],
},
},
},
],
executeToolCallback: async (toolCall) => {
try {
if (toolCall.toolName === 'calculate') {
const { expression } = toolCall.arguments;
// In production, use a safe math evaluator library
const result = eval(expression); // CAUTION: eval is dangerous, use math.js or similar
return `The result of ${expression} is ${result}`;
}
if (toolCall.toolName === 'get_constant') {
const { constant } = toolCall.arguments;
const constants = {
pi: Math.PI,
e: Math.E,
phi: 1.618033988749895,
sqrt2: Math.SQRT2,
};
return `The value of ${constant} is ${constants[constant]}`;
}
return 'Unknown tool';
} catch (error) {
return `Error executing tool: ${error.message}`;
}
},
displayToolCalls: false, // Hide internal tool calls
},
});
}
}, [llm.isReady]);
const handleSend = async () => {
if (input.trim() && !llm.isGenerating) {
const message = input;
setInput('');
await llm.sendMessage(message);
}
};
return (
<View style={{ flex: 1, padding: 20 }}>
<ScrollView style={{ flex: 1 }}>
{llm.messageHistory.map((msg, idx) => (
<View key={idx} style={{ marginBottom: 10 }}>
<Text style={{ fontWeight: 'bold' }}>{msg.role}:</Text>
<Text>{msg.content}</Text>
</View>
))}
{llm.isGenerating && (
<View style={{ marginBottom: 10 }}>
<Text style={{ fontWeight: 'bold' }}>assistant:</Text>
<Text>{llm.response}</Text>
</View>
)}
</ScrollView>
<View style={{ flexDirection: 'row' }}>
<TextInput
value={input}
onChangeText={setInput}
placeholder="Ask a math question..."
style={{ flex: 1, borderWidth: 1, padding: 10 }}
/>
<Button title="Send" onPress={handleSend} disabled={llm.isGenerating} />
</View>
</View>
);
}