{"id":31106099,"url":"https://github.com/jchristn/sharpai","last_synced_at":"2025-09-17T04:59:27.601Z","repository":{"id":306372989,"uuid":"1024802438","full_name":"jchristn/sharpai","owner":"jchristn","description":"SharpAI is an embeddable embeddings, completions, and model management platform using llama.cpp via LlamaSharp, with a built-in Ollama-compatible webserver.","archived":false,"fork":false,"pushed_at":"2025-09-05T17:12:50.000Z","size":1662,"stargazers_count":4,"open_issues_count":0,"forks_count":2,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-09-16T16:22:02.432Z","etag":null,"topics":["ai","artificial","chat","completion","completions","embedding","embeddings","intelligence","llm","llms","model","models","rag","vector"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jchristn.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-07-23T09:13:58.000Z","updated_at":"2025-09-05T17:12:54.000Z","dependencies_parsed_at":"2025-07-25T10:25:24.537Z","dependency_job_id":"852b129d-df61-447f-8a8d-baa7a27f055e","html_url":"https://github.com/jchristn/sharpai","commit_stats":null,"previous_names":["jchristn/sharpai"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/jchristn/sharpai","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jchristn%2Fsharpai","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jchristn%2Fsharpai/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jchristn%2Fsharpai/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jchristn%2Fsharpai/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jchristn","download_url":"https://codeload.github.com/jchristn/sharpai/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jchristn%2Fsharpai/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":275537166,"owners_count":25482345,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-17T02:00:09.119Z","response_time":84,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","artificial","chat","completion","completions","embedding","embeddings","intelligence","llm","llms","model","models","rag","vector"],"created_at":"2025-09-17T04:59:25.322Z","updated_at":"2025-09-17T04:59:27.588Z","avatar_url":"https://github.com/jchristn.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/jchristn/sharpai/blob/main/assets/logo.png\" width=\"256\" height=\"256\"\u003e\n\u003c/div\u003e\n\n# SharpAI\n\n**Transform your .NET applications into AI powerhouses - embed models directly or deploy as an Ollama-compatible API server. No cloud dependencies, no limits, just pure local inference.**\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://img.shields.io/badge/.NET-5C2D91?style=for-the-badge\u0026logo=.net\u0026logoColor=white\" /\u003e\n  \u003cimg src=\"https://img.shields.io/badge/C%23-239120?style=for-the-badge\u0026logo=c-sharp\u0026logoColor=white\" /\u003e\n  \u003cimg src=\"https://img.shields.io/badge/License-MIT-yellow.svg?style=for-the-badge\" /\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://www.nuget.org/packages/SharpAI/\"\u003e\n    \u003cimg src=\"https://img.shields.io/nuget/v/SharpAI.svg?style=flat\" alt=\"NuGet Version\"\u003e\n  \u003c/a\u003e\n  \u0026nbsp;\n  \u003ca href=\"https://www.nuget.org/packages/SharpAI\"\u003e\n    \u003cimg src=\"https://img.shields.io/nuget/dt/SharpAI.svg\" alt=\"NuGet Downloads\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cstrong\u003eA .NET library for local AI model inference with Ollama-compatible REST API\u003c/strong\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  Embeddings • Completions • Chat • Built on LlamaSharp • GGUF Models Only\n\u003c/p\u003e\n\n---\n\n## 🚀 Features\n\n- **Ollama-Compatible REST API Server** - Provides endpoints compatible with Ollama's API\n- **Model Management** - Download and manage GGUF models from HuggingFace\n- **Multiple Inference Types**:\n  - Text embeddings generation\n  - Text completions\n  - Chat completions\n- **Prompt Engineering Tools** - Built-in helpers for formatting prompts for different model types\n- **GPU Acceleration** - Automatic CUDA detection when available\n- **Streaming Support** - Real-time token streaming for completions\n- **SQLite Model Registry** - Tracks model metadata and file information\n\n## 📋 Table of Contents\n\n- [Installation](#-installation)\n- [Core Components](#-core-components)\n- [Model Management](#-model-management)\n- [Generating Embeddings](#-generating-embeddings)\n- [Text Completions](#-text-completions)\n- [Chat Completions](#-chat-completions)\n- [Prompt Formatting](#-prompt-formatting)\n- [API Server](#-api-server)\n- [Requirements](#-requirements)\n- [Version History](#-version-history)\n- [License](#-license)\n- [Acknowledgments](#-acknowledgments)\n\n## 📦 Installation\n\nInstall SharpAI via NuGet:\n\n```bash\ndotnet add package SharpAI\n```\n\nOr via Package Manager Console:\n\n```powershell\nInstall-Package SharpAI\n```\n\n## 📖 Core Components\n\n### AIDriver\n\nThe main entry point that provides access to all functionality:\n\n```csharp\nusing SharpAI;\nusing SyslogLogging;\n\n// Initialize the AI driver\nvar ai = new AIDriver(\n    logging: new LoggingModule(), \n    databaseFilename: \"./sharpai.db\",     \n    huggingFaceApiKey: \"hf_xxxxxxxxxxxx\", \n    modelDirectory: \"./models/\"           \n);\n\n// Download a model from HuggingFace (GGUF format)\nawait ai.Models.Add(\"microsoft/phi-2\");\n\n// Generate a completion\nstring response = await ai.Completion.GenerateCompletion(\n    model: \"microsoft/phi-2\",\n    prompt: \"Once upon a time\",\n    maxTokens: 512,\n    temperature: 0.7f\n);\n```\n\nThe AIDriver provides access to APIs via:\n- `ai.Models` - Model management operations\n- `ai.Embeddings` - Embedding generation\n- `ai.Completion` - Text completion generation\n- `ai.Chat` - Chat completion generation\n\n### ModelDriver\n\nManages model downloads and lifecycle:\n\n```csharp\n// List all downloaded models\nList\u003cModelFile\u003e models = ai.Models.All();\n\n// Get a specific model\nModelFile model = ai.Models.GetByName(\"microsoft/phi-2\");\n\n// Download a new model from HuggingFace\nModelFile downloaded = await ai.Models.Add(\"meta-llama/Llama-2-7b-chat-hf\");\n\n// Delete a model\nai.Models.Delete(\"microsoft/phi-2\");\n\n// Get the filesystem path for a model\nstring modelPath = ai.Models.GetFilename(\"microsoft/phi-2\");\n```\n\n## 🗄️ Model Management\n\nSharpAI automatically handles downloading GGUF files from HuggingFace. Only GGUF format models are supported.\n\n- Queries available GGUF files for a model\n- Selects appropriate quantization based on file naming conventions\n- Downloads and stores models with metadata\n- Tracks model information in local Sqlite model registry\n\nModel metadata includes:\n\n- Model name and GUID\n- File size and hashes (MD5, SHA1, SHA256)\n- Quantization type\n- Source URL\n- Creation timestamps\n\n## 🔢 Generating Embeddings\n\nGenerate vector embeddings for text:\n\n```csharp\n// Single text embedding\nfloat[] embedding = await ai.Embeddings.Generate(\n    model: \"microsoft/phi-2\",\n    input: \"This is a sample text\"\n);\n\n// Multiple text embeddings\nstring[] texts = { \"First text\", \"Second text\", \"Third text\" };\nfloat[][] embeddings = await ai.Embeddings.Generate(\n    model: \"microsoft/phi-2\",\n    inputs: texts\n);\n```\n\n## 📝 Text Completions\n\n\u003e *Note*: for best results, structure your prompt in a manner appropriate for the model you are using.  See the prompt formatting section below.\n\nGenerate text continuations:\n\n```csharp\n// Non-streaming completion\nstring completion = await ai.Completion.GenerateCompletion(\n    model: \"microsoft/phi-2\",\n    prompt: \"The meaning of life is\",\n    maxTokens: 512,\n    temperature: 0.7f\n);\n\n// Streaming completion\nawait foreach (string token in ai.Completion.GenerateCompletionStreaming(\n    model: \"microsoft/phi-2\",\n    prompt: \"Write a poem about\",\n    maxTokens: 512,\n    temperature: 0.8f))\n{\n    Console.Write(token);\n}\n```\n\n## 💬 Chat Completions\n\n\u003e *Note*: for best results, structure your prompt in a manner appropriate for the model you are using.  See the prompt formatting section below.\n\nGenerate conversational responses:\n\n```csharp\n// Non-streaming chat\nstring response = await ai.Chat.GenerateCompletion(\n    model: \"microsoft/phi-2\",\n    prompt: chatFormattedPrompt,  // Prompt should be formatted for chat\n    maxTokens: 512,\n    temperature: 0.7f\n);\n\n// Streaming chat\nawait foreach (string token in ai.Chat.GenerateCompletionStreaming(\n    model: \"microsoft/phi-2\",\n    prompt: chatFormattedPrompt,\n    maxTokens: 512,\n    temperature: 0.7f))\n{\n    Console.Write(token);\n}\n```\n\n## 🛠️ Prompt Formatting\n\nSharpAI includes prompt builders to format conversations for different model types:\n\n### Chat Message Formatting\n\n```csharp\nusing SharpAI.Prompts;\n\nvar messages = new List\u003cChatMessage\u003e\n{\n    new ChatMessage { Role = \"system\", Content = \"You are a helpful assistant.\" },\n    new ChatMessage { Role = \"user\", Content = \"What is the capital of France?\" },\n    new ChatMessage { Role = \"assistant\", Content = \"The capital of France is Paris.\" },\n    new ChatMessage { Role = \"user\", Content = \"What is its population?\" }\n};\n\n// Format for different model types\nstring chatMLPrompt = PromptBuilder.Build(ChatFormat.ChatML, messages);\n/* Output:\n\u003c|im_start|\u003esystem\nYou are a helpful assistant.\u003c|im_end|\u003e\n\u003c|im_start|\u003euser\nWhat is the capital of France?\u003c|im_end|\u003e\n\u003c|im_start|\u003eassistant\nThe capital of France is Paris.\u003c|im_end|\u003e\n\u003c|im_start|\u003euser\nWhat is its population?\u003c|im_end|\u003e\n\u003c|im_start|\u003eassistant\n*/\n\nstring llama2Prompt = PromptBuilder.Build(ChatFormat.Llama2, messages);\n/* Output:\n\u003cs\u003e[INST] \u003c\u003cSYS\u003e\u003e\nYou are a helpful assistant.\n\u003c\u003c/SYS\u003e\u003e\n\nWhat is the capital of France? [/INST] The capital of France is Paris. \u003c/s\u003e\u003cs\u003e[INST] What is its population? [/INST] \n*/\n\nstring simplePrompt = PromptBuilder.Build(ChatFormat.Simple, messages);\n/* Output:\nsystem: You are a helpful assistant.\nuser: What is the capital of France?\nassistant: The capital of France is Paris.\nuser: What is its population?\nassistant:\n*/\n```\n\nSupported chat formats:\n- `Simple` - Basic role: content format (generic models, base models)\n- `ChatML` - OpenAI ChatML format (GPT models, models fine-tuned with ChatML) including Qwen\n- `Llama2` - Llama 2 instruction format (Llama-2-Chat models)\n- `Llama3` - Llama 3 format (Llama-3-Instruct models)\n- `Alpaca` - Alpaca instruction format (Alpaca, Vicuna, WizardLM, and many Llama-based fine-tunes)\n- `Mistral` - Mistral instruction format (Mistral-Instruct, Mixtral-Instruct models)\n- `HumanAssistant` - Human/Assistant format (Anthropic Claude-style training, some chat models)\n- `Zephyr` - Zephyr model format (Zephyr beta/alpha models)\n- `Phi` - Microsoft Phi format (Phi-2, Phi-3 models)\n- `DeepSeek` - DeepSeek format (DeepSeek-Coder, DeepSeek-LLM models)\n\nIf you are unsure which your model supports, choose `Simple`.\n\n### Text Generation Formatting\n\n```csharp\nusing SharpAI.Prompts;\n\n// Simple instruction\nstring instructionPrompt = TextPromptBuilder.Build(\n    TextGenerationFormat.Instruction,\n    \"Write a haiku about programming\"\n);\n/* Output:\n### Instruction:\nWrite a haiku about programming\n\n### Response:\n*/\n\n// Code generation with context\nvar context = new Dictionary\u003cstring, string\u003e\n{\n    [\"language\"] = \"python\",\n    [\"requirements\"] = \"Include error handling\"\n};\n\nstring codePrompt = TextPromptBuilder.Build(\n    TextGenerationFormat.CodeGeneration,\n    \"Write a function to parse JSON\",\n    context\n);\n/* Output:\nLanguage: python\nTask: Write a function to parse JSON\nRequirements: Include error handling\n\n```python\n*/\n\n// Question-answer format\nstring qaPrompt = TextPromptBuilder.Build(\n    TextGenerationFormat.QuestionAnswer,\n    \"What causes rain?\"\n);\n/* Output:\nQuestion: What causes rain?\n\nAnswer:\n*/\n\n// Few-shot examples\nvar examples = new List\u003c(string input, string output)\u003e\n{\n    (\"2+2\", \"4\"),\n    (\"5*3\", \"15\")\n};\n\nstring fewShotPrompt = TextPromptBuilder.BuildWithExamples(\n    TextGenerationFormat.QuestionAnswer,\n    \"7-3\",\n    examples\n);\n/* Output:\nExamples:\n\nQuestion: 2+2\n\nAnswer:\n4\n\n---\n\nQuestion: 5*3\n\nAnswer:\n15\n\n---\n\nNow complete the following:\n\nQuestion: 7-3\n\nAnswer:\n*/\n```\n\nSupported text generation formats:\n- `Raw` - No formatting\n- `Completion` - Continuation format\n- `Instruction` - Instruction/response format\n- `QuestionAnswer` - Q\u0026A format\n- `CreativeWriting` - Story/creative format\n- `CodeGeneration` - Code generation format\n- `Academic` - Academic writing format\n- `ListGeneration` - List creation format\n- `TemplateFilling` - Template completion\n- `Dialogue` - Dialogue generation\n\n## 🌐 API Server\n\nSharpAI includes a fully-functional REST API server through the **SharpAI.Server** project, which provides Ollama-compatible endpoints. The server acts and behaves like Ollama (with minor gaps), allowing you to use existing Ollama clients and integrations with SharpAI.\n\nKey endpoints include:\n- `/api/generate` - Text generation\n- `/api/chat` - Chat completions\n- `/api/embeddings` - Generate embeddings\n- `/api/tags` - List available models\n- `/api/pull` - Download models from HuggingFace\n\nRefer to the SharpAI.Server documentation for deployment and configuration details.\n\n## ⚙️ Requirements\n\n- .NET 8.0 or higher\n- Windows, Linux, or macOS\n- HuggingFace API key (for downloading models)\n- (Optional) GPU for acceleration (see GPU Support section)\n\n### Tested Platforms\n\nSharpAI has been tested on:\n- Windows 11\n- macOS Sequoia\n- Ubuntu 24.04\n\n## 📊 Model Information\n\nWhen models are downloaded, the following information is tracked:\n\n- Model name and unique GUID\n- File size\n- MD5, SHA1, and SHA256 hashes\n- Quantization type (e.g., Q4_K_M, Q5_K_S)\n- Source URL from HuggingFace\n- Download and creation timestamps\n\n## 🔧 Configuration\n\n### Directory Structure\n\nModels are stored in the specified `modelDirectory` with files named by their GUID. Model metadata is stored in the SQLite database specified by `databaseFilename`.\n\n### GPU Support\n\nThe library automatically detects CUDA availability and optimizes layer allocation. The `LlamaSharpEngine` determines optimal GPU layers based on available hardware.\n\nLlamaSharp supports multiple GPU backends through LlamaSharp and llama.cpp:\n- **NVIDIA GPUs** - via CUDA\n- **AMD GPUs** - via ROCm (Linux) or Vulkan\n- **Apple Silicon** - via Metal (M1, M2, M3, etc.)\n- **Intel GPUs** - via SYCL or Vulkan\n\nNote: The actual GPU support depends on the LlamaSharp build and backend availability on your system. CUDA support is most mature, while other backends may require specific LlamaSharp builds or additional setup.\n## 🐳 Running in Docker\n\nSharpAI.Server is available as a Docker image, providing an easy way to deploy the Ollama-compatible API server without local installation.\n\n### Quick Start\n\n#### Using Docker Run\n\nFor Windows:\n```batch\nrun.bat v1.0.0\n```\n\nFor Linux/macOS:\n```bash\n./run.sh v1.0.0\n```\n\n#### Using Docker Compose\n\nFor Windows:\n```batch\ncompose-up.bat\n```\n\nFor Linux/macOS:\n```bash\n./compose-up.sh\n```\n\n### Prerequisites\n\nBefore running the Docker container, ensure you have:\n\n1. **Configuration file**: Create a `sharpai.json` configuration file in your working directory\n2. **Directory structure**: The container expects the following directories to exist:\n   - `./logs/` - For application logs\n   - `./models/` - For storing downloaded GGUF models\n\n### Docker Image\n\nThe official Docker image is available at: [`jchristn/sharpai`](https://hub.docker.com/r/jchristn/sharpai).  Refer to the `docker` directory for assets useful for running in Docker and Docker Compose.\n\n### Volume Mappings\n\nThe container uses several volume mappings for persistence:\n\n| Host Path | Container Path | Description |\n|-----------|---------------|-------------|\n| `./sharpai.json` | `/app/sharpai.json` | Configuration file |\n| `./sharpai.db` | `/app/sharpai.db` | SQLite database for model registry |\n| `./logs/` | `/app/logs/` | Application logs |\n| `./models/` | `/app/models/` | Downloaded GGUF model files |\n\n### Configuration\n\nModify the `sharpai.json` file to supply your configuration.\n\n### Networking\n\nThe container exposes port 8000 by default. You can access the API at:\n- `http://localhost:8000/api/tags` - List available models\n- `http://localhost:8000/api/generate` - Generate text\n- `http://localhost:8000/api/chat` - Chat completions\n- `http://localhost:8000/api/embeddings` - Generate embeddings\n\n### Example Usage\n\n1. Create the required directory structure:\n   ```bash\n   mkdir logs models\n   ```\n\n2. Create your `sharpai.json` configuration file\n\n3. Run the container:\n   ```bash\n   # Windows\n   run.bat v1.0.0\n   \n   # Linux/macOS\n   ./run.sh v1.0.0\n   ```\n\n4. Download a model using the API:\n   ```bash\n   curl http://localhost:8000/api/pull \\\n     -d '{\"name\":\"microsoft/phi-2\"}'\n   ```\n\n5. Generate text:\n   ```bash\n   curl http://localhost:8000/api/generate \\\n     -d '{\n       \"model\": \"microsoft/phi-2\",\n       \"prompt\": \"Why is the sky blue?\",\n       \"stream\": false\n     }'\n   ```\n\n### Docker Compose\n\nFor production deployments, you can use Docker Compose. Create a `compose.yaml` file:\n\n```yaml\nversion: '3.8'\n\nservices:\n  sharpai:\n    image: jchristn/sharpai:v3.1.0\n    ports:\n      - \"8000:8000\"\n    volumes:\n      - ./sharpai.json:/app/sharpai.json\n      - ./sharpai.db:/app/sharpai.db\n      - ./logs:/app/logs\n      - ./models:/app/models\n    environment:\n      - TERM=xterm-256color\n    restart: unless-stopped\n```\n\nThen run:\n```bash\ndocker compose up -d\n```\n\n### GPU Support in Docker\n\nTo enable GPU acceleration in Docker:\n\n#### NVIDIA GPUs\nInstall the [NVIDIA Container Toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html) and modify your run command:\n\n```bash\ndocker run --gpus all \\\n  -p 8000:8000 \\\n  -v ./sharpai.json:/app/sharpai.json \\\n  -v ./sharpai.db:/app/sharpai.db \\\n  -v ./logs:/app/logs \\\n  -v ./models:/app/models \\\n  jchristn/sharpai:v3.1.0\n```\n\nFor Docker Compose, add:\n```yaml\nservices:\n  sharpai:\n    # ... other configuration ...\n    deploy:\n      resources:\n        reservations:\n          devices:\n            - driver: nvidia\n              count: all\n              capabilities: [gpu]\n```\n\n### Troubleshooting\n\n- **Container exits immediately**: Check that `sharpai.json` exists and is valid JSON\n- **Models not persisting**: Ensure the `./models/` directory has proper write permissions\n- **Cannot connect to API**: Verify port 8000 is not already in use and firewall rules allow access\n- **Out of memory errors**: Large models may require significant RAM. Consider using quantized models or adjusting Docker memory limits\n## 📚 Version History\n\nPlease see the [CHANGELOG.md](CHANGELOG.md) file for detailed version history and release notes.\n\n## 🗺️ Roadmap\n\nThe following features are planned for future releases:\n\n- **Enriching Model Metadata Locally** - Enhanced local tracking of model capabilities, performance metrics, and usage statistics\n- **Classifications for Models** - Automatic categorization of models by their primary use case (embeddings vs generation)\n- **Native SharpAI API** - Additional functionality beyond Ollama compatibility for advanced use cases\n\nHave a feature request or idea? Please [file an issue](https://github.com/yourusername/sharpai/issues) on our GitHub repository. We welcome community input on our roadmap!\n\n## 📄 License\n\nThis project is licensed under the MIT License.\n\n## 🙏 Acknowledgments\n\n- Built on [LlamaSharp](https://github.com/SciSharp/LLamaSharp) for GGUF model inference\n- Model hosting by [HuggingFace](https://huggingface.co/)\n- Inspired by (and forever grateful to) [Ollama](https://ollama.ai/) for API compatibility\n- Special thanks to the community of developers that helped build, test, and refine SharpAI","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjchristn%2Fsharpai","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjchristn%2Fsharpai","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjchristn%2Fsharpai/lists"}