{"id":44607624,"url":"https://github.com/sauravbhattacharya001/prompt","last_synced_at":"2026-04-30T02:04:40.671Z","repository":{"id":187628960,"uuid":"677269284","full_name":"sauravbhattacharya001/prompt","owner":"sauravbhattacharya001","description":".NET 8 prompt engineering toolkit — Azure OpenAI client, template engine, prompt chaining, injection detection, bias detector, and more","archived":false,"fork":false,"pushed_at":"2026-04-20T06:53:49.000Z","size":1845,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-20T08:34:27.525Z","etag":null,"topics":["ai","azure-openai","chat-completions","chatgpt","csharp","dotnet","dotnet-library","gpt-4","llm","nuget","openai","prompt-chaining","prompt-engineering","prompt-template"],"latest_commit_sha":null,"homepage":null,"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/sauravbhattacharya001.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","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":"2023-08-11T06:37:51.000Z","updated_at":"2026-04-20T06:53:54.000Z","dependencies_parsed_at":"2023-08-12T01:17:02.282Z","dependency_job_id":null,"html_url":"https://github.com/sauravbhattacharya001/prompt","commit_stats":null,"previous_names":["sauravbhattacharya001/prompt"],"tags_count":21,"template":false,"template_full_name":null,"purl":"pkg:github/sauravbhattacharya001/prompt","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sauravbhattacharya001%2Fprompt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sauravbhattacharya001%2Fprompt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sauravbhattacharya001%2Fprompt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sauravbhattacharya001%2Fprompt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sauravbhattacharya001","download_url":"https://codeload.github.com/sauravbhattacharya001/prompt/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sauravbhattacharya001%2Fprompt/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32220295,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-24T10:26:35.452Z","status":"ssl_error","status_checked_at":"2026-04-24T10:25:27.643Z","response_time":64,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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","azure-openai","chat-completions","chatgpt","csharp","dotnet","dotnet-library","gpt-4","llm","nuget","openai","prompt-chaining","prompt-engineering","prompt-template"],"created_at":"2026-02-14T11:20:35.968Z","updated_at":"2026-04-30T02:04:40.659Z","avatar_url":"https://github.com/sauravbhattacharya001.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n# 🤖 Prompt\n\n**A comprehensive .NET library for Azure OpenAI prompt engineering**\n\n[![NuGet](https://img.shields.io/nuget/v/prompt-llm-aoi?style=flat-square\u0026logo=nuget\u0026color=004880)](https://www.nuget.org/packages/prompt-llm-aoi)\n[![NuGet Downloads](https://img.shields.io/nuget/dt/prompt-llm-aoi?style=flat-square\u0026logo=nuget\u0026color=004880)](https://www.nuget.org/packages/prompt-llm-aoi)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg?style=flat-square)](LICENSE)\n[![.NET](https://img.shields.io/badge/.NET-8.0-blueviolet?style=flat-square\u0026logo=dotnet)](https://dotnet.microsoft.com/download/dotnet/8.0)\n[![CodeQL](https://img.shields.io/github/actions/workflow/status/sauravbhattacharya001/prompt/codeql.yml?style=flat-square\u0026label=CodeQL\u0026logo=github)](https://github.com/sauravbhattacharya001/prompt/actions/workflows/codeql.yml)\n[![CI](https://img.shields.io/github/actions/workflow/status/sauravbhattacharya001/prompt/ci.yml?style=flat-square\u0026label=CI\u0026logo=github)](https://github.com/sauravbhattacharya001/prompt/actions/workflows/ci.yml)\n[![Publish](https://img.shields.io/github/actions/workflow/status/sauravbhattacharya001/prompt/nuget-publish.yml?style=flat-square\u0026label=Publish\u0026logo=github)](https://github.com/sauravbhattacharya001/prompt/actions/workflows/nuget-publish.yml)\n[![codecov](https://img.shields.io/codecov/c/github/sauravbhattacharya001/prompt?style=flat-square\u0026logo=codecov)](https://codecov.io/gh/sauravbhattacharya001/prompt)\n![Tests](https://img.shields.io/badge/tests-1011%20passed-brightgreen?style=flat-square)\n[![Docker](https://img.shields.io/github/actions/workflow/status/sauravbhattacharya001/prompt/docker.yml?style=flat-square\u0026label=Docker\u0026logo=docker)](https://github.com/sauravbhattacharya001/prompt/actions/workflows/docker.yml)\n[![Pages](https://img.shields.io/github/actions/workflow/status/sauravbhattacharya001/prompt/pages.yml?style=flat-square\u0026label=Docs\u0026logo=github)](https://sauravbhattacharya001.github.io/prompt/)\n[![GitHub Release](https://img.shields.io/github/v/release/sauravbhattacharya001/prompt?style=flat-square\u0026logo=github\u0026color=blue)](https://github.com/sauravbhattacharya001/prompt/releases)\n[![Last Commit](https://img.shields.io/github/last-commit/sauravbhattacharya001/prompt?style=flat-square\u0026logo=git\u0026color=orange)](https://github.com/sauravbhattacharya001/prompt/commits/main)\n[![GitHub Stars](https://img.shields.io/github/stars/sauravbhattacharya001/prompt?style=flat-square\u0026logo=github\u0026color=gold)](https://github.com/sauravbhattacharya001/prompt/stargazers)\n[![Open Issues](https://img.shields.io/github/issues/sauravbhattacharya001/prompt?style=flat-square\u0026logo=github\u0026color=red)](https://github.com/sauravbhattacharya001/prompt/issues)\n[![Contributors](https://img.shields.io/github/contributors/sauravbhattacharya001/prompt?style=flat-square\u0026logo=github\u0026color=green)](https://github.com/sauravbhattacharya001/prompt/graphs/contributors)\n[![Repo Size](https://img.shields.io/github/repo-size/sauravbhattacharya001/prompt?style=flat-square\u0026logo=github\u0026color=lightgrey)](https://github.com/sauravbhattacharya001/prompt)\n[![Dependabot](https://img.shields.io/badge/Dependabot-enabled-brightgreen?style=flat-square\u0026logo=dependabot)](https://github.com/sauravbhattacharya001/prompt/security/dependabot)\n\nSend prompts to Azure OpenAI and get responses — with templates, chains, safety guards, token management, version control, and a full prompt engineering toolkit. Zero boilerplate.\n\n[Installation](#installation) · [Quick Start](#quick-start) · [Full Class Library](#full-class-library) · [API Reference](#api-reference) · [Docs](https://sauravbhattacharya001.github.io/prompt/) · [Changelog](CHANGELOG.md)\n\n\u003c/div\u003e\n\n---\n\n## 🚀 Why Prompt?\n\nMost Azure OpenAI wrappers give you a thin HTTP client and call it a day. **Prompt** gives you the full toolkit:\n\n- **One line to start** — `await Main.GetResponseAsync(\"...\")` handles auth, retries, and connection pooling\n- **Templates + Chains** — build reusable, composable prompt pipelines without string concatenation\n- **Safety built in** — injection detection, token budgeting, and quality scoring out of the box\n- **100+ specialized classes** — from A/B testing to workflow orchestration, every prompt engineering pattern is covered\n- **Production-ready** — 1,000+ tests, NuGet package, Docker image, full docs site\n\nIf you've ever copy-pasted prompt strings across files, hand-rolled retry logic, or wondered if your prompt is vulnerable to injection — this library exists so you don't have to.\n\n---\n\n## ✨ Features\n\n### Core\n- **Single method call** — `GetResponseAsync()` handles everything\n- **Multi-turn conversations** — `Conversation` class maintains message history across turns\n- **Configurable parameters** — `PromptOptions` class with presets (`ForCodeGeneration()`, `ForCreativeWriting()`, etc.)\n- **Automatic retries** — Exponential backoff for 429 rate-limit and 503 errors\n- **Cancellation support** — Pass `CancellationToken` to cancel long-running requests\n- **Connection pooling** — Thread-safe singleton client with double-check locking\n\n### Prompt Engineering\n- **Templates** — `PromptTemplate` with `{{variable}}` placeholders, defaults, validation, and composition\n- **Chains** — `PromptChain` pipelines multiple prompts sequentially, each step's output feeding into the next\n- **Composer** — `PromptComposer` fluent builder for structured prompts (persona, context, task, constraints, examples, output format)\n- **Few-shot builder** — `FewShotBuilder` for structured few-shot prompt construction with 5 formats and token-budget awareness\n- **Library** — `PromptLibrary` central template registry with search, categories, tags, and 8 built-in templates\n- **Router** — `PromptRouter` intent-based routing with keyword/regex scoring and fallback support\n\n### Safety \u0026 Quality\n- **Guard** — `PromptGuard` injection detection (10 attack vectors), quality scoring (0–100, A–F grade), sanitization, and format wrapping\n- **Token budget** — `TokenBudget` auto-trims conversations to fit model context windows with 3 trim strategies\n- **Test suite** — `PromptTestSuite` automated prompt evaluation framework with 10 assertion types and pluggable response providers\n\n### Management\n- **Version manager** — `PromptVersionManager` version history, line-level diffs, and rollback for prompt templates\n- **Response parser** — `ResponseParser` extracts structured data (JSON, lists, tables, key-value pairs, code blocks) from LLM responses\n- **Serialization** — All classes support JSON round-trip (ToJson/FromJson/SaveToFileAsync/LoadFromFileAsync)\n\n### Infrastructure\n- **1,000+ tests** — Comprehensive xUnit test suite\n- **Cross-platform** — Environment variable resolution on Windows, Linux, and macOS\n- **NuGet ready** — Published as [`prompt-llm-aoi`](https://www.nuget.org/packages/prompt-llm-aoi)\n\n### Full Class Library\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003e🔧 Core Runtime\u003c/strong\u003e — The essentials for sending prompts and managing conversations\u003c/summary\u003e\n\n| Class | Description |\n|-------|-------------|\n| [`Main`](#maingettresponseasync) | Single-call Azure OpenAI completions with retries and cancellation |\n| [`Conversation`](#conversation-class) | Multi-turn message history with configurable model parameters |\n| `PromptOptions` | Model parameter presets (code generation, creative writing, data extraction, summarization) |\n| `PromptRetryPolicy` | Configurable retry with backoff, circuit breaker, and error classification |\n| `PromptCache` | Response caching with configurable expiration policies |\n| `PromptRateLimiter` | Request rate limiting and throttling |\n| `PromptFallbackChain` | Resilient multi-model execution with automatic fallback |\n| `PromptLoadBalancer` | Distribute requests across multiple endpoints |\n| `ResponseParser` | Extract JSON, lists, tables, key-value pairs, and code blocks from LLM responses |\n| `StreamChunk` | Typed chunk model for streaming response parsing |\n| `PromptStreamParser` | Real-time streaming content extraction |\n| `TokenBudget` | Context window management with 3 trim strategies and 15+ model presets |\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003e✏️ Prompt Engineering\u003c/strong\u003e — Templates, chains, composition, and routing\u003c/summary\u003e\n\n| Class | Description |\n|-------|-------------|\n| [`PromptTemplate`](#prompttemplate-class) | Reusable `{{variable}}` templates with defaults, validation, and composition |\n| [`PromptChain`](#promptchain-class) | Multi-step LLM pipeline with variable forwarding between steps |\n| `PromptComposer` | Fluent structured prompt builder with semantic sections and 4 presets |\n| `FewShotBuilder` | Structured few-shot prompt construction with 5 formats and token-budget integration |\n| `PromptLibrary` | Central template registry with CRUD, search by category/tag, merge, and 8 built-in templates |\n| `PromptRouter` | Intent-based prompt routing with keyword/regex scoring and fallback |\n| `PromptConditional` | Conditional logic for prompt templates |\n| `PromptContextBuilder` | Priority-based prompt context assembly with token budgeting |\n| `PromptContextCompressor` | Intelligent conversation context compression with 4 strategies |\n| `PromptInheritance` | Block-based template inheritance with `{{super}}` support |\n| `PromptInterpolator` | Pipe-based template variable transformations |\n| `PromptMerger` | Merge and combine multiple prompt templates |\n| `PromptPipeline` | Configurable prompt processing pipeline with middleware |\n| `PromptWorkflow` | DAG-based prompt workflow engine |\n| `PromptSignature` | Strongly-typed prompt signatures (DSPy-style) |\n| `PromptSamplerConfig` | LLM sampling parameter builder |\n| `PromptSchemaGenerator` | Fluent structured output schema builder |\n| `PromptToolFormatter` | Unified tool/function calling format across LLM providers |\n| `PromptSlotFiller` | Structured slot extraction and multi-turn filling |\n| `PromptExpander` | Expand compressed prompts into full form |\n| `PromptMinifier` | Prompt compression and whitespace optimization |\n| `PromptTokenOptimizer` | Token usage optimization and prompt compression |\n| `PromptSplitter` | Boundary-aware content chunking for long prompts |\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003e🛡️ Safety \u0026 Quality\u003c/strong\u003e — Injection detection, validation, compliance\u003c/summary\u003e\n\n| Class | Description |\n|-------|-------------|\n| `PromptGuard` | Injection detection (10 attack vectors), quality scoring, sanitization, and output format wrapping |\n| `PromptInjectionDetector` | Specialized prompt injection attack detection |\n| `PromptRiskAssessor` | Multi-dimensional security risk analysis for prompts |\n| `PromptSanitizer` | Prompt cleaning and normalization utility |\n| `PromptComplianceChecker` | Policy and regulatory compliance validation for prompts |\n| `PromptQualityGate` | Configurable pass/fail gate for prompt validation |\n| `PromptOutputValidator` | LLM response validation against configurable rules |\n| `PromptGrammarValidator` | Response format validation with 11 rule types (regex, JSON, length, structure) |\n| `PromptLinter` | Rule-based static analysis for LLM prompts |\n| `PromptBiasDetector` | Detect potential biases in prompts |\n| `PromptChecklist` | Pre-flight validation checklists |\n| `SerializationGuards` | Input validation and safety checks for deserialization |\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003e🧪 Testing \u0026 Evaluation\u003c/strong\u003e — Test suites, benchmarks, fuzzing\u003c/summary\u003e\n\n| Class | Description |\n|-------|-------------|\n| `PromptTestSuite` | Automated prompt evaluation with 10 assertion types and pluggable response providers |\n| `PromptBenchmarkSuite` | Benchmark prompt variants against test scenarios |\n| `PromptGoldenTester` | Snapshot testing for prompt outputs |\n| `PromptFuzzer` | Robustness testing — generates prompt variants via 7 mutation strategies |\n| `PromptABTester` | A/B testing framework for comparing prompt variant performance |\n| `PromptMatrix` | Combinatorial template variable testing |\n| `PromptResponseEvaluator` | Heuristic quality scoring across 5 dimensions |\n| `PromptScorecardBuilder` | Custom evaluation rubrics with weighted scoring |\n| `PromptConversationSimulator` | Simulated multi-turn conversations for testing |\n| `PromptDatasetBuilder` | Evaluation and fine-tuning dataset builder |\n| `PromptVariantGenerator` | Automated prompt variant generation for testing |\n| `PromptCoverageAnalyzer` | Library coverage analysis with health scoring |\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003e📊 Analytics \u0026 Observability\u003c/strong\u003e — Profiling, auditing, reporting\u003c/summary\u003e\n\n| Class | Description |\n|-------|-------------|\n| `PromptAnalytics` | Prompt usage analytics and metrics collection |\n| `PromptAuditLog` | Immutable hash-chained execution audit trail |\n| `PromptCostEstimator` | Token-based cost estimation for prompt execution |\n| `PromptCostOptimizer` | Cost optimization recommendations |\n| `PromptPerformanceProfiler` | Execution profiling with percentiles, comparison, and reports |\n| `PromptUsageReport` | Comprehensive usage reporting with time-bucketed breakdowns and cost analysis |\n| `PromptHistory` | Prompt execution history tracking and retrieval |\n| `PromptHealthCheck` | Library-wide quality analysis and health scoring |\n| `PromptHeatmap` | Visual prompt usage and performance heatmaps |\n| `PromptCanary` | Canary deployment monitoring for prompt changes |\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003e🔄 Versioning \u0026 Lifecycle\u003c/strong\u003e — Version control, snapshots, promotion\u003c/summary\u003e\n\n| Class | Description |\n|-------|-------------|\n| `PromptVersionManager` | Version history, line-level diffs, and rollback for templates |\n| `PromptSnapshotManager` | Point-in-time library snapshots with diff comparison and rollback |\n| `PromptPromotionManager` | Lifecycle stage management with approval gates and rollback |\n| `PromptDeprecationManager` | Deprecation tracking and migration |\n| `PromptChangeImpactAnalyzer` | Blast-radius analysis for prompt template changes |\n| `PromptChangelogGenerator` | Formatted changelogs from version history with multiple output formats |\n| `PromptDiff` | Line-level diff comparison between prompt versions |\n| `PromptDiffEngine` | Advanced diff computation engine |\n| `PromptDiffViewer` | Visual diff rendering |\n| `PromptMigrationAssistant` | Cross-provider prompt adaptation assistant |\n| `PromptFeatureFlag` | Feature-flagged prompt variants |\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003e🔍 Analysis \u0026 Intelligence\u003c/strong\u003e — Understanding, classifying, and improving prompts\u003c/summary\u003e\n\n| Class | Description |\n|-------|-------------|\n| `PromptDebugger` | Deep structural analysis — anti-pattern detection, clarity scoring, suggested fixes |\n| `PromptExplainer` | Analyze prompts for techniques, sections, and improvement suggestions |\n| `PromptComplexityScorer` | Multi-dimensional prompt complexity analysis |\n| `PromptIntentClassifier` | Intent classification for prompt routing |\n| `PromptMetadataExtractor` | Structured prompt analysis for routing and analytics |\n| `PromptEmotionAnalyzer` | Emotional tone analysis for prompts |\n| `PromptSimilarityAnalyzer` | Multi-metric prompt comparison and duplicate detection |\n| `PromptSemanticSearch` | Semantic similarity search across prompt libraries |\n| `PromptFingerprint` | Content-based prompt fingerprinting for deduplication |\n| `PromptDependencyGraph` | DAG analysis for prompt pipelines |\n| `PromptCompatibilityChecker` | Cross-provider prompt portability analysis |\n| `PromptRefactorer` | Automated prompt refactoring and optimization suggestions |\n| `PromptCoEvolver` | Co-evolutionary prompt improvement |\n| `PromptStyleTransfer` | Heuristic prompt tone and style rewriting |\n| `PromptNegotiator` | Iterative prompt refinement with validation feedback loops |\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003e📦 Import/Export \u0026 Tooling\u003c/strong\u003e — Serialization, formatting, documentation\u003c/summary\u003e\n\n| Class | Description |\n|-------|-------------|\n| `PromptAnnotation` | Structured inline comments and metadata for prompts |\n| `PromptCatalogExporter` | Export prompt library to HTML, CSV, and JSON formats |\n| `PromptMarkdownExporter` | Export and import prompt libraries as Markdown |\n| `PromptDocGenerator` | Auto-generate documentation from prompt templates |\n| `PromptChainVisualizer` | Mermaid, DOT, and ASCII flowchart generation from prompt chains |\n| `PromptFlowChart` | Visual flowchart generation |\n| `PromptChatFormatter` | Multi-provider chat message formatting |\n| `PromptLocalizer` | Prompt localization and translation management |\n| `PromptLocalizationManager` | Localization resource management |\n| `PromptAudienceAdapter` | Adapt prompts for different audience levels |\n| `PromptDialect` | Provider-specific prompt dialect conversion |\n| `PromptGlossary` | Domain-specific terminology management |\n| `PromptEnvironmentManager` | Environment-specific prompt configuration management |\n| `PromptBatchProcessor` | Batch execution of prompts with concurrency control |\n| `PromptReplayRecorder` | VCR-style prompt interaction recording and replay |\n| `PromptEnsemble` | Multi-response aggregation (majority vote, best-of-N, consensus) |\n| `PromptAutopilot` | Automated prompt improvement loops |\n| `PromptErrorRecovery` | Graceful error handling and recovery strategies |\n| `PromptArchetypeLibrary` | Pre-built prompt archetypes and patterns |\n| `PromptConflictDetector` | Detect conflicting prompt instructions |\n\n\u003c/details\u003e\n\n## Prerequisites\n\n- [.NET 8.0](https://dotnet.microsoft.com/download/dotnet/8.0) or later\n- An [Azure OpenAI](https://azure.microsoft.com/en-us/products/ai-services/openai-service) resource with a deployed model\n\n## Installation\n\n```bash\ndotnet add package prompt-llm-aoi\n```\n\n## Configuration\n\nSet the following environment variables:\n\n| Variable | Description | Example |\n|---|---|---|\n| `AZURE_OPENAI_API_URI` | Your Azure OpenAI endpoint URI | `https://myresource.openai.azure.com/` |\n| `AZURE_OPENAI_API_KEY` | Your Azure OpenAI API key | `sk-...` |\n| `AZURE_OPENAI_API_MODEL` | The deployed model name | `gpt-4` |\n\n\u003e **Note:** On Windows, the library checks Process → User → Machine scopes. On Linux/macOS, it reads from the process environment (shell exports, Docker env, systemd, etc.).\n\n## Quick Start\n\n```csharp\nusing Prompt;\n\n// Simple prompt (single-turn)\nstring? response = await Main.GetResponseAsync(\"Explain quantum computing in simple terms.\");\nConsole.WriteLine(response);\n```\n\n### With Custom Options\n\nUse `PromptOptions` to customize model behavior for any use case:\n\n```csharp\nusing Prompt;\n\n// Code generation — low temperature, high token limit\nvar codeOpts = PromptOptions.ForCodeGeneration();\nstring? code = await Main.GetResponseAsync(\n    \"Write a merge sort in C#\",\n    options: codeOpts);\n\n// Creative writing — high temperature\nvar creativeOpts = PromptOptions.ForCreativeWriting();\nstring? story = await Main.GetResponseAsync(\n    \"Write a short story about a time-traveling cat\",\n    options: creativeOpts);\n\n// Custom configuration\nvar custom = new PromptOptions\n{\n    Temperature = 0.4f,\n    MaxTokens = 4000,\n    TopP = 0.9f,\n    FrequencyPenalty = 0.3f,\n    PresencePenalty = 0.1f\n};\nstring? result = await Main.GetResponseAsync(\"Summarize this article...\", options: custom);\n```\n\n**Built-in presets:**\n\n| Preset | Temperature | MaxTokens | TopP | Use Case |\n|---|---|---|---|---|\n| `ForCodeGeneration()` | 0.1 | 4000 | 0.95 | Deterministic code output |\n| `ForCreativeWriting()` | 0.9 | 2000 | 0.9 | Stories, poems, creative text |\n| `ForDataExtraction()` | 0.0 | 2000 | 1.0 | JSON, structured output |\n| `ForSummarization()` | 0.3 | 1000 | 0.9 | Text summarization |\n\n## Multi-Turn Conversations\n\nThe `Conversation` class maintains message history so the model has full context:\n\n```csharp\nusing Prompt;\n\nvar conv = new Conversation(\"You are a helpful math tutor.\");\n\nstring? r1 = await conv.SendAsync(\"What is 2+2?\");\nConsole.WriteLine(r1); // \"4\"\n\nstring? r2 = await conv.SendAsync(\"Now multiply that by 3.\");\nConsole.WriteLine(r2); // \"12\" — the model remembers the context!\n\nstring? r3 = await conv.SendAsync(\"What was my first question?\");\nConsole.WriteLine(r3); // It knows: \"What is 2+2?\"\n```\n\n### Customizing Parameters\n\nEach conversation can have its own model parameters, either via `PromptOptions` or individual properties:\n\n```csharp\n// Using PromptOptions (recommended)\nvar opts = PromptOptions.ForCreativeWriting();\nvar conv = new Conversation(\"You are a creative writer.\", opts);\n\n// Or set properties individually\nvar conv2 = new Conversation(\"You are a creative writer.\")\n{\n    Temperature = 1.2f,     // More creative\n    MaxTokens = 2000,       // Longer responses\n    TopP = 0.9f,\n    FrequencyPenalty = 0.5f // Less repetition\n};\n\nstring? story = await conv.SendAsync(\"Write a short story about a robot.\");\n```\n\n### Replaying Conversations\n\nInject prior messages to give the model context from a previous session:\n\n```csharp\nvar conv = new Conversation(\"You are a coding assistant.\");\nconv.AddUserMessage(\"How do I sort a list in C#?\");\nconv.AddAssistantMessage(\"Use list.Sort() for in-place sorting or list.OrderBy() for LINQ.\");\n\n// Now continue the conversation with full context\nstring? response = await conv.SendAsync(\"Show me the LINQ version with a custom comparer.\");\n```\n\n### Conversation History\n\nExport the conversation for logging, serialization, or display:\n\n```csharp\nvar conv = new Conversation(\"System prompt\");\nconv.AddUserMessage(\"Hello\");\nconv.AddAssistantMessage(\"Hi there!\");\n\nList\u003c(string Role, string Content)\u003e history = conv.GetHistory();\nforeach (var (role, content) in history)\n    Console.WriteLine($\"[{role}] {content}\");\n\n// [system] System prompt\n// [user] Hello\n// [assistant] Hi there!\n```\n\n### Clearing History\n\nReset the conversation while preserving the system prompt:\n\n```csharp\nvar conv = new Conversation(\"You are helpful.\");\nconv.AddUserMessage(\"Hello\");\nconv.Clear(); // Removes user/assistant messages, keeps system prompt\n```\n\n### Save \u0026 Load Conversations\n\nSave a conversation to JSON and restore it later — perfect for persisting sessions across app restarts, sharing conversations, or implementing conversation history:\n\n```csharp\nvar conv = new Conversation(\"You are a coding tutor.\");\nawait conv.SendAsync(\"Explain SOLID principles\");\nawait conv.SendAsync(\"Show me an example of SRP\");\n\n// Save to JSON string\nstring json = conv.SaveToJson();\n\n// Save to file\nawait conv.SaveToFileAsync(\"session.json\");\n\n// Later... restore from JSON\nvar restored = Conversation.LoadFromJson(json);\n\n// Or restore from file\nvar fromFile = await Conversation.LoadFromFileAsync(\"session.json\");\n\n// Continue the conversation with full context\nstring? response = await fromFile.SendAsync(\"Now show me OCP\");\n```\n\nThe serialized JSON includes all messages and model parameters (temperature, max tokens, etc.), so the restored conversation is an exact replica:\n\n```json\n{\n  \"messages\": [\n    { \"role\": \"system\", \"content\": \"You are a coding tutor.\" },\n    { \"role\": \"user\", \"content\": \"Explain SOLID principles\" },\n    { \"role\": \"assistant\", \"content\": \"SOLID stands for...\" }\n  ],\n  \"parameters\": {\n    \"temperature\": 0.7,\n    \"maxTokens\": 800,\n    \"topP\": 0.95,\n    \"frequencyPenalty\": 0,\n    \"presencePenalty\": 0,\n    \"maxRetries\": 3\n  }\n}\n```\n\n## Prompt Templates\n\nThe `PromptTemplate` class lets you define reusable prompts with `{{variable}}` placeholders. Set defaults, validate inputs, compose templates together, and serialize them for sharing.\n\n### Basic Usage\n\n```csharp\nusing Prompt;\n\nvar template = new PromptTemplate(\n    \"You are a {{role}} assistant. Help the user with {{topic}}.\",\n    new Dictionary\u003cstring, string\u003e { [\"role\"] = \"helpful\" }\n);\n\n// Render with variables (role uses default, topic is provided)\nstring prompt = template.Render(new Dictionary\u003cstring, string\u003e\n{\n    [\"topic\"] = \"C# programming\"\n});\n// → \"You are a helpful assistant. Help the user with C# programming.\"\n```\n\n### Variable Introspection\n\n```csharp\nvar template = new PromptTemplate(\n    \"Translate {{text}} from {{source}} to {{target}}.\",\n    new Dictionary\u003cstring, string\u003e { [\"source\"] = \"English\" }\n);\n\nHashSet\u003cstring\u003e all = template.GetVariables();\n// { \"text\", \"source\", \"target\" }\n\nHashSet\u003cstring\u003e required = template.GetRequiredVariables();\n// { \"text\", \"target\" } — source has a default\n```\n\n### Strict vs. Non-Strict Rendering\n\n```csharp\nvar template = new PromptTemplate(\"Hello {{name}}, you are {{role}}!\");\n\n// Strict (default) — throws if variables are missing\ntemplate.Render(); // ❌ InvalidOperationException\n\n// Non-strict — leaves unresolved placeholders as-is\nstring result = template.Render(strict: false);\n// → \"Hello {{name}}, you are {{role}}!\"\n```\n\n### Composing Templates\n\nChain templates together to build complex prompts from reusable parts:\n\n```csharp\nvar persona = new PromptTemplate(\n    \"You are a {{role}} with expertise in {{domain}}.\",\n    new Dictionary\u003cstring, string\u003e { [\"role\"] = \"senior developer\" }\n);\n\nvar task = new PromptTemplate(\n    \"Review this code and suggest improvements:\\n{{code}}\");\n\nvar combined = persona.Compose(task);\n\nstring prompt = combined.Render(new Dictionary\u003cstring, string\u003e\n{\n    [\"domain\"] = \"C#\",\n    [\"code\"] = \"public void Foo() { /* ... */ }\"\n});\n```\n\n### Render \u0026 Send in One Call\n\nSkip the manual render step — send directly to Azure OpenAI:\n\n```csharp\n// Single-turn\nvar template = new PromptTemplate(\"Explain {{concept}} in simple terms.\");\nstring? response = await template.RenderAndSendAsync(\n    new Dictionary\u003cstring, string\u003e { [\"concept\"] = \"recursion\" },\n    systemPrompt: \"You are a teacher.\"\n);\n\n// Multi-turn (with existing Conversation)\nvar conv = new Conversation(\"You are a coding tutor.\");\nawait template.RenderAndSendAsync(conv,\n    new Dictionary\u003cstring, string\u003e { [\"concept\"] = \"closures\" });\n```\n\n### Save \u0026 Load Templates\n\n```csharp\nvar template = new PromptTemplate(\n    \"Summarize {{text}} in {{style}} style.\",\n    new Dictionary\u003cstring, string\u003e { [\"style\"] = \"concise\" }\n);\n\n// Save to file\nawait template.SaveToFileAsync(\"summarizer.json\");\n\n// Load from file\nvar loaded = await PromptTemplate.LoadFromFileAsync(\"summarizer.json\");\n\n// Or use JSON strings directly\nstring json = template.ToJson();\nvar restored = PromptTemplate.FromJson(json);\n```\n\n## Prompt Chains\n\nThe `PromptChain` class lets you build multi-step LLM pipelines where each step's output automatically becomes a variable for subsequent steps. Perfect for summarize-then-translate, extract-then-analyze, or any sequential reasoning pattern.\n\n### Basic Chain\n\n```csharp\nusing Prompt;\n\nvar chain = new PromptChain()\n    .AddStep(\"summarize\",\n        new PromptTemplate(\"Summarize this text in 2 sentences: {{text}}\"),\n        \"summary\")\n    .AddStep(\"translate\",\n        new PromptTemplate(\"Translate to French: {{summary}}\"),\n        \"french\")\n    .AddStep(\"keywords\",\n        new PromptTemplate(\"Extract 5 keywords from: {{summary}}\"),\n        \"keywords\");\n\nvar result = await chain.RunAsync(new Dictionary\u003cstring, string\u003e\n{\n    [\"text\"] = \"Your long article text here...\"\n});\n\nConsole.WriteLine(result.FinalResponse);          // keywords output\nConsole.WriteLine(result.GetOutput(\"summary\"));   // the summary\nConsole.WriteLine(result.GetOutput(\"french\"));    // the French translation\n```\n\n### Chain Configuration\n\n```csharp\nvar chain = new PromptChain()\n    .WithSystemPrompt(\"You are a precise analyst.\")\n    .WithMaxRetries(5)\n    .AddStep(\"extract\",\n        new PromptTemplate(\"Extract key facts from: {{document}}\"),\n        \"facts\")\n    .AddStep(\"analyze\",\n        new PromptTemplate(\"Analyze these facts for trends: {{facts}}\"),\n        \"analysis\");\n```\n\n### Validation\n\nCheck that all variables are satisfied before running (no API calls):\n\n```csharp\nvar chain = new PromptChain()\n    .AddStep(\"s1\", new PromptTemplate(\"Process: {{input}}\"), \"result\")\n    .AddStep(\"s2\", new PromptTemplate(\"Refine: {{result}}\"), \"final\");\n\nList\u003cstring\u003e errors = chain.Validate(\n    new Dictionary\u003cstring, string\u003e { [\"input\"] = \"test\" });\n\nif (errors.Count == 0)\n    Console.WriteLine(\"Chain is valid!\");\nelse\n    errors.ForEach(Console.WriteLine);\n```\n\n### Chain Results\n\nEvery step is tracked with timing, rendered prompts, and responses:\n\n```csharp\nvar result = await chain.RunAsync(initialVars);\n\nConsole.WriteLine($\"Total time: {result.TotalElapsed.TotalSeconds}s\");\nConsole.WriteLine($\"Steps: {result.Steps.Count}\");\n\nforeach (var step in result.Steps)\n{\n    Console.WriteLine($\"  [{step.StepName}] {step.Elapsed.TotalMilliseconds}ms\");\n    Console.WriteLine($\"    Prompt: {step.RenderedPrompt}\");\n    Console.WriteLine($\"    Response: {step.Response}\");\n}\n\n// Export results as JSON for logging/analysis\nstring json = result.ToJson();\n```\n\n### Save \u0026 Load Chains\n\n```csharp\nvar chain = new PromptChain()\n    .WithSystemPrompt(\"Be helpful\")\n    .AddStep(\"step1\", new PromptTemplate(\"Summarize: {{text}}\"), \"summary\");\n\n// Save to file\nawait chain.SaveToFileAsync(\"my-chain.json\");\n\n// Load from file\nvar loaded = await PromptChain.LoadFromFileAsync(\"my-chain.json\");\n\n// Or use JSON strings\nstring chainJson = chain.ToJson();\nvar restored = PromptChain.FromJson(chainJson);\n```\n\n## Usage Examples\n\n### System Prompt\n\nSet the assistant's behavior to control the style of responses:\n\n```csharp\nstring? response = await Main.GetResponseAsync(\n    \"Summarize this text: ...\",\n    systemPrompt: \"You are a concise summarizer. Respond in 2-3 sentences max.\");\n```\n\n### Cancellation\n\nCancel long-running requests with a timeout:\n\n```csharp\nusing var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10));\n\ntry\n{\n    string? response = await Main.GetResponseAsync(\"Hello!\", cancellationToken: cts.Token);\n}\ncatch (OperationCanceledException)\n{\n    Console.WriteLine(\"Request timed out.\");\n}\n```\n\n### Custom Retry Policy\n\nAdjust the retry count for transient failures:\n\n```csharp\n// Default: 3 retries with exponential backoff\nstring? response = await Main.GetResponseAsync(\"Hello!\");\n\n// Custom: 5 retries for high-reliability scenarios\nstring? response = await Main.GetResponseAsync(\"Hello!\", maxRetries: 5);\n```\n\n### Reset Client\n\nForce the client to re-read environment variables (useful for runtime config changes):\n\n```csharp\nMain.ResetClient();\n```\n\n## API Reference\n\n### `Main.GetResponseAsync()`\n\n```csharp\npublic static async Task\u003cstring?\u003e GetResponseAsync(\n    string prompt,\n    string? systemPrompt = null,\n    int maxRetries = 3,\n    CancellationToken cancellationToken = default)\n```\n\n| Parameter | Type | Default | Description |\n|---|---|---|---|\n| `prompt` | `string` | *(required)* | The user prompt to send |\n| `systemPrompt` | `string?` | `null` | Optional system prompt for assistant behavior |\n| `maxRetries` | `int` | `3` | Maximum retries for transient failures |\n| `cancellationToken` | `CancellationToken` | `default` | Token to cancel the operation |\n\n**Returns:** `Task\u003cstring?\u003e` — The model's response text, or `null` if no response was generated.\n\n**Throws:**\n- `ArgumentException` — if `prompt` is null or empty\n- `ArgumentOutOfRangeException` — if `maxRetries` is negative\n- `InvalidOperationException` — if required environment variables are missing\n- `OperationCanceledException` — if cancelled via token\n\n### `Main.ResetClient()`\n\n```csharp\npublic static void ResetClient()\n```\n\nClears the cached client, forcing re-initialization on the next call. Thread-safe.\n\n### `Conversation` Class\n\n```csharp\npublic class Conversation\n```\n\nMulti-turn conversation manager with full message history and configurable model parameters.\n\n#### Constructor\n\n| Parameter | Type | Default | Description |\n|---|---|---|---|\n| `systemPrompt` | `string?` | `null` | Optional system prompt for the entire conversation |\n\n#### Methods\n\n| Method | Returns | Description |\n|---|---|---|\n| `SendAsync(message, cancellationToken)` | `Task\u003cstring?\u003e` | Sends a message and returns the response. Both are added to history. |\n| `AddUserMessage(message)` | `void` | Adds a user message to history without calling the API. |\n| `AddAssistantMessage(message)` | `void` | Adds an assistant message to history without calling the API. |\n| `Clear()` | `void` | Clears history but preserves the system prompt. |\n| `GetHistory()` | `List\u003c(string Role, string Content)\u003e` | Returns a snapshot of the conversation. |\n| `SaveToJson(indented)` | `string` | Serializes the conversation (messages + parameters) to a JSON string. |\n| `LoadFromJson(json)` | `Conversation` | *Static.* Restores a conversation from a JSON string. |\n| `SaveToFileAsync(filePath, indented, cancellationToken)` | `Task` | Saves the conversation to a JSON file. |\n| `LoadFromFileAsync(filePath, cancellationToken)` | `Task\u003cConversation\u003e` | *Static.* Loads a conversation from a JSON file. |\n\n#### Properties\n\n| Property | Type | Default | Range | Description |\n|---|---|---|---|---|\n| `MessageCount` | `int` | — | — | Number of messages including system prompt |\n| `Temperature` | `float` | `0.7` | `0.0–2.0` | Sampling temperature |\n| `MaxTokens` | `int` | `800` | `≥ 1` | Maximum response tokens |\n| `TopP` | `float` | `0.95` | `0.0–1.0` | Nucleus sampling |\n| `FrequencyPenalty` | `float` | `0.0` | `-2.0–2.0` | Frequency penalty |\n| `PresencePenalty` | `float` | `0.0` | `-2.0–2.0` | Presence penalty |\n| `MaxRetries` | `int` | `3` | `≥ 0` | Retry count for transient failures |\n\n### `PromptTemplate` Class\n\n```csharp\npublic class PromptTemplate\n```\n\nReusable prompt template with `{{variable}}` placeholders, default values, and composition.\n\n#### Constructor\n\n| Parameter | Type | Default | Description |\n|---|---|---|---|\n| `template` | `string` | *(required)* | Template string with `{{variable}}` placeholders |\n| `defaults` | `Dictionary\u003cstring, string\u003e?` | `null` | Default values for variables |\n\n#### Methods\n\n| Method | Returns | Description |\n|---|---|---|\n| `Render(variables, strict)` | `string` | Renders the template by replacing placeholders. Strict mode throws on missing variables. |\n| `RenderAndSendAsync(variables, systemPrompt, maxRetries, cancellationToken)` | `Task\u003cstring?\u003e` | Renders and sends as a single-turn prompt via `Main.GetResponseAsync()`. |\n| `RenderAndSendAsync(conversation, variables, cancellationToken)` | `Task\u003cstring?\u003e` | Renders and sends as a message in an existing `Conversation`. |\n| `GetVariables()` | `HashSet\u003cstring\u003e` | Returns all variable names found in the template. |\n| `GetRequiredVariables()` | `HashSet\u003cstring\u003e` | Returns variable names that have no default value. |\n| `SetDefault(name, value)` | `void` | Sets or updates a default value for a variable. |\n| `RemoveDefault(name)` | `bool` | Removes a default value, making the variable required. |\n| `Compose(other, separator)` | `PromptTemplate` | Combines two templates with merged defaults. |\n| `ToJson(indented)` | `string` | Serializes the template to JSON. |\n| `FromJson(json)` | `PromptTemplate` | *Static.* Deserializes a template from JSON. |\n| `SaveToFileAsync(filePath, indented, cancellationToken)` | `Task` | Saves the template to a JSON file. |\n| `LoadFromFileAsync(filePath, cancellationToken)` | `Task\u003cPromptTemplate\u003e` | *Static.* Loads a template from a JSON file. |\n\n#### Properties\n\n| Property | Type | Description |\n|---|---|---|\n| `Template` | `string` | The raw template string |\n| `Defaults` | `IReadOnlyDictionary\u003cstring, string\u003e` | Read-only copy of default values |\n\n### `PromptChain` Class\n\n```csharp\npublic class PromptChain\n```\n\nMulti-step prompt pipeline where each step's output feeds into subsequent steps as template variables.\n\n#### Methods\n\n| Method | Returns | Description |\n|---|---|---|\n| `AddStep(name, template, outputVariable)` | `PromptChain` | Adds a step to the chain (fluent). Output variable must be unique. |\n| `WithSystemPrompt(systemPrompt)` | `PromptChain` | Sets the system prompt for all API calls (fluent). |\n| `WithMaxRetries(maxRetries)` | `PromptChain` | Sets the retry count for API calls (fluent). |\n| `RunAsync(initialVariables, cancellationToken)` | `Task\u003cChainResult\u003e` | Executes all steps sequentially. |\n| `Validate(initialVariables)` | `List\u003cstring\u003e` | Checks that all required variables are satisfiable (no API calls). |\n| `ToJson(indented)` | `string` | Serializes the chain definition to JSON. |\n| `FromJson(json)` | `PromptChain` | *Static.* Deserializes a chain from JSON. |\n| `SaveToFileAsync(filePath, indented, cancellationToken)` | `Task` | Saves the chain definition to a JSON file. |\n| `LoadFromFileAsync(filePath, cancellationToken)` | `Task\u003cPromptChain\u003e` | *Static.* Loads a chain from a JSON file. |\n\n#### Properties\n\n| Property | Type | Description |\n|---|---|---|\n| `StepCount` | `int` | Number of steps in the chain |\n| `Steps` | `IReadOnlyList\u003cChainStep\u003e` | Read-only view of chain steps |\n\n### `ChainResult` Class\n\n| Property / Method | Type | Description |\n|---|---|---|\n| `Steps` | `IReadOnlyList\u003cStepResult\u003e` | Ordered step results |\n| `Variables` | `IReadOnlyDictionary\u003cstring, string\u003e` | All accumulated variables |\n| `TotalElapsed` | `TimeSpan` | Total execution time |\n| `FinalResponse` | `string?` | Last step's response (convenience) |\n| `GetOutput(variableName)` | `string?` | Get a specific step's output by variable name |\n| `ToJson(indented)` | `string` | Serialize results to JSON for logging |\n\n### Default Model Parameters\n\n| Parameter | Value |\n|---|---|\n| Temperature | 0.7 |\n| Max Tokens | 800 |\n| Top P | 0.95 |\n| Frequency Penalty | 0 |\n| Presence Penalty | 0 |\n\n## Tech Stack\n\n| Component | Technology |\n|---|---|\n| Language | C# 12 |\n| Framework | .NET 8.0 |\n| SDK | [Azure.AI.OpenAI](https://www.nuget.org/packages/Azure.AI.OpenAI) 2.1.0 |\n| Retry | Azure.Core pipeline (exponential backoff with jitter) |\n| Security | [CodeQL](https://github.com/sauravbhattacharya001/prompt/actions/workflows/codeql.yml) |\n| Package | [NuGet](https://www.nuget.org/packages/prompt-llm-aoi) |\n\n## Architecture\n\n```\n┌─────────────────────────────────────────────────────┐\n│                 Your Application                    │\n└──────────────────────┬──────────────────────────────┘\n                       │\n┌──────────────────────▼──────────────────────────────┐\n│              Prompt Library (this)                   │\n│                                                     │\n│  ┌─── Prompt Engineering ─────────────────────────┐ │\n│  │ PromptTemplate  PromptChain   PromptComposer   │ │\n│  │ FewShotBuilder  PromptLibrary PromptRouter     │ │\n│  └────────────────────────────────────────────────┘ │\n│                                                     │\n│  ┌─── Safety \u0026 Quality ───────────────────────────┐ │\n│  │ PromptGuard  TokenBudget  PromptTestSuite      │ │\n│  └────────────────────────────────────────────────┘ │\n│                                                     │\n│  ┌─── Management ─────────────────────────────────┐ │\n│  │ PromptVersionManager  ResponseParser           │ │\n│  └────────────────────────────────────────────────┘ │\n│                                                     │\n│  ┌─── Runtime ────────────────────────────────────┐ │\n│  │ Main (Singleton)  Conversation  PromptOptions  │ │\n│  │ Env Config        Retry Pipeline               │ │\n│  └────────────────────────────────────────────────┘ │\n└──────────────────────┬──────────────────────────────┘\n                       │\n┌──────────────────────▼──────────────────────────────┐\n│            Azure OpenAI Service                     │\n│        Chat Completions API (GPT-4)                 │\n└─────────────────────────────────────────────────────┘\n```\n\n## Contributing\n\nContributions are welcome! Please:\n\n1. Fork the repository\n2. Create a feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit your changes (`git commit -m 'Add amazing feature'`)\n4. Push to the branch (`git push origin feature/amazing-feature`)\n5. Open a Pull Request\n\n## License\n\nThis project is licensed under the MIT License — see the [LICENSE](LICENSE) file for details.\n\n---\n\n\u003cdiv align=\"center\"\u003e\n\nMade by [Saurav Bhattacharya](https://github.com/sauravbhattacharya001)\n\n\u003c/div\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsauravbhattacharya001%2Fprompt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsauravbhattacharya001%2Fprompt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsauravbhattacharya001%2Fprompt/lists"}