{"id":49407529,"url":"https://github.com/legionio/lex-llm-azure-foundry","last_synced_at":"2026-05-04T23:02:20.342Z","repository":{"id":354504711,"uuid":"1223641412","full_name":"LegionIO/lex-llm-azure-foundry","owner":"LegionIO","description":null,"archived":false,"fork":false,"pushed_at":"2026-05-01T23:11:15.000Z","size":38,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-02T21:03:27.665Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Ruby","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/LegionIO.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","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":"2026-04-28T14:12:22.000Z","updated_at":"2026-05-01T23:10:46.000Z","dependencies_parsed_at":"2026-05-03T22:00:35.057Z","dependency_job_id":null,"html_url":"https://github.com/LegionIO/lex-llm-azure-foundry","commit_stats":null,"previous_names":["legionio/lex-llm-azure-foundry"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/LegionIO/lex-llm-azure-foundry","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LegionIO%2Flex-llm-azure-foundry","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LegionIO%2Flex-llm-azure-foundry/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LegionIO%2Flex-llm-azure-foundry/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LegionIO%2Flex-llm-azure-foundry/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LegionIO","download_url":"https://codeload.github.com/LegionIO/lex-llm-azure-foundry/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LegionIO%2Flex-llm-azure-foundry/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32586187,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-03T06:36:36.687Z","status":"ssl_error","status_checked_at":"2026-05-03T06:36:09.306Z","response_time":103,"last_error":"SSL_read: 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":[],"created_at":"2026-04-28T22:00:56.194Z","updated_at":"2026-05-03T22:00:47.764Z","avatar_url":"https://github.com/LegionIO.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# lex-llm-azure-foundry\n\nLegionIO LLM provider extension for Azure AI Foundry Models and Azure OpenAI hosted deployments.\n\nThis gem lives under `Legion::Extensions::Llm::AzureFoundry` and depends on `lex-llm \u003e= 0.1.5` for shared provider-neutral routing, fleet, model-offering, readiness, canonical-alias, and schema primitives.\n\nLoad it with `require 'legion/extensions/llm/azure_foundry'`.\n\n## What It Provides\n\n- `Legion::Extensions::Llm::Provider` registration as `:azure_foundry`\n- Azure AI Foundry model inference chat completions through `POST /models/chat/completions?api-version=...`\n- Azure AI Foundry model inference embeddings through `POST /models/embeddings?api-version=...`\n- Azure AI Foundry model info health check through `GET /models/info?api-version=...` when `live: true`\n- Azure OpenAI v1-compatible endpoint support through `/openai/v1/chat/completions` and `/openai/v1/embeddings`\n- Deployment-name-preserving routing offerings for hosted Azure deployments\n- Explicit `model_family` and `canonical_model_alias` metadata for deployments whose base model cannot be proven from Azure metadata\n- Offline-first discovery from configured deployments\n- Shared OpenAI-compatible request and response mapping via `Legion::Extensions::Llm::Provider::OpenAICompatible`\n- Conservative token-counting metadata when no portable Azure token-counting REST endpoint is configured\n- Best-effort `llm.registry` event publishing for readiness and model availability via AMQP when transport is available\n\n## Architecture\n\n```\nLegion::Extensions::Llm::AzureFoundry\n├── Provider              # Azure AI Foundry and Azure OpenAI hosted provider surface\n│   └── Capabilities      # Capability predicates inferred from deployment metadata and model naming\n├── RegistryPublisher     # Best-effort async publisher for llm.registry availability events\n├── RegistryEventBuilder  # Builds sanitized lex-llm registry envelopes for provider state\n├── Transport/\n│   ├── Messages::RegistryEvent  # AMQP message for llm.registry events\n│   └── Exchanges::LlmRegistry  # Topic exchange for provider availability events\n└── VERSION\n```\n\n## File Map\n\n| Path | Purpose |\n|------|---------|\n| `lib/legion/extensions/llm/azure_foundry.rb` | Entry point, provider registration, default settings |\n| `lib/legion/extensions/llm/azure_foundry/provider.rb` | Provider implementation with chat, stream, embed, health, readiness, discovery |\n| `lib/legion/extensions/llm/azure_foundry/registry_publisher.rb` | Async registry event publishing with transport guards |\n| `lib/legion/extensions/llm/azure_foundry/registry_event_builder.rb` | Sanitized registry envelope construction |\n| `lib/legion/extensions/llm/azure_foundry/transport/messages/registry_event.rb` | AMQP message class for registry events |\n| `lib/legion/extensions/llm/azure_foundry/transport/exchanges/llm_registry.rb` | Topic exchange definition for llm.registry |\n| `lib/legion/extensions/llm/azure_foundry/version.rb` | `VERSION` constant |\n\n## Observability\n\nEvery class and module uses `Legion::Logging::Helper`:\n\n- **AzureFoundry** module: `extend Legion::Logging::Helper`\n- **Provider**: inherits `include Legion::Logging::Helper` from `Legion::Extensions::Llm::Provider`\n- **RegistryPublisher**: `include Legion::Logging::Helper`\n- **RegistryEventBuilder**: `include Legion::Logging::Helper`\n\nAll rescue blocks call `handle_exception(e, level:, handled:, operation:)` for structured exception reporting. Key actions emit info-level log lines including discover_offerings, health checks, readiness, model listing, chat, stream, embed, and registry publish operations.\n\n## API Contract\n\nThe implementation follows Microsoft Learn REST documentation for Azure AI Foundry Models:\n\n- Azure AI Foundry model inference endpoints use deployment names as the request `model`.\n- The model inference endpoint supports chat completions and embeddings.\n- The documented model-info endpoint is used only for explicit live health checks.\n- Azure deployment metadata is not assumed to reliably prove base model family or version, so routing metadata should be configured explicitly.\n\n## Defaults\n\n```ruby\nLegion::Extensions::Llm::AzureFoundry.default_settings\n# {\n#   provider_family: :azure_foundry,\n#   discovery: { enabled: true, live: false },\n#   instances: {\n#     default: {\n#       endpoint: \"https://\u003cresource\u003e.services.ai.azure.com\",\n#       api_version: \"2024-05-01-preview\",\n#       surface: :model_inference,\n#       tier: :frontier,\n#       transport: :http,\n#       credentials: {\n#         api_key: \"env://AZURE_INFERENCE_CREDENTIAL\",\n#         bearer_token: \"env://AZURE_FOUNDRY_BEARER_TOKEN\",\n#         entra_scope: \"https://cognitiveservices.azure.com/.default\"\n#       },\n#       deployments: [],\n#       usage: { inference: true, embedding: true, token_counting: false },\n#       limits: { concurrency: 4 }\n#     }\n#   }\n# }\n```\n\n## Configuration\n\n```ruby\nLegion::Extensions::Llm.configure do |config|\n  config.azure_foundry_endpoint = ENV.fetch(\"AZURE_FOUNDRY_ENDPOINT\")\n  config.azure_foundry_api_key = ENV[\"AZURE_INFERENCE_CREDENTIAL\"]\n  config.azure_foundry_bearer_token = ENV[\"AZURE_FOUNDRY_BEARER_TOKEN\"]\n  config.azure_foundry_api_version = \"2024-05-01-preview\"\n  config.azure_foundry_surface = :model_inference\n  config.azure_foundry_deployments = [\n    {\n      deployment: \"gpt-4o-prod\",\n      model_family: :openai,\n      canonical_model_alias: \"gpt-4o\",\n      usage_type: :inference\n    },\n    {\n      deployment: \"mistral-large-prod\",\n      model_family: :mistral,\n      canonical_model_alias: \"mistral-large\",\n      usage_type: :inference\n    },\n    {\n      deployment: \"embedding-prod\",\n      model_family: :openai,\n      canonical_model_alias: \"text-embedding-3-small\",\n      usage_type: :embedding\n    }\n  ]\nend\n```\n\nUse `config.azure_foundry_surface = :openai_v1` when the target endpoint should be treated as the OpenAI v1-compatible Azure route. The provider appends `/openai/v1` when the configured endpoint does not already include it.\n\n## Provider Methods\n\n```ruby\nprovider = Legion::Extensions::Llm::AzureFoundry.provider_class.new(Legion::Extensions::Llm.config)\n\nprovider.discover_offerings(live: false)\nprovider.offering_for(model: \"gpt-4o-prod\", model_family: :openai, canonical_model_alias: \"gpt-4o\")\nprovider.health(live: false)\nprovider.readiness(live: false)\nprovider.list_models\nprovider.chat(messages, model: \"gpt-4o-prod\")\nprovider.stream(messages, model: \"gpt-4o-prod\") { |chunk| puts chunk.content }\nprovider.embed([\"hello\"], model: \"embedding-prod\")\nprovider.count_tokens(messages, model: \"gpt-4o-prod\")\n```\n\n`discover_offerings(live: false)` never calls Azure. It maps configured deployments into `Legion::Extensions::Llm::Routing::ModelOffering` values with `provider_family: :azure_foundry`.\n\n`health(live: true)` calls the documented model-info endpoint for the configured model-inference surface. Keep `live: false` for startup paths and tests that must not require Azure.\n\n`count_tokens` returns a structured unsupported result by default because the Microsoft REST contract used here does not define a portable token-counting endpoint across Azure AI Foundry deployments.\n\n## Routing Metadata\n\nAzure deployments are aliases. A deployment name can hide provider, model, and version details, so this extension preserves the deployment name as `model` and treats `canonical_model_alias` and `model_family` as routing metadata.\n\nSupported `model_family` values are intentionally open-ended symbols, including:\n\n- `:openai`\n- `:mistral`\n- `:meta`\n- `:xai`\n- `:anthropic`\n- `:microsoft`\n\nWhen `model_family` or `canonical_model_alias` is missing, offerings include `requires_explicit_model_metadata: true`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flegionio%2Flex-llm-azure-foundry","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flegionio%2Flex-llm-azure-foundry","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flegionio%2Flex-llm-azure-foundry/lists"}