CoolFace
Apppublic

danielrosehill/Assistant-Config-Library

sourceHugging Faceupdated 2y agoView on Hugging Face
0likes
app.py278 linesDownload Raw Back to root
1import os2import streamlit as st3import pyperclip4import yaml5from datetime import datetime6 7# Function to format date8def format_date(timestamp):9    return datetime.fromtimestamp(timestamp).strftime("%Y-%m-%d %H:%M:%S")10 11# Function to convert folder names to readable format12def format_folder_name(folder_name):13    return folder_name.replace("-", " ").title()14 15# Function to load markdown files and extract YAML front matter and content16def load_markdown(file_path):17    with open(file_path, 'r') as file:18        content = file.read()19    20    # Check for YAML front matter21    if content.startswith('---'):22        parts = content.split('---', 2)23        if len(parts) >= 3:24            yaml_content = parts[1].strip()25            markdown_content = parts[2].strip()26            try:27                front_matter = yaml.safe_load(yaml_content)28                # Ensure tags is a list29                if 'tags' in front_matter:30                    if isinstance(front_matter['tags'], str):31                        front_matter['tags'] = [tag.strip() for tag in front_matter['tags'].split(',')]32                else:33                    front_matter['tags'] = []34                return front_matter, markdown_content35            except yaml.YAMLError:36                return {'tags': []}, content37    return {'tags': []}, content38 39# Function to extract the first header from markdown content40def extract_title_and_body(markdown_content):41    lines = markdown_content.split('\n')42    title = "Untitled Configuration"43    body = markdown_content44    45    for i, line in enumerate(lines):46        if line.startswith('# '):47            title = line.strip('# ').strip()48            body = '\n'.join(lines[i+1:]).strip()49            break50    51    return title, body52 53# Function to recursively build the sidebar navigation54def build_sidebar_navigation(base_path, current_path):55    items = os.listdir(current_path)56    for item in sorted(items):57        item_path = os.path.join(current_path, item)58        if os.path.isdir(item_path):59            with st.sidebar.expander(format_folder_name(item)):60                build_sidebar_navigation(base_path, item_path)61        elif item.endswith('.md'):62            front_matter, markdown_content = load_markdown(item_path)63            title, _ = extract_title_and_body(markdown_content)64            # Add binoculars icon if vision is enabled65            vision = front_matter.get("vision", "")66            vision_icon = " ๐Ÿ”ญ" if str(vision).lower() == "yes" else ""67            if st.sidebar.button(f"{title}{vision_icon}", key=item_path):68                st.session_state['selected_file'] = item_path69 70# Function to search for configurations71def search_configurations(base_path, search_term, selected_tags=None):72    matches = []73    for root, dirs, files in os.walk(base_path):74        for file in files:75            if file.endswith('.md'):76                file_path = os.path.join(root, file)77                front_matter, markdown_content = load_markdown(file_path)78                title, body = extract_title_and_body(markdown_content)79                80                # Check if content matches search term and tags81                content_matches = search_term.lower() in markdown_content.lower()82                tags_match = True83                if selected_tags:84                    tags_match = any(tag in front_matter.get('tags', []) for tag in selected_tags)85                86                if content_matches and tags_match:87                    matches.append((file_path, title, front_matter.get('tags', [])))88    return matches89 90# Main function to run the Streamlit app91def main():92    st.set_page_config(page_title="AI Agent Configurations", layout="wide")93 94    # Define the base path for agent configurations95    base_path = "agent-configs"96 97    # Initialize session state98    if 'selected_file' not in st.session_state:99        st.session_state['selected_file'] = None100    if 'dark_mode' not in st.session_state:101        st.session_state['dark_mode'] = False102    if 'favorites' not in st.session_state:103        st.session_state['favorites'] = set()104 105    # Apply dark mode if enabled106    if st.session_state['dark_mode']:107        st.markdown("""108            <style>109            .stApp {110                background-color: #1E1E1E;111                color: #FFFFFF;112            }113            .sidebar .sidebar-content {114                background-color: #2D2D2D;115            }116            </style>117            """, unsafe_allow_html=True)118 119    # Sidebar for navigation and search120    st.sidebar.title("AI Agent Configurations")121    122    # Dark mode toggle123    st.sidebar.checkbox("Dark Mode", key="dark_mode", value=st.session_state['dark_mode'])124    125    # GitHub repository badge in sidebar126    st.sidebar.markdown(127        "[![View on GitHub](https://img.shields.io/badge/View_on_GitHub-181717?style=for-the-badge&logo=github&logoColor=white)](https://github.com/danielrosehill/LLM-Assistants-Web-Library)",128        unsafe_allow_html=True129    )130    131    # Collect all configurations and their metadata132    all_configs = []133    all_tags = set()134    for root, _, files in os.walk(base_path):135        for file in files:136            if file.endswith('.md'):137                file_path = os.path.join(root, file)138                front_matter, _ = load_markdown(file_path)139                title, _ = extract_title_and_body(_)140                last_modified = os.path.getmtime(file_path)141                all_configs.append({142                    'path': file_path,143                    'title': title,144                    'tags': front_matter.get('tags', []),145                    'last_modified': last_modified146                })147                all_tags.update(front_matter.get('tags', []))148    149    # Sorting options150    sort_options = {151        'Title (A-Z)': lambda x: x['title'].lower(),152        'Title (Z-A)': lambda x: x['title'].lower(),153        'Last Modified (Newest)': lambda x: x['last_modified'],154        'Last Modified (Oldest)': lambda x: x['last_modified']155    }156    sort_by = st.sidebar.selectbox('Sort by', list(sort_options.keys()))157    158    # Sort configurations159    all_configs.sort(key=sort_options[sort_by])160    if sort_by == 'Title (Z-A)' or sort_by == 'Last Modified (Newest)':161        all_configs.reverse()162    163    # Search and filter functionality164    search_term = st.sidebar.text_input("Search configurations")165    selected_tags = st.sidebar.multiselect("Filter by tags", sorted(list(all_tags)))166    167    # Show favorites section if there are any168    if st.session_state['favorites']:169        st.sidebar.markdown("### Favorites")170        for file_path in st.session_state['favorites']:171            front_matter, _ = load_markdown(file_path)172            title, _ = extract_title_and_body(_)173            if st.sidebar.button(f"โญ {title}", key=f"fav_{file_path}"):174                st.session_state['selected_file'] = file_path175        st.sidebar.divider()176    177    if search_term or selected_tags:178        matches = search_configurations(base_path, search_term, selected_tags)179        if matches:180            st.sidebar.write("Search Results:")181            for file_path, title, tags in matches:182                if st.sidebar.button(f"{title} ({', '.join(tags)})", key=f"search_{file_path}"):183                    st.session_state['selected_file'] = file_path184        else:185            st.sidebar.write("No matches found.")186    else:187        # Build the sidebar navigation188        build_sidebar_navigation(base_path, base_path)189 190    # Main content area191    st.title("Daniel Rosehill AI Assistant Library")192    st.markdown(193        """194        <div style="background-color: #f0f0f0; padding: 10px; border-radius: 10px; margin-bottom: 20px;">195            <p style="margin: 0;">This microsite contains open source configurations for AI assistants.</p>196        </div>197        """,198        unsafe_allow_html=True199    )200 201    if st.session_state['selected_file']:202        front_matter, markdown_content = load_markdown(st.session_state['selected_file'])203        title, body = extract_title_and_body(markdown_content)204        205        # Display title and metadata206        st.markdown(f"# {title}")207        208        # Display tags if present209        if front_matter.get('tags'):210            st.markdown("**Tags:** " + ", ".join(f"`{tag}`" for tag in front_matter['tags']))211        212        # Display last modified date213        last_modified = os.path.getmtime(st.session_state['selected_file'])214        st.markdown(f"**Last Modified:** {format_date(last_modified)}")215        216        # Create a container for buttons217        with st.container():218            st.write("Options:")219            button_col1, button_col2, button_col3, button_col4, _ = st.columns([2, 2, 2, 2, 4])220            221            with button_col1:222                if st.button("๐Ÿ“‹ Copy Title", 223                           key="copy_title",224                           help="Copy title to clipboard",225                           type="secondary"):226                    pyperclip.copy(title)227                    st.success("Title copied!")228            229            with button_col2:230                if st.button("๐Ÿ“„ Copy Content", 231                           key="copy_body",232                           help="Copy full content to clipboard",233                           type="secondary"):234                    pyperclip.copy(body)235                    st.success("Content copied!")236            237            with button_col3:238                is_favorite = st.session_state['selected_file'] in st.session_state['favorites']239                if st.button("โญ " + ("Unfavorite" if is_favorite else "Favorite"),240                           key="toggle_favorite",241                           help="Add/remove from favorites",242                           type="secondary"):243                    if is_favorite:244                        st.session_state['favorites'].remove(st.session_state['selected_file'])245                    else:246                        st.session_state['favorites'].add(st.session_state['selected_file'])247            248            with button_col4:249                if st.button("๐Ÿ”— Share",250                           key="share_config",251                           help="Copy shareable link",252                           type="secondary"):253                    share_url = f"https://github.com/danielrosehill/LLM-Assistants-Web-Library/blob/main/{st.session_state['selected_file']}"254                    pyperclip.copy(share_url)255                    st.success("Share link copied!")256        257        st.divider()258        259        # Display markdown content260        st.markdown(body, unsafe_allow_html=True)261    else:262        st.write("Select a configuration from the sidebar to view its details.")263    264    # Footer with GitHub badge265    st.markdown(266        """267        <div style="position: fixed; bottom: 0; width: 100%; background-color: #f0f0f0; padding: 10px; text-align: center;">268            <a href="https://github.com/danielrosehill/LLM-Assistants-Web-Library" target="_blank">269                <img src="https://img.shields.io/badge/View_on_GitHub-181717?style=for-the-badge&logo=github&logoColor=white" alt="View on GitHub">270            </a>271        </div>272        """,273        unsafe_allow_html=True274    )275 276if __name__ == "__main__":277    main()278