{"id":20046262,"url":"https://github.com/chataize/utilities","last_synced_at":"2026-05-12T10:33:07.906Z","repository":{"id":260183338,"uuid":"879603022","full_name":"chataize/utilities","owner":"chataize","description":"Extensions and helper methods for ChatAIze projects.","archived":false,"fork":false,"pushed_at":"2025-12-22T11:44:39.000Z","size":288,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-12-23T22:47:42.922Z","etag":null,"topics":["case","char","chataize","comparison","conversion","csharp","dotnet","extension","extensions","format","helper","lib","library","normalization","static","string","tool","tools","util","utils"],"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":null,"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":"2024-10-28T08:11:24.000Z","updated_at":"2025-12-22T11:44:43.000Z","dependencies_parsed_at":"2024-11-16T00:15:27.001Z","dependency_job_id":"6e80a356-906d-459a-bc71-d30e34b5d515","html_url":"https://github.com/chataize/utilities","commit_stats":null,"previous_names":["chataize/utilities"],"tags_count":52,"template":false,"template_full_name":null,"purl":"pkg:github/chataize/utilities","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chataize%2Futilities","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chataize%2Futilities/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chataize%2Futilities/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chataize%2Futilities/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chataize","download_url":"https://codeload.github.com/chataize/utilities/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chataize%2Futilities/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32934528,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-12T09:19:52.626Z","status":"ssl_error","status_checked_at":"2026-05-12T09:17:33.438Z","response_time":102,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6: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":["case","char","chataize","comparison","conversion","csharp","dotnet","extension","extensions","format","helper","lib","library","normalization","static","string","tool","tools","util","utils"],"created_at":"2024-11-13T11:22:21.238Z","updated_at":"2026-05-12T10:33:07.898Z","avatar_url":"https://github.com/chataize.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ChatAIze.Utilities\nShared helpers and extensions used across the ChatAIze stack. This package is intentionally small and focused: it provides\nstring normalization, placeholder substitution, delegate invocation helpers for tool calls, and lightweight date parsing.\n\nIt is referenced by:\n- `ChatAIze.Chatbot` (host runtime and dashboard)\n- `ChatAIze.GenerativeCS` (tool schema and provider integration)\n- `ChatAIze.PluginApi` (plugin authoring helpers)\n- first-party plugins like `law-firm-plugin`\n\n## Install\n```bash\ndotnet add package ChatAIze.Utilities\n```\n\nTarget framework: `net10.0`. The package depends on `ChatAIze.Abstractions` for tool and workflow context types.\n\n## What this package contains\nNamespaces:\n- `ChatAIze.Utilities` for standalone helpers (for example `DateTimeOffsetParser`).\n- `ChatAIze.Utilities.Extensions` for extension methods used across the host and plugins.\n\nKey modules:\n- `StringExtension`: normalization, identifier casing, placeholder substitution.\n- `CharExtension`: simple Latin transliteration for diacritics.\n- `DictionaryExtensions`: tolerant JSON reads and placeholder expansion for dictionaries.\n- `DelegateExtensions`: tool/action/condition invocation helpers with validation.\n- `DateTimeOffsetExtension`: \"natural\" UI-friendly date formatting.\n- `DateTimeOffsetParser`: small natural-language date/time parser.\n\n## Where it is used in ChatAIze\nConcrete examples from the current codebase:\n- `ToSnakeLower` is used to normalize database titles and properties in `ChatAIze.Chatbot` and to generate tool schemas in\n  `ChatAIze.GenerativeCS`.\n- `NormalizedEquals` is used to match tool calls coming back from providers (OpenAI/Gemini) to registered functions.\n- `WithPlaceholderValues` is used to expand action settings and confirmation text in the workflow engine.\n- `TryGetSettingValue` is used in the action/condition UI builders to read settings with safe defaults.\n- `ToNaturalString` is used in dashboard UI timestamps (chat cards, account metadata, backups).\n- `DateTimeOffsetParser` is used in `law-firm-plugin` and in condition evaluation to parse date/time expressions.\n- `DelegateExtensions` is the standard path for invoking tool functions, workflow actions, and conditions.\n\n## Quick start\n```csharp\nusing ChatAIze.Utilities.Extensions;\n\nvar normalized = \"My Project Name\".ToSnakeLower(); // \"my_project_name\"\nvar equal = \"Sao Paulo\".NormalizedEquals(\"Sao-Paulo\"); // true\n\nvar template = \"Hello {user.name}, your order is {order_id}.\";\nvar placeholders = new Dictionary\u003cstring, string\u003e\n{\n    [\"UserName\"] = \"Marcel\",\n    [\"order_id\"] = \"A-123\"\n};\nvar message = template.WithPlaceholderValues(placeholders);\n```\n\n## String and character normalization\n`StringExtension` and `CharExtension` provide the normalization rules used throughout ChatAIze.\n\nHighlights:\n- `NormalizedEquals` compares strings by transliterating diacritics, ignoring punctuation/whitespace, and matching\n  ASCII letters/digits case-insensitively.\n- `ToSeparated`, `ToSnakeLower`, `ToKebabLower` normalize identifiers for use in tool schemas and settings keys.\n- `ToAlphanumeric` strips non-ASCII characters and optionally preserves `-` or `_` (whitespace normalizes to the chosen separator).\n- `ToLatin` maps a curated set of diacritics to ASCII-friendly characters.\n\nWarnings:\n- This is intentionally lossy. Do not use `NormalizedEquals` for security-sensitive comparisons (passwords, tokens).\n- Strings containing only punctuation normalize to an empty value, so they compare equal.\n- `ToSeparated` drops non-ASCII characters and splits on lower-to-upper transitions (for example \"ChatBot\" -\u003e \"chat_bot\").\n\n## Placeholder substitution\n`WithPlaceholderValues` exists for string templates and for dictionaries that contain JSON values.\n\nString templates:\n- Placeholder keys are normalized to snake_case.\n- Supported syntax includes `{key}`, `{key.sub_property}`, and `{key:sub_property}`.\n- Replacement is plain text, no escaping is performed.\n\nDictionary placeholders:\n- For `IReadOnlyDictionary\u003cstring, JsonElement\u003e`, string values are replaced directly.\n- For JSON objects/arrays, substitution occurs on raw JSON and then the JSON is reparsed.\n\nWarnings:\n- Placeholder replacement is not JSON-escaped. Make sure your placeholder values produce valid JSON after replacement.\n- Placeholders are simple and do not evaluate expressions; they just substitute strings.\n\n## Dictionary helpers\n`DictionaryExtensions` is designed for settings dictionaries used by actions and conditions.\n\nKey helpers:\n- `TryGetSettingValue\u003cT\u003e`: tolerant JSON read that returns a default value on deserialization errors.\n- `WithPlaceholderValues` overloads: apply placeholder substitution to strings and JSON data.\n\nTip: `TryGetSettingValue` is used heavily in `ChatAIze.Chatbot` action/condition builders to keep UI logic resilient to\nmissing or invalid settings values.\n\n## Delegate invocation helpers\n`DelegateExtensions` provides the standard binding and validation rules for ChatAIze tools and workflows.\n\nMain features:\n- `GetNormalizedMethodName` extracts stable names for delegates. Prefer named methods; lambdas can throw if the compiler\n  name is not recognized.\n- `InvokeForStringResultAsync` binds JSON arguments to function delegates, injects `IFunctionContext`/`CancellationToken`,\n  and serializes non-string results to snake_case JSON.\n- For actions, missing/invalid values mark the action as failed via `IActionContext.SetActionResult`.\n- For conditions, missing required values throw; callers should validate settings before invocation.\n\nValidation rules:\n- `Required`, `MinLength`, `MaxLength`, `StringLength` attributes are enforced on string parameters.\n- Enum parameters are parsed case-insensitively and tolerate underscores.\n\nWarnings:\n- Delegate exceptions are not swallowed; they propagate to the caller.\n- Tool invocation returns `\"Error: ...\"` strings for validation failures (not exceptions).\n\n## Date and time helpers\n### `DateTimeOffsetExtension.ToNaturalString`\nFormats timestamps for UI display:\n- English output, 24-hour time.\n- Uses a simple hour offset from UTC, not a time zone with DST rules.\n- Returns values like `Today, 13:37`, `Yesterday`, `Mon, 15:00`, or `2025-01-31`.\n\n### `DateTimeOffsetParser.Parse`\nA lightweight parser for human-friendly date/time expressions.\n\nSupported examples:\n- `now`, `today`, `tomorrow`, `next monday at 14:30`\n- `2025-01-31`, `31.01.2025`, `12/31/2025`\n- `utc+2`, `gmt-5`, `cest`\n\nLimitations and gotchas:\n- It is not a general NLP parser. Catch exceptions for untrusted input.\n- Parsing is anchored to `DateTimeOffset.UtcNow` and uses fixed offsets for time zones (no DST).\n- Ambiguous formats like `01/02/2025` are interpreted as `month/day/year`.\n- Day underflow (for example \"yesterday\" on the 1st) is not normalized and can throw.\n- The `at` keyword is detected by substring and can match inside other words.\n- A small Polish-to-English keyword map is applied after `ToLatin()` normalization.\n\n## Preview project\n`ChatAIze.Utilities.Preview` is a tiny console app used to demo placeholder replacement with `JsonElement` values.\nIt is not published as a package.\n\n## Related packages\n- `ChatAIze.Abstractions`: base interfaces referenced by `DelegateExtensions`.\n- `ChatAIze.PluginApi`: concrete helper implementations for plugin authors.\n- `ChatAIze.GenerativeCS`: tool schema generation, uses `ToSnakeLower` and `NormalizedEquals`.\n\n## Links\n- GitHub: https://github.com/chataize/utilities\n- Chataize organization: https://github.com/chataize\n- Website: https://www.chataize.com\n\n## License\nGPL-3.0-or-later. See `LICENSE` for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchataize%2Futilities","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchataize%2Futilities","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchataize%2Futilities/lists"}