diff --git a/README.md b/README.md index 7ae3cc8..2dd368d 100644 --- a/README.md +++ b/README.md @@ -26,9 +26,9 @@ We welcome contributions! To add or update resources: Each resource should include: - Name - Description -- Links +- Links (website, github...) - Tags -- Logo +- Logo (preferably a file in logos/) ### Pull Request Process diff --git a/generate_site.py b/generate_site.py index 3666e25..f0efd43 100644 --- a/generate_site.py +++ b/generate_site.py @@ -1,35 +1,43 @@ +from datetime import datetime import yaml from jinja2 import Environment, FileSystemLoader import json + def load_resources(): - with open('resources.yaml', 'r') as file: - return yaml.safe_load(file)['resources'] + with open("resources.yaml", "r") as file: + return yaml.safe_load(file)["resources"] + def generate_html(resources): # Prepare Jinja2 environment - env = Environment(loader=FileSystemLoader('.')) - template = env.get_template('template.html') + env = Environment(loader=FileSystemLoader(".")) + template = env.get_template("template.html") # Render the template html_output = template.render( resources=resources, - resources_json=json.dumps(resources) + resources_json=json.dumps(resources), + generation_date=datetime.now(), ) # Write the output - with open('dist/index.html', 'w') as file: + with open("dist/index.html", "w") as file: file.write(html_output) + def main(): import os import shutil - os.makedirs('dist', exist_ok=True) + + os.makedirs("dist", exist_ok=True) resources = load_resources() generate_html(resources) # Copy the styles file to the dist directory - shutil.copy('styles.css', 'dist/styles.css') - shutil.copytree('scripts', 'dist/scripts/', dirs_exist_ok=True) + shutil.copy("styles.css", "dist/styles.css") + shutil.copytree("scripts", "dist/scripts/", dirs_exist_ok=True) + shutil.copytree("logos", "dist/logos/", dirs_exist_ok=True) + -if __name__ == '__main__': - main() \ No newline at end of file +if __name__ == "__main__": + main() diff --git a/logos/agentops.svg b/logos/agentops.svg new file mode 100644 index 0000000..57ac52d --- /dev/null +++ b/logos/agentops.svg @@ -0,0 +1,6 @@ + diff --git a/logos/autogen.svg b/logos/autogen.svg new file mode 100644 index 0000000..9402bbd --- /dev/null +++ b/logos/autogen.svg @@ -0,0 +1 @@ + diff --git a/logos/axolotl.svg b/logos/axolotl.svg new file mode 100644 index 0000000..48ca4cb --- /dev/null +++ b/logos/axolotl.svg @@ -0,0 +1,18 @@ + diff --git a/logos/braintrust.svg b/logos/braintrust.svg new file mode 100644 index 0000000..7b6ce90 --- /dev/null +++ b/logos/braintrust.svg @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/logos/ell.png b/logos/ell.png new file mode 100644 index 0000000..5b9c9ad Binary files /dev/null and b/logos/ell.png differ diff --git a/logos/giskard.svg b/logos/giskard.svg new file mode 100644 index 0000000..40ff9d5 --- /dev/null +++ b/logos/giskard.svg @@ -0,0 +1,36 @@ + diff --git a/logos/humanloop.svg b/logos/humanloop.svg new file mode 100644 index 0000000..eab80dc --- /dev/null +++ b/logos/humanloop.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/logos/lightning.png b/logos/lightning.png new file mode 100644 index 0000000..fc03bf2 Binary files /dev/null and b/logos/lightning.png differ diff --git a/logos/pydanticai.svg b/logos/pydanticai.svg new file mode 100644 index 0000000..f8f9314 --- /dev/null +++ b/logos/pydanticai.svg @@ -0,0 +1,34 @@ + diff --git a/logos/qdrant.svg b/logos/qdrant.svg new file mode 100644 index 0000000..d25596a --- /dev/null +++ b/logos/qdrant.svg @@ -0,0 +1,137 @@ + + diff --git a/logos/swarm.png b/logos/swarm.png new file mode 100644 index 0000000..26511b2 Binary files /dev/null and b/logos/swarm.png differ diff --git a/resources.yaml b/resources.yaml index 2e86336..68e847d 100644 --- a/resources.yaml +++ b/resources.yaml @@ -8,7 +8,7 @@ resources: - "open-source" tags: - agents - logo: https://microsoft.github.io/autogen/0.2/img/ag.svg + logo: logos/autogen.svg - name: "AutoGPT" description: "Open source AI agent project. Given a goal, the agent will decompose it into actionable subtasks and utilize given resources to accomplish them" @@ -105,7 +105,7 @@ resources: licensing: - "open-source" tags: - - observability + - observability/evaluation - LLMOps logo: https://langfuse.com/langfuse_logo.png @@ -116,7 +116,7 @@ resources: licensing: - "commercial" tags: - - observability + - observability/evaluation - platform - LLMOps logo: https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRejzbKjev2a8d-EKtUU06p84fh5NX_S7dDLA&s @@ -170,7 +170,7 @@ resources: licensing: - "open-source" tags: - - observability + - observability/evaluation logo: https://openai.com/favicon.ico - name: "promptfoo" @@ -181,7 +181,7 @@ resources: - "open-source" tags: - prompt engineering - - observability + - observability/evaluation logo: https://www.promptfoo.dev/favicon.ico - name: "Ragas" @@ -192,7 +192,7 @@ resources: - "open-source" tags: - RAG - - observability + - observability/evaluation logo: https://docs.ragas.io/en/stable/_static/imgs/ragas-logo.png - name: "SpringAI" @@ -214,7 +214,7 @@ resources: licensing: - "open-source" tags: - - observability + - observability/evaluation logo: - name: "Weights & Biases (W&B)" @@ -236,7 +236,7 @@ resources: - "open-source" - commercial tags: - - data storage + - data search and storage - RAG logo: https://weaviate.io/img/site/weaviate-logo-light.png @@ -247,9 +247,9 @@ resources: licensing: - commercial tags: - - data storage + - data search and storage - RAG - logo: + logo: - name: "CrewAI" description: "Framework for orchestrating autonomous AI Agents" @@ -274,7 +274,6 @@ resources: tags: - agents - RAG - - name: ollama description: "Lightweight, extensible framework for building and running language models on the local machine" @@ -315,8 +314,8 @@ resources: - "commercial" tags: - serving - logo: - + logo: + - name: "together.ai" description: "Manage and run AI models" links: @@ -325,8 +324,9 @@ resources: - "commercial" tags: - serving + - fine-tuning logo: - + - name: "Chroma" description: "AI application database" links: @@ -335,7 +335,135 @@ resources: licensing: - "open-source" tags: - - data storage + - data search and storage logo: https://www.trychroma.com/img/chroma.png + + - name: "Giskard" + description: "Evaluation and testing framework. Also provides a testing two commercial products: LLM evaluation hub and AI compliance hub" + links: + - website: "https://www.giskard.ai" + - github: "https://github.com/Giskard-AI/giskard" + licensing: + - "open-source" + - "commercial" + tags: + - observability/evaluation + - guardrails/security + logo: logos/giskard.svg + + - name: "braintrust" + description: "End-to-end platform for building AI applications, including iterative experimentation, evluations, real-time monitoring, and data management" + links: + - website: "https://www.braintrust.dev/" + licensing: + - "commercial" + tags: + - platform + logo: logos/braintrust.svg + + - name: "Humanloop" + description: "Humanloop provides a platform for data labeling and model evaluation" + links: + - website: "https://humanloop.com/" + licensing: + - "commercial" + tags: + - observability/evaluation + logo: logos/humanloop.svg + + - name: "ell" + description: "A lightweight prompt engineering library treating prompts as functions" + links: + - website: "https://docs.ell.so/" + - github: "https://github.com/madcowd/ell" + licensing: + - "open-source" + tags: + - prompt engineering + logo: logos/ell.png + + - name: "PydanticAI" + description: "Python agent framework" + links: + - website: https://ai.pydantic.dev/ + - github: https://github.com/pydantic/pydantic-ai + licensing: + - "open-source" + tags: + - agents + logo: logos/pydanticai.svg + + - name: "Qdrant" + description: "Vector similarity search engine and vector database, open-source or fully managed with Qdrant Cloud" + links: + - website: "https://qdrant.tech/" + - github: "https://github.com/qdrant/qdrant" + licensing: + - "open-source" + - "commercial" + tags: + - data search and storage + logo: logos/qdrant.svg + - name: "pgvector" + description: "Open-source vector similarity search for Postgres" + links: + - github: "https://github.com/pgvector/pgvector" + licensing: + - "open-source" + tags: + - data search and storage + + - name: "OpenAI Swarm" + description: Educational framework exploring ergonomic, lightweight multi-agent orchestration + links: + - github: "https://github.com/openai/swarm" + licensing: + - "open-source" + tags: + - agents + logo: logos/swarm.png + + - name: "unsloth" + description: "Tool to fine-tune LLMs faster and more efficiently" + links: + - website: "https://unsloth.ai/" + - github: "https://github.com/unslothai/unsloth" + licensing: + - "open-source" + - "commercial" + tags: + - fine-tuning + - name: "axolotl" + description: "Library designed to streamline the fine-tuning of various AI models" + links: + - github: "https://github.com/axolotl-ai-cloud/axolotl" + licensing: + - "open-source" + tags: + - fine-tuning + logo: logos/axolotl.svg + + - name: "Lightning" + description: "Platform to train models, deploy, and more." + links: + - website: "https://www.lightning.ai/" + licensing: + - "commercial" + tags: + - platform + - serving + - fine-tuning + logo: logos/lightning.png + + - name: "AgentOps" + description: "Developer platform to test and debug AI agents" + links: + - website: "https://www.agentops.ai/" + licensing: + - "commercial" + tags: + - agents + - platform + logo: logos/agentops.svg \ No newline at end of file diff --git a/scripts/landscape.js b/scripts/landscape.js index 967a767..cbbc5a7 100644 --- a/scripts/landscape.js +++ b/scripts/landscape.js @@ -48,10 +48,11 @@ function renderResourceLandscape(resources) { logo.alt = resource.name; logo.className = 'logo'; resourceLink.appendChild(logo); - // If logo link is broken - logo.onerror = function () { - logo.src = ''; - } + logo.onerror = () => { + console.error('Logo not found:', resource.logo); + resourceLink.removeChild(logo); + resourceLink.textContent = resource.name; + }; } // Use name if no logo else { diff --git a/scripts/table.js b/scripts/table.js index 39bf670..9024622 100644 --- a/scripts/table.js +++ b/scripts/table.js @@ -28,8 +28,8 @@ function renderResources(filteredResources) { // Licensing const licensingCell = document.createElement('td'); - const licensingBadge = document.createElement('span'); resource.licensing.forEach(licensing => { + const licensingBadge = document.createElement('span'); licensingBadge.className = `badge licensing-badge licensing-${licensing.toLowerCase().replace(' ', '-')}`; licensingBadge.textContent = licensing; licensingCell.appendChild(licensingBadge); diff --git a/styles.css b/styles.css index fa3a704..d63bcd6 100644 --- a/styles.css +++ b/styles.css @@ -16,193 +16,187 @@ body { --tag-color-7: #16a085; --tag-color-8: #27ae60; --tag-color-9: #2980b9; + --tag-color-10: #8e44ad; + --tag-color-11: #2c3e50; + --tag-color-12: #1abc9c; + --tag-color-13: #f1c40f; + +} - .sticky { - background-color: #f4f4f4; - position: sticky; - top: 0; - } - - .logo { - display: flex; - justify-content: center; - align-items: center; - max-height: 20px; - } - - img[src=""] { - visibility: hidden; - } - .tag-badge { - margin-right: 5px; - margin-bottom: 5px; - } +.sticky { + background-color: #f4f4f4; + position: sticky; + top: 0; +} +.generation-date { + position: absolute; + top: 10px; + right: 10px; + background-color: rgba(0, 0, 0, 0.7); + color: white; + padding: 5px 10px; + border-radius: 4px; + font-size: 0.8rem; + opacity: 0.8; + z-index: 1000; +} - .licensing-badge { - font-size: 0.8em; - margin-left: 5px; - } +.logo { + display: flex; + justify-content: center; + align-items: center; + max-height: 20px; +} - .licensing-open-source { - background-color: #2881a7; - color: white; - } +img[src=""] { + visibility: hidden; +} - .licensing-freemium { - background-color: #ffc107; - color: black; - } +.tag-badge { + margin-right: 5px; + margin-bottom: 5px; +} - .licensing-commercial { - background-color: #257139; - color: white; - } - .landscape-container { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); - gap: 20px; - } +.licensing-badge { + font-size: 0.8em; + margin-left: 5px; +} - .tag-box { - border-width: 3px; - border-style: solid; - border-radius: 8px; - padding: 15px; - box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); - background-color: white; - } +.licensing-open-source { + background-color: #2881a7; + color: white; +} - .tag-title { - font-weight: bold; - margin-bottom: 10px; - text-transform: uppercase; - border-bottom: 2px solid; - padding-bottom: 5px; - } +.licensing-freemium { + background-color: #ffc107; + color: black; +} - .resources-container { - display: flex; - flex-wrap: wrap; - gap: 10px; - } +.licensing-commercial { + background-color: #257139; + color: white; +} - .resource-item { - background-color: #f9f9f9; - border-radius: 4px; - padding: 8px; - margin-bottom: 5px; - } +.landscape-container { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); + gap: 20px; +} - .resource-item a { - text-decoration: none; - color: #333; - font-weight: 500; - } +.tag-box { + border-width: 3px; + border-style: solid; + border-radius: 8px; + padding: 15px; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); + background-color: white; +} - /* Dynamic tag colors */ - .tag-box[data-tag="tag-1"] { - border-color: var(--tag-color-1); +.tag-title { + font-weight: bold; + margin-bottom: 10px; + text-transform: uppercase; + border-bottom: 2px solid; + padding-bottom: 5px; +} - .tag-title { - border-bottom-color: var(--tag-color-1); - } - } +.resources-container { + display: flex; + flex-wrap: wrap; + gap: 10px; +} - .tag-box[data-tag="tag-2"] { - border-color: var(--tag-color-2); +.resource-item { + background-color: #f9f9f9; + border-radius: 4px; + padding: 8px; + margin-bottom: 5px; +} - .tag-title { - border-bottom-color: var(--tag-color-2); - } - } +.resource-item a { + text-decoration: none; + color: #333; + font-weight: 500; +} - .tag-box[data-tag="tag-3"] { - border-color: var(--tag-color-3); +/* Dynamic tag colors */ +.tag-box[data-tag="tag-1"] { + border-color: var(--tag-color-1); - .tag-title { - border-bottom-color: var(--tag-color-3); - } + .tag-title { + border-bottom-color: var(--tag-color-1); } +} - .tag-box[data-tag="tag-4"] { - border-color: var(--tag-color-4); +.tag-box[data-tag="tag-2"] { + border-color: var(--tag-color-2); - .tag-title { - border-bottom-color: var(--tag-color-4); - } + .tag-title { + border-bottom-color: var(--tag-color-2); } +} - .tag-box[data-tag="tag-5"] { - border-color: var(--tag-color-5); +.tag-box[data-tag="tag-3"] { + border-color: var(--tag-color-3); - .tag-title { - border-bottom-color: var(--tag-color-5); - } + .tag-title { + border-bottom-color: var(--tag-color-3); } +} - .tag-box[data-tag="tag-6"] { - border-color: var(--tag-color-6); +.tag-box[data-tag="tag-4"] { + border-color: var(--tag-color-4); - .tag-title { - border-bottom-color: var(--tag-color-6); - } + .tag-title { + border-bottom-color: var(--tag-color-4); } +} - .tag-box[data-tag="tag-7"] { - border-color: var(--tag-color-7); +.tag-box[data-tag="tag-5"] { + border-color: var(--tag-color-5); - .tag-title { - border-bottom-color: var(--tag-color-7); - } + .tag-title { + border-bottom-color: var(--tag-color-5); } +} - .tag-box[data-tag="tag-8"] { - border-color: var(--tag-color-8); +.tag-box[data-tag="tag-6"] { + border-color: var(--tag-color-6); - .tag-title { - border-bottom-color: var(--tag-color-8); - } + .tag-title { + border-bottom-color: var(--tag-color-6); } +} - .tag-box[data-tag="tag-9"] { - border-color: var(--tag-color-9); +.tag-box[data-tag="tag-7"] { + border-color: var(--tag-color-7); - .tag-title { - border-bottom-color: var(--tag-color-9); - } + .tag-title { + border-bottom-color: var(--tag-color-7); } +} - form { - display: grid; - grid-template-columns: max-content 1fr; - grid-gap: 1rem; - text-align: left; - padding: 2rem 0; - margin: 0; - } +.tag-box[data-tag="tag-8"] { + border-color: var(--tag-color-8); - form label { - display: contents; + .tag-title { + border-bottom-color: var(--tag-color-8); } +} - form input[type="email"], - form textarea, - form button { - font-family: inherit; - font-size: inherit; - border: 1px solid gray; - border-radius: 5px; - background: none; - padding: 0.4rem 0.5rem; - } +.tag-box[data-tag="tag-9"] { + border-color: var(--tag-color-9); - form textarea { - resize: vertical; + .tag-title { + border-bottom-color: var(--tag-color-9); } +} - form button { - justify-self: start; - } \ No newline at end of file +button { + &.btn-block { + width: 100%; + } +} \ No newline at end of file diff --git a/template.html b/template.html index 0c510bc..e4d6706 100644 --- a/template.html +++ b/template.html @@ -11,6 +11,10 @@
or contact me directly: