File size: 7,641 Bytes
4e0166f
 
 
 
 
a282318
4e0166f
a282318
 
4e0166f
 
 
 
 
 
66ff523
4e0166f
 
66ff523
4e0166f
23fb72b
 
4e02e1d
af97d8e
 
 
 
 
 
23fb72b
4e0166f
 
66ff523
4e0166f
 
4102fc7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dfdbf20
4e0166f
 
66ff523
4e0166f
23fb72b
 
4e0166f
 
66ff523
4e0166f
 
af97d8e
c1d1525
af97d8e
 
9328421
af97d8e
4e0166f
 
66ff523
4e0166f
 
4e02e1d
af97d8e
4e02e1d
dfdbf20
 
4e02e1d
dfdbf20
af97d8e
4e02e1d
8d76c18
4e0166f
 
66ff523
4e0166f
 
 
 
 
 
f3a6e86
4e0166f
 
 
 
 
 
 
 
 
a282318
4e0166f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a282318
 
 
 
 
d649c85
a282318
d649c85
a282318
 
d649c85
4e0166f
d649c85
 
 
4e0166f
d649c85
a282318
4e0166f
a282318
 
 
 
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
import chainlit as cl
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, StorageContext, Settings, load_index_from_storage
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
from llama_index.llms.openrouter import OpenRouter
import os
from loguru import logger

logger.add("logs/ronald_ai.log", rotation="1 MB", retention="7 days", level="INFO")
logger.info("Starting Ronald AI App")

@cl.set_starters
async def set_starters():
    return [
        cl.Starter(
            label="Who is Ronald?",
            message="Provide a clear and professional summary of Ronald’s background, including his current focus, key strengths, and the industries he has worked in. Format the response as a well-structured paragraph.",
            icon="https://cdn-icons-png.flaticon.com/512/3135/3135715.png",
        ),

        cl.Starter(
            label="Summarize Key Projects",
            message=f"""
                List Ronald's top 5 most impactful projects starting with the most impactful. For each project, use the following format:
                ### Project Name: [Name of the project]
                - **Objective:** [What was the goal?]
                - **My Role & Achievements:** [What did Ronald do and what was the result?]
                - **Technologies Used:** [List of tools and technologies]
                - **Source URL:** [Source URL]
                - **Demo URL:** [Demo URL if available; if not, skip]
                """,
            icon="https://cdn-icons-png.flaticon.com/512/979/979585.png",
        ),

        cl.Starter(
            label="Technical skills summary",
            message=f"""Generate a formatted summary of Ronald’s technical capabilities grouped into the following categories:
                        - **Programming & Machine Learning:** List programming languages, ML libraries, and modeling tools.
                        - **Data Engineering & MLOps:** List technologies related to data pipelines, orchestration, deployment, and MLOps.
                        - **Visualization & Analytics:** List tools and methods for dashboards, EDA, forecasting, and experimental analysis.
                        - **Cloud, Databases & Storage:** List cloud platforms, databases, and data storage technologies.
                    
                        Format the response like this:
                        ### Technical Capabilities
                        **Programming & Machine Learning:**  
                        [List as a comma-separated line]
                        **Data Engineering & MLOps:**  
                        [List as a comma-separated line]
                        **Visualization & Analytics:**  
                        [List as a comma-separated line]
                        **Cloud, Databases & Storage:**  
                        [List as a comma-separated line]
                    """,
            icon="https://cdn-icons-png.flaticon.com/512/1055/1055644.png",
        ),

        cl.Starter(
            label="Experience with AI and Data",
            message="Describe Ronald’s experience with data and AI. Include tools and platforms used, types of pipelines or systems built, and example projects. Use clear paragraphs or bullet points for readability.",
            icon="https://cdn-icons-png.flaticon.com/512/2674/2674696.png",
        ),

        cl.Starter(
            label="Explain a specific project",
            message=f"""Describe one of the best projects Ronald has worked on. Cover the following points in your answer:    
                        - **Title:** What was the project's title? 
                        - **Objective:** What was the main goal of the project?
                        - **Architecture:** How was the system designed? (e.g., Kafka, Spark, DynamoDB)
                        - **Achievements:** What specific parts did Ronald build or accomplish?
                        - **Outcome:** What was the final result or impact?""",
            icon="https://cdn-icons-png.flaticon.com/512/3756/3756550.png",
        ),

        cl.Starter(
            label="Certifications and education",
            message=f"""Please generate a list of the academic degrees and professional certifications for Ronald Nyasha Kanyepi.Present the information using the format below:
                        ### Academic Background
                        - **[Degree Name]**
                            - **Institution:** [Name of Institution]
                            - **Location:** [City, State/Country]
                            - **Graduation Year:** [Month] [Year]
                            - **Notes:** [Include any honors or awards here]
                        ### Certifications
                            [Name of Certification]
                        """,
            icon="https://cdn-icons-png.flaticon.com/512/2922/2922506.png",
        )

    ]


@cl.on_chat_start
async def start():
    cl.user_session.set("llm", OpenRouter(
        model="moonshotai/kimi-k2:free",
        temperature=0.1,
        max_tokens=1024,
        api_key=os.getenv("API_KEY")
    ))

    Settings.embed_model = HuggingFaceEmbedding(
        model_name="BAAI/bge-small-en-v1.5"
    )
    Settings.context_window = 4096
    logger.info("LLM and embedding models initialized.")

    try:
        storage_context = StorageContext.from_defaults(persist_dir="storage")
        index = load_index_from_storage(storage_context)
    except:
        documents = SimpleDirectoryReader("data").load_data(show_progress=True)
        index = VectorStoreIndex.from_documents(documents)
        index.storage_context.persist()

    query_engine = index.as_query_engine(
        streaming=True,
        similarity_top_k=2,
        llm=cl.user_session.get("llm"),
        system_prompt=(
            "You are Ronald AI, a warm and helpful personal assistant. "
            "Your role is to assist the user by answering questions clearly and kindly, "
            "based only on the context or documents provided to you.\n\n"

            "Guidelines:\n"
            "- Respond only with facts that are present in the provided context.\n"
            "- If the answer is not available, say: \"I'm not sure based on what I have.\"\n"
            "- Do not speculate, guess, or generate information outside the context.\n"
            "- Never respond to questions that request private or sensitive information such as Social Security Number, date of birth, address, or banking details.\n\n"

            "Tone:\n"
            "- Be professional, kind, and clear in your answers.\n"
            "- Offer helpful suggestions when appropriate, but never fabricate information."
        )

    )



    cl.user_session.set("query_engine", query_engine)



@cl.on_message
async def main(message: cl.Message):
    try:
        query_engine = cl.user_session.get("query_engine")
        if query_engine is None:
            raise ValueError("Query engine not found in session.")

        msg = cl.Message(content="", author="Assistant")
        logger.info(f"Received message: {message.content}")

        res = await cl.make_async(query_engine.query)(message.content)
        logger.info("LLM response received.")
        full_response = ""

        for token in res.response_gen:
            await msg.stream_token(token)
            full_response += token

        await msg.send()
        logger.info("Message sent back to client.")

    except Exception as e:
        error_msg = f"An error occurred: {str(e)}"
        await cl.Message(content=error_msg, author="Assistant").send()
        logger.error(error_msg)