Further enhance and add in an advanced problem-solving skills with yielding awareness.

```
import streamlit as st
import g4f
from g4f.client import Client
import os
import json
import time
from typing import List, Tuple

client = Client()

class DynamicMemory:
    def __init__(self, max_memory_size=5):
        self.memory = []
        self.max_memory_size = max_memory_size

    def add_step(self, step_title: str, step_content: str):
        self.memory.append((step_title, step_content))
        if len(self.memory) > self.max_memory_size:
            self.memory.pop(0)  # Remove the oldest memory if exceeding max size

    def get_relevant_memory(self, current_content: str) -> str:
        # Implement semantic similarity to retrieve relevant memory
        # For now, return all memory entries
        return "\n".join([f"{title}: {content}" for title, content in self.memory]) if self.memory else ""

def make_api_call(messages: List[dict], max_tokens: int, is_final_answer: bool = False) -> dict:
    for attempt in range(3):
        try:
            response = client.chat.completions.create(
                model="gpt-4o",  # Adjust the model as needed
                messages=messages,
                max_tokens=max_tokens,
                temperature=0.2,
                response_format={"type": "json_object"}
            )
            return json.loads(response.choices[0].message.content)
        except Exception as e:
            if attempt == 2:
                error_content = f"Failed to generate {'final answer' if is_final_answer else 'step'} after 3 attempts. Error: {str(e)}"
                return {
                    "title": "Error",
                    "content": error_content,
                    "next_action": "final_answer" if is_final_answer else "continue"
                }
            time.sleep(1)  # Wait for 1 second before retrying

def generate_response(prompt: str):
    messages = [
        {
            "role": "system",
            "content": """You are an advanced analytical AI assistant with adaptive capabilities to thoroughly analyze complex problems. You have a dynamic memory module that maintains a short-term memory buffer of previously generated reasoning steps and user-provided context. This memory is contextually queried during reasoning to simulate a more "human-like" working memory that adapts dynamically to the problem at hand. Your task is to provide detailed, step-by-step explanations of your thought process using advanced analytical methods, adaptive reasoning, and advanced common-sense reasoning. For each step:

1. **Advanced Analysis**: Apply sophisticated analytical techniques to dissect the problem.
2. **Adaptive Reasoning**: Reflect on previous steps and dynamically adjust your approach based on new insights or information retrieved from your dynamic memory.
3. **Common-Sense Reasoning**: Utilize everyday knowledge and logical reasoning to fill in gaps and make sound judgments.
4. **In-depth Exploration**: Explore multiple dimensions and perspectives of the problem.
5. **Critical Evaluation**: Critically evaluate your findings and adjust hypotheses accordingly.

**Response Format:**
Use JSON with keys:
- `"title"`: A clear, concise title describing the current reasoning phase.
- `"content"`: Elaborate on your thought process in this step.
- `"next_action"`: Decide whether to `"continue"` reasoning or provide a `"final_answer"`.

**Key Instructions:**
- Employ at least 5 distinct reasoning steps.
- In each step, explicitly reference relevant parts of previous steps or user context from your dynamic memory to adapt your reasoning.
- Use advanced analytical methods (e.g., statistical analysis, logical deductions, scenario planning).
- Apply advanced common-sense reasoning to make logical inferences and fill in gaps in information.
- Adapt your reasoning strategies based on the complexity and nuances of the problem.
- Acknowledge your limitations and explicitly state what you can and cannot do.
- Evaluate alternative answers or approaches thoroughly.
- Critically assess your reasoning; identify potential flaws or biases.
- Ensure that your explanations are consistent and coherent throughout the reasoning process.
- Utilize diverse methods to derive or verify your answer.
- Incorporate relevant domain knowledge and best practices.
- Quantify certainty levels for each step and the final conclusion when applicable.
- Consider potential edge cases, exceptions, or unintended consequences.
- Provide clear justifications for eliminating alternative hypotheses.

**Example of a valid JSON response:**
json
{
    "title": "Advanced Statistical Analysis",
    "content": "Based on the dynamic memory retrieved, I will perform a statistical analysis to determine... [detailed explanation]... This will help quantify the relationships between variables.",
    "next_action": "continue"
}
"""
            },
        {"role": "user", "content": prompt},
        {
            "role": "assistant",
            "content": "Understood. I will proceed to analyze the problem using advanced analytical methods, adaptive reasoning, and common-sense reasoning, utilizing my dynamic memory module."
        }
    ]

    memory = DynamicMemory(max_memory_size=5)
    steps = []
    step_count = 1
    total_thinking_time = 0

    while True:
        start_time = time.time()

        # Retrieve relevant memory
        relevant_memory = memory.get_relevant_memory(prompt)
        if relevant_memory:
            messages.append({"role": "system", "content": f"Relevant Memory:\n{relevant_memory}"})

        # Add user-provided context if it's the first step
        if step_count == 1:
            messages.append({"role": "system", "content": f"User Context:\n{prompt}"})

        step_data = make_api_call(messages, 800)
        end_time = time.time()
        thinking_time = end_time - start_time
        total_thinking_time += thinking_time

        # Error handling if step_data is None
        if not step_data:
            step_data = {
                "title": "Error",
                "content": "An unexpected error occurred during processing.",
                "next_action": "final_answer"
            }

        # Add the new step to dynamic memory
        memory.add_step(step_data['title'], step_data['content'])

        steps.append((f"Step {step_count}: {step_data['title']}", step_data['content'], thinking_time))

        # Add the assistant's response to the message history
        messages.append({"role": "assistant", "content": json.dumps(step_data)})

        if step_data.get('next_action', '') == 'final_answer':
            break

        step_count += 1

        # Optional: Clear messages to prevent input length exceeding model limits
        if len(messages) > 15:
            # Keep system prompts and last few messages
            messages = messages[:3] + messages[-12:]

        # Yield after each step for Streamlit to update
        yield steps, None  # Total time is yielded at the end

    # Generate final answer
    messages.append({"role": "user", "content": "Please provide the final answer based on your reasoning above."})

    start_time = time.time()
    final_data = make_api_call(messages, 500, is_final_answer=True)
    end_time = time.time()
    thinking_time = end_time - start_time
    total_thinking_time += thinking_time

    # Error handling if final_data is None
    if not final_data:
        final_data = {
            "content": "An unexpected error occurred while generating the final answer."
        }

    steps.append(("Final Answer", final_data['content'], thinking_time))

    yield steps, total_thinking_time

def main():
    st.set_page_config(page_title="Adaptive AI Reasoning Chains", page_icon="🧠", layout="wide")

    st.title("Adaptive AI Assistant with Context-Aware Dynamic Memory Chain-of-Thought")

    st.markdown("""
This application utilizes an adaptive AI assistant that applies advanced analytical methods and common-sense reasoning to thoroughly analyze complex problems using a **Context-Aware Dynamic Memory Chain-of-Thought (CADM-CoT)** approach.
        
Forked from [bklieger-groq](https://github.com/bklieger-groq)
        
Open source [repository here](https://github.com/win4r/o1)
""")

    # Text input for user query
    user_query = st.text_area(
        "Enter a complex problem for analysis:",
        placeholder="e.g., Analyze the potential impacts of implementing a universal basic income.",
        height=150
    )

    if user_query:
        st.write("Generating response...")

        # Create empty elements to hold the generated text and total time
        response_container = st.empty()
        time_container = st.empty()

        # Generate and display the response
        for steps, total_thinking_time in generate_response(user_query):
            with response_container.container():
                for i, (title, content, thinking_time) in enumerate(steps):
                    if title.startswith("Final Answer"):
                        st.markdown(f"### {title}")
                        st.markdown(content.replace('\n', '<br>'), unsafe_allow_html=True)
                    else:
                        with st.expander(title, expanded=False):
                            st.markdown(content.replace('\n', '<br>'), unsafe_allow_html=True)
                            st.caption(f"Thinking time for this step: {thinking_time:.2f} seconds")

            # Only show total time when it's available at the end
            if total_thinking_time is not None:
                time_container.markdown(f"**Total thinking time: {total_thinking_time:.2f} seconds**")

if __name__ == "__main__":
    main()