{"id":20046281,"url":"https://github.com/chataize/generative-cs","last_synced_at":"2025-08-30T12:38:20.408Z","repository":{"id":217011840,"uuid":"732678718","full_name":"chataize/generative-cs","owner":"chataize","description":"Generative AI library for .NET 9.0 with built-in OpenAI ChatGPT and Google Gemini API clients and support for C# function calling via reflection.","archived":false,"fork":false,"pushed_at":"2025-08-26T13:52:28.000Z","size":809,"stargazers_count":44,"open_issues_count":2,"forks_count":13,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-08-26T18:45:44.345Z","etag":null,"topics":["ai","chatbot","chatgpt","chatgpt-api","csharp","dotnet","function-calling","gemini","gemini-api","gemini-pro","generative-ai","gpt","gpt-3","gpt-4","language-model","library","openai","openai-api"],"latest_commit_sha":null,"homepage":"https://www.chataize.com","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chataize.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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}},"created_at":"2023-12-17T13:43:43.000Z","updated_at":"2025-08-26T13:50:44.000Z","dependencies_parsed_at":"2024-01-31T18:30:57.931Z","dependency_job_id":"9a8e33ab-bd91-4c2c-ad05-af947d9d4094","html_url":"https://github.com/chataize/generative-cs","commit_stats":null,"previous_names":["chataize/generative-cs"],"tags_count":72,"template":false,"template_full_name":null,"purl":"pkg:github/chataize/generative-cs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chataize%2Fgenerative-cs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chataize%2Fgenerative-cs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chataize%2Fgenerative-cs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chataize%2Fgenerative-cs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chataize","download_url":"https://codeload.github.com/chataize/generative-cs/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chataize%2Fgenerative-cs/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272852281,"owners_count":25004053,"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-08-30T02:00:09.474Z","response_time":77,"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","chatbot","chatgpt","chatgpt-api","csharp","dotnet","function-calling","gemini","gemini-api","gemini-pro","generative-ai","gpt","gpt-3","gpt-4","language-model","library","openai","openai-api"],"created_at":"2024-11-13T11:22:33.271Z","updated_at":"2025-08-30T12:38:20.376Z","avatar_url":"https://github.com/chataize.png","language":"C#","readme":"# Generative CS\nGenerative AI library for .NET 9.0 with built-in OpenAI ChatGPT and Google Gemini API clients and support for C# function calling via reflection.\n\n![](https://github.com/chataize/generative-cs/assets/124832798/a0b46290-105d-487b-9145-6ce57a1879f7)\n\n## Supported Features\n### OpenAI\n- [x] Chat Completion\n- [x] Text Embedding\n- [x] Text-to-Speech\n- [x] Speech-to-Text\n    - [x] Transcription\n    - [x] Translation\n- [x] Moderation\n- [x] Response Streaming\n- [x] Function Calling\n- [ ] Image Generation\n- [ ] Assistants API\n- [ ] Files API\n### Gemini\n- [x] Chat Completion\n- [x] Function Calling\n- [ ] Text Embedding\n- [ ] Moderation\n- [ ] Response Streaming\n- [ ] Multi-Modal Requests\n### Miscellaneous\n- [x] Dependency Injection\n- [x] Time Awareness\n- [x] Message/Character Count Limiting\n- [x] Message Pinning\n- [x] Auto-Reattempt on Failure \n- [ ] Token Counting\n- [ ] XML Documentation\n- [ ] Unit Tests\n\n## Installation\n### .NET CLI\n```bash\ndotnet add package ChatAIze.GenerativeCS\n```\n### Package Manager Console\n```powershell\nInstall-Package ChatAIze.GenerativeCS\n```\n\n## Clients\n### Single Instance\n```cs\nusing ChatAIze.GenerativeCS.Clients;\n\nvar openAIClient = new OpenAIClient(\"\u003cOPENAI API KEY\u003e\");\nvar geminiClient = new GeminiClient(\"\u003cGEMINI API KEY\u003e\");\n```\n### Dependency Injection\n```cs\nusing ChatAIze.GenerativeCS.Extensions;\n\nbuilder.Services.AddOpenAIClient(\"\u003cOPENAI API KEY\u003e\");\nbuilder.Services.AddGeminiClient(\"\u003cGEMINI API KEY\u003e\");\n```\n\u003e [!NOTE]\n\u003e By default, both `OpenAIClient` and `GeminiClient` services are registered as singleton. It's advised not to change global client options after the web application has already been launched. Use per-request options instead.\n## Chat Completion\n### Simple Prompt\n```cs\nusing ChatAIze.GenerativeCS.Clients;\n\nvar client = new OpenAIClient(\"\u003cOPENAI API KEY\u003e\");\nstring response = await client.CompleteAsync(\"Write an article about Bitcoin.\");\n\nConsole.WriteLine(response);\n```\n### Streamed Prompt\n```cs\nusing ChatAIze.GenerativeCS.Clients;\n\nvar client = new OpenAIClient(\"\u003cOPENAI API KEY\u003e\");\nawait foreach (string chunk in client.StreamCompletionAsync(\"Write an article about Bitcoin.\"))\n{\n    Console.Write(chunk);\n}\n```\n### Chat\n```cs\nusing ChatAIze.GenerativeCS.Clients;\nusing ChatAIze.GenerativeCS.Models;\n\nvar client = new OpenAIClient(\"\u003cOPENAI API KEY\u003e\");\nvar chat = new Chat();\n\nwhile (true)\n{\n    string message = Console.ReadLine()!;\n    chat.FromUser(message);\n\n    string response = await client.CompleteAsync(chat);\n    Console.WriteLine(response);\n}   \n```\n### Streamed Chat\n```cs\nusing ChatAIze.GenerativeCS.Clients;\nusing ChatAIze.GenerativeCS.Models;\n\nvar client = new OpenAIClient(\"\u003cOPENAI API KEY\u003e\");\nvar chat = new Chat();\n\nwhile (true)\n{\n    string message = Console.ReadLine()!;\n    chat.FromUser(message);\n\n    await foreach (string chunk in client.StreamCompletionAsync(chat))\n    {\n        Console.Write(chunk);\n    }\n}\n```\n\u003e [!NOTE]\n\u003e Chatbot responses, function calls, and function results are automatically added to the chat.\n\u003e You don't need to and should not call ```chat.FromAssistant(...)``` manually, unless you want to *inject* custom messages (e.g. welcome message).\n## Embeddings\n```cs\nusing ChatAIze.GenerativeCS.Clients;\n\nvar client = new OpenAIClient(\"\u003cOPENAI API KEY\u003e\");\nfloat[] vectorEmbedding = await client.GetEmbeddingAsync(\"The quick brown fox jumps over the lazy dog\");\nstring base64Embedding = await client.GetBase64EmbeddingAsync(\"The quick brown fox jumps over the lazy dog\");\n```\n## Audio\n### Text-to-Speech\n#### Synthesize to File\n```cs\nvar client = new OpenAIClient(\"\u003cOPENAI API KEY\u003e\");\nawait client.SynthesizeSpeechAsync(\"The quick brown fox jumps over the lazy dog\", \"speech.mp3\");\n```\n#### Synthesize to Byte Array\n```cs\nusing ChatAIze.GenerativeCS.Clients;\n\nvar client = new OpenAIClient(\"\u003cOPENAI API KEY\u003e\");\nbyte[] speech = await client.SynthesizeSpeechAsync(\"The quick brown fox jumps over the lazy dog\");\n```\n### Speech-to-Text\n#### Transcript From File\n```cs\nusing ChatAIze.GenerativeCS.Clients;\n\nvar client = new OpenAIClient(\"\u003cOPENAI API KEY\u003e\");\nstring transcript = await client.TranscriptAsync(\"speech.mp3\");\n```\n#### Transcript From Byte Array\n```cs\nusing ChatAIze.GenerativeCS.Clients;\n\nvar client = new OpenAIClient(\"\u003cOPENAI API KEY\u003e\");\nbyte[] audio = await File.ReadAllBytesAsync(\"speech.mp3\");\nstring transcript = await client.TranscriptAsync(audio);\n```\n#### Translate From File\n```cs\nusing ChatAIze.GenerativeCS.Clients;\n\nvar client = new OpenAIClient(\"\u003cOPENAI API KEY\u003e\");\nstring translation = await client.TranslateAsync(\"speech.mp3\");\n```\n#### Translate From Byte Array\n```cs\nusing ChatAIze.GenerativeCS.Clients;\n\nvar client = new OpenAIClient(\"\u003cOPENAI API KEY\u003e\");\nbyte[] audio = await File.ReadAllBytesAsync(\"speech.mp3\");\nstring translation = await client.TranslateAsync(audio);\n```\n\n## Moderation\n```cs\nusing ChatAIze.GenerativeCS.Clients;\n\nvar client = new OpenAIClient(\"\u003cOPENAI API KEY\u003e\");\nvar result = await client.ModerateAsync(\"I am going to blow up your house in Minecraft.\");\n\nConsole.WriteLine(result.IsFlagged); // true\nConsole.WriteLine(result.IsViolence); // true \nConsole.WriteLine(result.ViolenceScore); // 0,908397912979126\n```\n\n## Options\n\u003e [!NOTE]\n\u003e Per-request options take precedence over default client options.\n\n\u003e [!TIP]\n\u003e If you use **OpenAI** client add:\n\u003e ```cs\n\u003e using ChatAIze.GenerativeCS.Options.OpenAI;\n\u003e ```\n\u003e If you use **Gemini** client add:\n\u003e ```cs\n\u003e using ChatAIze.GenerativeCS.Options.Gemini;\n\u003e ```\n### Dependency Injection\n#### OpenAI Client\n```cs\nusing ChatAIze.GenerativeCS.Constants;\nusing ChatAIze.GenerativeCS.Extensions;\n\nbuilder.Services.AddOpenAIClient(configure =\u003e\n{\n    configure.ApiKey = \"\u003cOPENAI API KEY\u003e\";\n    configure.DefaultCompletionOptions = new ChatCompletionOptions()\n    {\n        Model = ChatCompletionModels.OpenAI.GPT4o,\n        Temperature = 1.0\n        // set other chat completion options here\n    };\n    configure.DefaultEmbeddingOptions = new EmbeddingOptions()\n    {\n        Model = EmbeddingModels.OpenAI.TextEmbedding3Large,\n        MaxAttempts = 5\n        // set other embeding options here\n    };\n    // set other options here\n});\n```\n#### Gemini Client\n```cs\nusing ChatAIze.GenerativeCS.Constants;\nusing ChatAIze.GenerativeCS.Extensions;\n\nbuilder.Services.AddGeminiClient(configure =\u003e\n{\n    configure.ApiKey = \"\u003cGEMINI API KEY\u003e\";\n    configure.DefaultCompletionOptions = new ChatCompletionOptions()\n    {\n        Model = ChatCompletionModels.Gemini.GeminiPro,\n        MessageLimit = 10\n        // set other chat completion options here\n    };\n    // set other options here\n});\n```\n### Chat Completion\n#### OpenAI Client\n```cs\nusing ChatAIze.GenerativeCS.Clients;\nusing ChatAIze.GenerativeCS.Constants;\nusing ChatAIze.GenerativeCS.Models;\nusing ChatAIze.GenerativeCS.Options.OpenAI;\n\nvar options = new ChatCompletionOptions\n{\n    Model = ChatCompletionModels.OpenAI.GPT4o,\n    UserTrackingId = \"USER_ID_1234\",\n    MaxAttempts = 5,\n    MaxOutputTokens = 2000,\n    MessageLimit = 10,\n    CharacterLimit = 20000,\n    Seed = 1234,\n    Temperature = 1.0,\n    TopP = 1,\n    FrequencyPenalty = 0.0,\n    PresencePenalty = 0.0,\n    IsJsonMode = false,\n    IsTimeAware = true,\n    StopWords = [\"11.\", \"end\"],\n    Functions = [new ChatFunction(\"ToggleDarkMode\")],\n    DefaultFunctionCallback = async (name, arguments, cancellationToken) =\u003e\n    {\n        await Console.Out.WriteLineAsync($\"Function {name} called with arguments {arguments}\");\n        return new { Success = true, Property1 = \"ABC\", Property2 = 123 };\n    },\n    AddMessageCallback = async (message) =\u003e\n    {\n        // Called every time a new message is added, including function calls and results:\n        await Console.Out.WriteLineAsync($\"Message added: {message}\");\n    },\n    TimeCallback = () =\u003e DateTime.Now\n};\n\n// Set for entire client:\nvar client = new OpenAIClient(\"\u003cOPENAI API KEY\u003e\", options); // via constructor\nclient.DefaultCompletionOptions = options; // via property\n\n// Set for single request:\nstring response = await client.CompleteAsync(prompt, options);\nstring response = await client.CompleteAsync(chat, options);\n```\n#### Gemini Client\n```cs\nusing ChatAIze.GenerativeCS.Clients;\nusing ChatAIze.GenerativeCS.Constants;\nusing ChatAIze.GenerativeCS.Models;\nusing ChatAIze.GenerativeCS.Options.Gemini;\n\nvar options = new ChatCompletionOptions\n{\n    Model = ChatCompletionModels.Gemini.Gemini15Flash,\n    MaxAttempts = 5,\n    MessageLimit = 10,\n    CharacterLimit = 20000,\n    IsTimeAware = true,\n    Functions = [new ChatFunction(\"ToggleDarkMode\")],\n    DefaultFunctionCallback = async (name, arguments, cancellationToken) =\u003e\n    {\n        await Console.Out.WriteLineAsync($\"Function {name} called with arguments {arguments}\");\n        return new { Success = true, Property1 = \"ABC\", Property2 = 123 };\n    },\n    TimeCallback = () =\u003e DateTime.Now\n};\n\n// Set for entire client:\nvar client = new GeminiClient(\"\u003cGEMINI API KEY\u003e\", options); // via constructor\nclient.DefaultCompletionOptions = options; // via property\n\n// Set for single request:\nstring response = await client.CompleteAsync(prompt, options);\nstring response = await client.CompleteAsync(chat, options);\n```\n### Embeddings\n```cs\nusing ChatAIze.GenerativeCS.Clients;\nusing ChatAIze.GenerativeCS.Constants;\nusing ChatAIze.GenerativeCS.Options.OpenAI;\n\nvar options = new EmbeddingOptions\n{\n    Model = EmbeddingModels.OpenAI.TextEmbedding3Large,\n    User = \"USER_ID_1234\",\n    MaxAttempts = 5\n};\n\n// Set for entire client:\nvar client = new OpenAIClient(\"\u003cOPENAI API KEY\u003e\", options); // via constructor\nclient.DefaultEmbeddingOptions = options; // via property\n\n// Set for single request:\nfloat[] embedding = await client.GetEmbeddingAsync(\"The quick brown fox jumps over the lazy dog\", options);\n```\n### Audio\n#### Text-to-Speech\n```cs\nusing ChatAIze.GenerativeCS.Clients;\nusing ChatAIze.GenerativeCS.Constants;\nusing ChatAIze.GenerativeCS.Enums;\nusing ChatAIze.GenerativeCS.Options.OpenAI;\n\nvar options = new TextToSpeechOptions\n{\n    Model = TextToSpeechModels.OpenAI.TTS1,\n    Voice = TextToSpeechVoice.Alloy,\n    Speed = 1.0,\n    MaxAttempts = 5,\n    ResponseFormat = VoiceResponseFormat.MP3\n};\n\n// Set for entire client:\nvar client = new OpenAIClient(\"\u003cOPENAI API KEY\u003e\", options); // via constructor\nclient.DefaultTextToSpeechOptions = options; // via property\n\n// Set for single request:\nawait client.SynthesizeSpeechAsync(\"The quick brown fox jumps over the lazy dog\", \"speech.mp3\", options);\n```\n#### Transcription\n```cs\nusing ChatAIze.GenerativeCS.Clients;\nusing ChatAIze.GenerativeCS.Constants;\nusing ChatAIze.GenerativeCS.Enums;\nusing ChatAIze.GenerativeCS.Options.OpenAI;\n\nvar options = new TranscriptionOptions\n{\n    Model = SpeechRecognitionModels.OpenAI.Whisper1,\n    Language = \"en\",\n    Prompt = \"ZyntriQix, Digique Plus, CynapseFive, VortiQore V8, EchoNix Array, ...\",\n    Temperature = 0.0,\n    MaxAttempts = 5,\n    ResponseFormat = TranscriptionResponseFormat.Text\n};\n\n// Set for entire client:\nvar client = new OpenAIClient(\"\u003cOPENAI API KEY\u003e\", options); // via constructor\nclient.DefaultTranscriptionOptions = options; // via property\n\n// Set for single request:\nstring transcript = await client.TranscriptAsync(\"speech.mp3\", options);\n```\n#### Translation\n```cs\nusing ChatAIze.GenerativeCS.Clients;\nusing ChatAIze.GenerativeCS.Constants;\nusing ChatAIze.GenerativeCS.Enums;\nusing ChatAIze.GenerativeCS.Options.OpenAI;\n\nvar options = new TranslationOptions\n{\n    Model = SpeechRecognitionModels.OpenAI.Whisper1,\n    Prompt = \"ZyntriQix, Digique Plus, CynapseFive, VortiQore V8, EchoNix Array, ...\",\n    Temperature = 0.0,\n    MaxAttempts = 5,\n    ResponseFormat = TranscriptionResponseFormat.Text\n};\n\n// Set for entire client:\nvar client = new OpenAIClient(\"\u003cOPENAI API KEY\u003e\", options); // via constructor\nclient.DefaultTranslationOptions = options; // via property\n\n// Set for single request:\nstring translation = await client.TranslateAsync(\"speech.mp3\", options);\n```\n#### Moderation\n```cs\nusing ChatAIze.GenerativeCS.Clients;\nusing ChatAIze.GenerativeCS.Constants;\nusing ChatAIze.GenerativeCS.Options.OpenAI;\n\nvar options = new ModerationOptions\n{\n    Model = ModerationModels.OpenAI.TextModerationStable,\n    MaxAttempts = 5\n};\n\n// Set for entire client:\nvar client = new OpenAIClient(\"\u003cOPENAI API KEY\u003e\", options); // via constructor\nclient.DefaultModerationOptions = options; // via property\n\n// Set for single request:\nvar result = await client.ModerateAsync(\"I am going going to blow up your house in Minecraft.\", options);\n```\n\n## Function Calling\n### Top-Level Methods\n```cs\nusing ChatAIze.GenerativeCS.Options.OpenAI;\n// or\nusing ChatAIze.GenerativeCS.Options.Gemini;\n\nvoid ToggleDarkMode(bool isOn)\n{\n    Console.WriteLine($\"Dark mode set to: {isOn}\");\n}\n\nstring GetCurrentWeather(string location)\n{\n    return $\"The weather in {location} is 72 degrees and sunny.\";\n}\n\nasync Task\u003cobject\u003e SendEmailAsync(string recipient, string subject, string body)\n{\n    await Task.Delay(3000);\n    return new { Success = true, Property1 = \"ABC\", Property2 = 123 };\n}\n\nvar options = new ChatCompletionOptions();\n\noptions.AddFunction(ToggleDarkMode);\noptions.AddFunction(GetCurrentWeather);\noptions.AddFunction(SendEmailAsync);\n```\n### Static Class Methods\n```cs\nusing System.ComponentModel;\nusing ChatAIze.GenerativeCS.Options.OpenAI;\n// or\nusing ChatAIze.GenerativeCS.Options.Gemini;\n\nvar options = new ChatCompletionOptions();\n\noptions.AddFunction(SmartHome.CheckFrontCamera);\noptions.AddFunction(SmartHome.SetFrontDoorLockAsync);\noptions.AddFunction(SmartHome.SetTemperature);\n\npublic static class SmartHome\n{\n    [Description(\"Checks if there is someone waiting at the front door.\")]\n    public static object CheckFrontCamera()\n    {\n        return new { Success = true, IsPersonDetected = true };\n    }\n\n    public static async Task SetFrontDoorLockAsync(bool isLocked)\n    {\n        await Task.Delay(3000);\n        Console.WriteLine($\"Front door locked: {isLocked}\");\n    }\n\n    public static void SetTemperature(string room, int temperature)\n    {\n        Console.WriteLine($\"Temperature in {room} has been set to {temperature} degrees.\");\n    }\n}\n```\n### Class Instance Methods\n```cs\nusing ChatAIze.GenerativeCS.Options.OpenAI;\n// or\nusing ChatAIze.GenerativeCS.Options.Gemini;\n\nvar options = new ChatCompletionOptions();\nvar product = new Product();\n\noptions.AddFunction(product.GetDescription);\noptions.AddFunction(product.Rename);\noptions.AddFunction(product.Delete);\n\npublic class Product\n{\n    public string? Name { get; set; }\n\n    public string GetDescription()\n    {\n        return $\"This is a {Name}\";\n    }\n\n    public void Rename(string name)\n    {\n        Name = name;\n    }\n\n    public void Delete()\n    {\n        Console.WriteLine($\"Deleting product: {Name}\");\n    }\n}\n```\n### Anonymous Functions\n```cs\nusing ChatAIze.GenerativeCS.Options.OpenAI;\n// or\nusing ChatAIze.GenerativeCS.Options.Gemini;\n\nvar options = new ChatCompletionOptions();\n\noptions.AddFunction(\"GetCurrentWeather\", (string location) =\u003e \n{\n    return \"The current weather is sunny\";\n});\n\noptions.AddFunction(\"GetCurrentWeather\", async () =\u003e\n{\n    await Task.Delay(3000);\n    return \"The current weather is sunny\";\n});\n\noptions.AddFunction(\"GetCurrentWeather\", \"Gets the current weathe in default location.\", async () =\u003e\n{\n    await Task.Delay(3000);\n    return new WeatherData(20, 50);\n});\n\npublic record WeatherData(int Temperature, int Humidity);\n```\n### Default Function Callback\n```cs\nusing ChatAIze.GenerativeCS.Models;\nusing ChatAIze.GenerativeCS.Options.OpenAI;\n// or\nusing ChatAIze.GenerativeCS.Options.Gemini;\n\nvar options = new ChatCompletionOptions();\n\noptions.AddFunction(\"GetUserLocation\");\noptions.AddFunction(\"GetCurrentWeather\", new FunctionParameter(typeof(string), \"location\"));\n\nList\u003cFunctionParameter\u003e parameters = [new(typeof(string), \"room\"), new(typeof(int), \"temperature\")];\noptions.AddFunction(\"SetRoomTemperature\", parameters);\n\noptions.DefaultFunctionCallback = async (name, parameters, cancellationToken) =\u003e\n{\n    if (name == \"GetUserLocation\")\n    {\n        return \"London\";\n    }\n\n    if (name == \"GetCurrentWeather\")\n    {\n        return new { Temperature = 20, Weather = \"Sunny\" };\n    }\n\n    if (name == \"SetRoomTemperature\")\n    {\n        await Task.Delay(3000, cancellationToken);\n        return new { IsSuccess = true };\n    }\n\n    return new { Error = $\"Unknown function: {name}\" };\n};\n```\n\n## Additional Features\n### Time Awareness\nYou can configure both Gemini and OpenAI clients to be aware of the current date and time.\n```cs\nusing ChatAIze.GenerativeCS.Options.OpenAI;\n// or\nusing ChatAIze.GenerativeCS.Options.Gemini;\n\nvar options = new ChatCompletionOptions\n{\n    IsTimeAware = true,\n    // other completion options\n};\n```\nBy default, GenerativeCS uses `DateTime.Now`, but you can change the source of current time by specifying custom `TimeCallback`\n```cs\nusing ChatAIze.GenerativeCS.Options.OpenAI;\n// or\nusing ChatAIze.GenerativeCS.Options.Gemini;\n\nvar options = new ChatCompletionOptions\n{\n    IsTimeAware = true,\n    TimeCallback = () =\u003e new DateTime(2024, 1, 14),\n};\n```\n### Limits\n#### Message Limit\nThe maximum number of messages sent in a single chat completion request. The oldest messages will be removed one by one until the limit is satisfied.\n- Pinned messages count toward the limit and have priority but are never truncated.\n- The limit does include function calls and results. \n- Function definitions are not considered messages.\n```cs\nusing ChatAIze.GenerativeCS.Options.OpenAI;\n// or\nusing ChatAIze.GenerativeCS.Options.Gemini;\n\nvar options = new ChatCompletionOptions\n{\n    MessageLimit = 10,\n};\n```\n#### Character Limit\nThe maximum number of characters sent in a single chat completion request. The oldest messages will be removed one by one until the limit is satisfied.\n- Pinned messages count toward the limit and have priority but are never truncated.\n- The limit does include function calls and results. \n- Function definitions are not considered messages.\n```cs\nusing ChatAIze.GenerativeCS.Options.OpenAI;\n// or\nusing ChatAIze.GenerativeCS.Options.Gemini;\n\nvar options = new ChatCompletionOptions\n{\n    CharacterLimit = 10,\n};\n```\n### Message Pinning\nMessages can be pinned to ensure they stay in the chat even when message and character limits are exceeded.\n```cs\nusing ChatAIze.GenerativeCS.Enums;\nusing ChatAIze.GenerativeCS.Models;\n\nvar chat = new Chat();\n\nchat.FromUser(\"This will always be the first message\", PinLocation.Begin);\nchat.FromSystem(\"This message will never be truncated due to limits.\", PinLocation.Automatic);\nchat.FromUser(\"This will always be the last (most recent) message\", PinLocation.End);\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchataize%2Fgenerative-cs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchataize%2Fgenerative-cs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchataize%2Fgenerative-cs/lists"}