File size: 3,478 Bytes
7dbf6ae
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
334ec42
7dbf6ae
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
import streamlit as st
import requests
import pandas as pd

# ---------------------- App Title ----------------------
st.title("πŸ—οΈ BuildSmart Estimator")
st.markdown("Estimate construction materials using a Mistral-powered model via Hugging Face.")

# ---------------------- User Inputs ----------------------
st.header("πŸ“‹ Project Details")

area = st.number_input("Total Area (in square feet)", min_value=100, max_value=100000, step=100)
floors = st.number_input("Number of Floors", min_value=1, max_value=100, step=1)
structure_type = st.selectbox("Structure Type", ["Residential", "Commercial", "Industrial"])
material_preference = st.selectbox("Material Preference", ["Cement & Bricks", "Steel & Concrete"])
location = st.text_input("Location")

# ---------------------- Hugging Face Config ----------------------
HUGGINGFACE_API_TOKEN = st.secrets["api_token"]
HUGGINGFACE_API_URL = "https://api-inference.huggingface.co/models/mistralai/Mistral-7B-Instruct-v0.2"

headers = {
    "Authorization": f"Bearer {MISTRAL_API}",
    "Content-Type": "application/json"
}

# ---------------------- Build Prompt ----------------------
def build_prompt(area, floors, structure_type, material_pref, location):
    return (
        f"[INST] Estimate construction materials for the following project:\n"
        f"- Area: {area} sqft\n"
        f"- Floors: {floors}\n"
        f"- Structure type: {structure_type}\n"
        f"- Material preference: {material_pref}\n"
        f"- Location: {location}\n\n"
        f"Return in this format:\n"
        f"Cement (bags), Sand (cubic feet), Bricks (units), Steel (kg), Crush (cubic feet), Rori (cubic feet). [/INST]"
    )

# ---------------------- Call API ----------------------
def query_mistral(prompt):
    response = requests.post(
        HUGGINGFACE_API_URL,
        headers=headers,
        json={"inputs": prompt}
    )
    if response.status_code == 200:
        return response.json()[0]["generated_text"]
    else:
        return f"❌ API Error {response.status_code}: {response.text}"

# ---------------------- Submit Button ----------------------
if st.button("Estimate Materials"):
    if not location:
        st.warning("Please enter a location before submitting.")
    else:
        with st.spinner("Estimating materials using Mistral..."):
            prompt = build_prompt(area, floors, structure_type, material_preference, location)
            result_text = query_mistral(prompt)

            st.subheader("πŸ“¦ Estimated Materials")
            st.text(result_text)

            try:
                lines = result_text.strip().split(",")
                data = []
                for line in lines:
                    if ":" in line:
                        key, value = line.split(":", 1)
                    else:
                        parts = line.strip().split()
                        key = " ".join(parts[:-1])
                        value = parts[-1]
                    data.append([key.strip(), value.strip()])
                df = pd.DataFrame(data, columns=["Material", "Estimated Quantity"])
                st.dataframe(df)

                csv = df.to_csv(index=False)
                st.download_button("πŸ“₯ Download as CSV", csv, "material_estimate.csv", "text/csv")
            except Exception as e:
                st.error("❗ Could not parse the model output.")
                st.exception(e)

st.markdown("---")
st.caption("Powered by Mistral via Hugging Face Inference API")