nemo-platform-plugin 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nemo_platform/__init__.py +117 -0
- nemo_platform/_base_client.py +2146 -0
- nemo_platform/_client.py +1200 -0
- nemo_platform/_compat.py +241 -0
- nemo_platform/_constants.py +29 -0
- nemo_platform/_decoders/jsonl.py +138 -0
- nemo_platform/_exceptions.py +123 -0
- nemo_platform/_files.py +188 -0
- nemo_platform/_models.py +967 -0
- nemo_platform/_qs.py +164 -0
- nemo_platform/_resource.py +58 -0
- nemo_platform/_response.py +872 -0
- nemo_platform/_streaming.py +391 -0
- nemo_platform/_types.py +288 -0
- nemo_platform/_utils/__init__.py +79 -0
- nemo_platform/_utils/_compat.py +60 -0
- nemo_platform/_utils/_datetime_parse.py +151 -0
- nemo_platform/_utils/_json.py +50 -0
- nemo_platform/_utils/_logs.py +40 -0
- nemo_platform/_utils/_path.py +142 -0
- nemo_platform/_utils/_proxy.py +80 -0
- nemo_platform/_utils/_reflection.py +57 -0
- nemo_platform/_utils/_resources_proxy.py +39 -0
- nemo_platform/_utils/_streams.py +27 -0
- nemo_platform/_utils/_sync.py +73 -0
- nemo_platform/_utils/_transform.py +472 -0
- nemo_platform/_utils/_typing.py +171 -0
- nemo_platform/_utils/_utils.py +448 -0
- nemo_platform/_version.py +21 -0
- nemo_platform/auth/__init__.py +15 -0
- nemo_platform/auth/device_flow.py +303 -0
- nemo_platform/auth/helpers.py +211 -0
- nemo_platform/auth/token_provider.py +239 -0
- nemo_platform/beta/evaluator/__init__.py +120 -0
- nemo_platform/beta/evaluator/agent_inference.py +360 -0
- nemo_platform/beta/evaluator/constants.py +4 -0
- nemo_platform/beta/evaluator/dataset_schemas/common.py +177 -0
- nemo_platform/beta/evaluator/dataset_schemas/compatibility.py +353 -0
- nemo_platform/beta/evaluator/dataset_schemas/templates.py +389 -0
- nemo_platform/beta/evaluator/datasets/__init__.py +28 -0
- nemo_platform/beta/evaluator/datasets/loader.py +415 -0
- nemo_platform/beta/evaluator/enums.py +64 -0
- nemo_platform/beta/evaluator/execution/_protocols.py +20 -0
- nemo_platform/beta/evaluator/execution/backends/base.py +86 -0
- nemo_platform/beta/evaluator/execution/backends/local/backend.py +132 -0
- nemo_platform/beta/evaluator/execution/benchmark_execution.py +666 -0
- nemo_platform/beta/evaluator/execution/config.py +64 -0
- nemo_platform/beta/evaluator/execution/evaluator.py +289 -0
- nemo_platform/beta/evaluator/execution/job_poll.py +98 -0
- nemo_platform/beta/evaluator/execution/metric_execution.py +878 -0
- nemo_platform/beta/evaluator/execution/pipeline.py +64 -0
- nemo_platform/beta/evaluator/execution/runs.py +143 -0
- nemo_platform/beta/evaluator/execution/scoring.py +224 -0
- nemo_platform/beta/evaluator/execution/utils.py +116 -0
- nemo_platform/beta/evaluator/execution/values.py +53 -0
- nemo_platform/beta/evaluator/inference.py +456 -0
- nemo_platform/beta/evaluator/metrics/aggregation.py +451 -0
- nemo_platform/beta/evaluator/metrics/bleu.py +94 -0
- nemo_platform/beta/evaluator/metrics/exact_match.py +52 -0
- nemo_platform/beta/evaluator/metrics/f1.py +50 -0
- nemo_platform/beta/evaluator/metrics/hooks.py +41 -0
- nemo_platform/beta/evaluator/metrics/llm_judge.py +392 -0
- nemo_platform/beta/evaluator/metrics/number_check.py +95 -0
- nemo_platform/beta/evaluator/metrics/protocol.py +241 -0
- nemo_platform/beta/evaluator/metrics/ragas/__init__.py +41 -0
- nemo_platform/beta/evaluator/metrics/ragas/base.py +521 -0
- nemo_platform/beta/evaluator/metrics/ragas/git_patch.py +36 -0
- nemo_platform/beta/evaluator/metrics/ragas/imports.py +192 -0
- nemo_platform/beta/evaluator/metrics/ragas/metrics.py +183 -0
- nemo_platform/beta/evaluator/metrics/remote.py +250 -0
- nemo_platform/beta/evaluator/metrics/rouge.py +71 -0
- nemo_platform/beta/evaluator/metrics/string_check.py +69 -0
- nemo_platform/beta/evaluator/metrics/template_rendering.py +141 -0
- nemo_platform/beta/evaluator/metrics/tool_calling.py +173 -0
- nemo_platform/beta/evaluator/metrics/types.py +62 -0
- nemo_platform/beta/evaluator/metrics/utils.py +54 -0
- nemo_platform/beta/evaluator/resilience/api.py +142 -0
- nemo_platform/beta/evaluator/resilience/classifier.py +142 -0
- nemo_platform/beta/evaluator/resilience/config.py +69 -0
- nemo_platform/beta/evaluator/resilience/errors.py +117 -0
- nemo_platform/beta/evaluator/resilience/policy.py +50 -0
- nemo_platform/beta/evaluator/resilience/scheduler.py +459 -0
- nemo_platform/beta/evaluator/resilience/types.py +93 -0
- nemo_platform/beta/evaluator/structured_output.py +184 -0
- nemo_platform/beta/evaluator/templates.py +115 -0
- nemo_platform/beta/evaluator/values/__init__.py +162 -0
- nemo_platform/beta/evaluator/values/agents.py +84 -0
- nemo_platform/beta/evaluator/values/common.py +28 -0
- nemo_platform/beta/evaluator/values/dataset_schemas.py +112 -0
- nemo_platform/beta/evaluator/values/datasets.py +28 -0
- nemo_platform/beta/evaluator/values/metrics.py +587 -0
- nemo_platform/beta/evaluator/values/models.py +157 -0
- nemo_platform/beta/evaluator/values/multi_metric_results.py +359 -0
- nemo_platform/beta/evaluator/values/params.py +109 -0
- nemo_platform/beta/evaluator/values/results.py +699 -0
- nemo_platform/beta/evaluator/values/scores.py +300 -0
- nemo_platform/beta/safe_synthesizer/__init__.py +4 -0
- nemo_platform/beta/safe_synthesizer/config.py +29 -0
- nemo_platform/beta/safe_synthesizer/job.py +309 -0
- nemo_platform/beta/safe_synthesizer/job_builder.py +355 -0
- nemo_platform/cli/__init__.py +4 -0
- nemo_platform/cli/app.py +321 -0
- nemo_platform/cli/commands/__init__.py +15 -0
- nemo_platform/cli/commands/api/__init__.py +114 -0
- nemo_platform/cli/commands/api/adapters.py +384 -0
- nemo_platform/cli/commands/api/files/__init__.py +237 -0
- nemo_platform/cli/commands/api/files/filesets.py +386 -0
- nemo_platform/cli/commands/api/files/otlp/__init__.py +12 -0
- nemo_platform/cli/commands/api/files/otlp/logs.py +116 -0
- nemo_platform/cli/commands/api/guardrail/__init__.py +270 -0
- nemo_platform/cli/commands/api/guardrail/configs.py +311 -0
- nemo_platform/cli/commands/api/iam/__init__.py +12 -0
- nemo_platform/cli/commands/api/iam/role_bindings.py +264 -0
- nemo_platform/cli/commands/api/inference/__init__.py +76 -0
- nemo_platform/cli/commands/api/inference/deployment_configs/__init__.py +370 -0
- nemo_platform/cli/commands/api/inference/deployment_configs/versions.py +132 -0
- nemo_platform/cli/commands/api/inference/deployments/__init__.py +565 -0
- nemo_platform/cli/commands/api/inference/deployments/versions.py +141 -0
- nemo_platform/cli/commands/api/inference/gateway/__init__.py +14 -0
- nemo_platform/cli/commands/api/inference/gateway/model.py +324 -0
- nemo_platform/cli/commands/api/inference/gateway/openai/__init__.py +12 -0
- nemo_platform/cli/commands/api/inference/gateway/openai/v1/__init__.py +12 -0
- nemo_platform/cli/commands/api/inference/gateway/openai/v1/models.py +106 -0
- nemo_platform/cli/commands/api/inference/gateway/provider.py +327 -0
- nemo_platform/cli/commands/api/inference/models.py +106 -0
- nemo_platform/cli/commands/api/inference/providers.py +612 -0
- nemo_platform/cli/commands/api/inference/virtual_models.py +412 -0
- nemo_platform/cli/commands/api/intake/__init__.py +18 -0
- nemo_platform/cli/commands/api/intake/apps/__init__.py +326 -0
- nemo_platform/cli/commands/api/intake/apps/tasks.py +340 -0
- nemo_platform/cli/commands/api/intake/entries/__init__.py +445 -0
- nemo_platform/cli/commands/api/intake/entries/events.py +118 -0
- nemo_platform/cli/commands/api/intake/evaluator_results.py +267 -0
- nemo_platform/cli/commands/api/intake/exports/__init__.py +63 -0
- nemo_platform/cli/commands/api/intake/exports/jobs.py +245 -0
- nemo_platform/cli/commands/api/intake/ingest/__init__.py +14 -0
- nemo_platform/cli/commands/api/intake/ingest/atif.py +115 -0
- nemo_platform/cli/commands/api/intake/ingest/chat_completions.py +125 -0
- nemo_platform/cli/commands/api/intake/ingest/otlp/__init__.py +12 -0
- nemo_platform/cli/commands/api/intake/ingest/otlp/v1/__init__.py +12 -0
- nemo_platform/cli/commands/api/intake/ingest/otlp/v1/traces.py +72 -0
- nemo_platform/cli/commands/api/intake/spans/__init__.py +202 -0
- nemo_platform/cli/commands/api/intake/spans/evaluator_results.py +65 -0
- nemo_platform/cli/commands/api/intake/traces.py +183 -0
- nemo_platform/cli/commands/api/jobs/__init__.py +576 -0
- nemo_platform/cli/commands/api/jobs/results.py +211 -0
- nemo_platform/cli/commands/api/jobs/steps.py +243 -0
- nemo_platform/cli/commands/api/jobs/tasks.py +210 -0
- nemo_platform/cli/commands/api/members.py +304 -0
- nemo_platform/cli/commands/api/models/__init__.py +555 -0
- nemo_platform/cli/commands/api/models/adapters.py +261 -0
- nemo_platform/cli/commands/api/projects.py +332 -0
- nemo_platform/cli/commands/api/safe_synthesizer/__init__.py +12 -0
- nemo_platform/cli/commands/api/safe_synthesizer/jobs/__init__.py +417 -0
- nemo_platform/cli/commands/api/safe_synthesizer/jobs/results.py +211 -0
- nemo_platform/cli/commands/api/secrets/__init__.py +315 -0
- nemo_platform/cli/commands/api/secrets/admin.py +44 -0
- nemo_platform/cli/commands/api/workspaces.py +339 -0
- nemo_platform/cli/commands/auth.py +803 -0
- nemo_platform/cli/commands/config.py +308 -0
- nemo_platform/cli/commands/docs.py +277 -0
- nemo_platform/cli/commands/manifest_registry.py +180 -0
- nemo_platform/cli/commands/plugins.py +87 -0
- nemo_platform/cli/commands/quickstart/__init__.py +15 -0
- nemo_platform/cli/commands/quickstart/cli.py +1178 -0
- nemo_platform/cli/commands/services/_process.py +472 -0
- nemo_platform/cli/commands/services/cli.py +694 -0
- nemo_platform/cli/commands/setup.py +1947 -0
- nemo_platform/cli/commands/skills/agents/claude.py +29 -0
- nemo_platform/cli/commands/skills/agents/codex.py +32 -0
- nemo_platform/cli/commands/skills/agents/cursor.py +18 -0
- nemo_platform/cli/commands/skills/agents/opencode.py +20 -0
- nemo_platform/cli/commands/skills/base.py +53 -0
- nemo_platform/cli/commands/skills/cli.py +313 -0
- nemo_platform/cli/commands/skills/installer.py +51 -0
- nemo_platform/cli/commands/skills/registry.py +396 -0
- nemo_platform/cli/commands/use_cases/__init__.py +15 -0
- nemo_platform/cli/commands/use_cases/agent.py +245 -0
- nemo_platform/cli/commands/use_cases/chat.py +965 -0
- nemo_platform/cli/commands/use_cases/wait.py +151 -0
- nemo_platform/cli/core/__init__.py +8 -0
- nemo_platform/cli/core/agent_helpers.py +84 -0
- nemo_platform/cli/core/api.py +160 -0
- nemo_platform/cli/core/autocomplete.py +63 -0
- nemo_platform/cli/core/code_generator.py +306 -0
- nemo_platform/cli/core/context.py +179 -0
- nemo_platform/cli/core/errors.py +349 -0
- nemo_platform/cli/core/formatters.py +718 -0
- nemo_platform/cli/core/help_formatter.py +868 -0
- nemo_platform/cli/core/lazy_load.py +187 -0
- nemo_platform/cli/core/logging.py +24 -0
- nemo_platform/cli/core/pagination.py +255 -0
- nemo_platform/cli/core/stdin_utils.py +233 -0
- nemo_platform/cli/core/streaming.py +30 -0
- nemo_platform/cli/core/table_config.py +302 -0
- nemo_platform/cli/core/timestamp_formatter.py +127 -0
- nemo_platform/cli/core/types.py +112 -0
- nemo_platform/cli/core/waiters.py +339 -0
- nemo_platform/cli/manifest.py +108 -0
- nemo_platform/client/__init__.py +15 -0
- nemo_platform/client/factory.py +597 -0
- nemo_platform/config/README.md +168 -0
- nemo_platform/config/__init__.py +23 -0
- nemo_platform/config/config.py +538 -0
- nemo_platform/config/models.py +377 -0
- nemo_platform/config/types.py +7 -0
- nemo_platform/filesets/__init__.py +19 -0
- nemo_platform/filesets/filesystem/callbacks.py +229 -0
- nemo_platform/filesets/filesystem/filesystem.py +940 -0
- nemo_platform/filesets/resources.py +1120 -0
- nemo_platform/lib/.keep +4 -0
- nemo_platform/models/__init__.py +14 -0
- nemo_platform/models/resources.py +836 -0
- nemo_platform/pagination.py +149 -0
- nemo_platform/py.typed +0 -0
- nemo_platform/quickstart/__init__.py +99 -0
- nemo_platform/quickstart/cluster.py +198 -0
- nemo_platform/quickstart/config.py +402 -0
- nemo_platform/quickstart/container.py +758 -0
- nemo_platform/quickstart/gpu_config.py +111 -0
- nemo_platform/quickstart/platform_config.py +82 -0
- nemo_platform/quickstart/preflight.py +451 -0
- nemo_platform/quickstart/prompts.py +426 -0
- nemo_platform/quickstart/storage.py +90 -0
- nemo_platform/quickstart/validators.py +268 -0
- nemo_platform/resources/__init__.py +16 -0
- nemo_platform/resources/adapters/__init__.py +34 -0
- nemo_platform/resources/adapters/adapters.py +704 -0
- nemo_platform/resources/adapters/api.md +15 -0
- nemo_platform/resources/audit/__init__.py +16 -0
- nemo_platform/resources/entities/__init__.py +34 -0
- nemo_platform/resources/entities/api.md +16 -0
- nemo_platform/resources/entities/entities.py +1014 -0
- nemo_platform/resources/evaluation/__init__.py +118 -0
- nemo_platform/resources/evaluation/api.md +303 -0
- nemo_platform/resources/evaluation/benchmark_job_results.py +541 -0
- nemo_platform/resources/evaluation/benchmark_jobs/__init__.py +48 -0
- nemo_platform/resources/evaluation/benchmark_jobs/benchmark_jobs.py +900 -0
- nemo_platform/resources/evaluation/benchmark_jobs/results/__init__.py +76 -0
- nemo_platform/resources/evaluation/benchmark_jobs/results/aggregate_scores.py +197 -0
- nemo_platform/resources/evaluation/benchmark_jobs/results/artifacts.py +206 -0
- nemo_platform/resources/evaluation/benchmark_jobs/results/results.py +516 -0
- nemo_platform/resources/evaluation/benchmark_jobs/results/row_scores.py +213 -0
- nemo_platform/resources/evaluation/benchmarks.py +690 -0
- nemo_platform/resources/evaluation/evaluation.py +277 -0
- nemo_platform/resources/evaluation/metric_job_results.py +533 -0
- nemo_platform/resources/evaluation/metric_jobs/__init__.py +48 -0
- nemo_platform/resources/evaluation/metric_jobs/metric_jobs.py +888 -0
- nemo_platform/resources/evaluation/metric_jobs/results/__init__.py +76 -0
- nemo_platform/resources/evaluation/metric_jobs/results/aggregate_scores.py +197 -0
- nemo_platform/resources/evaluation/metric_jobs/results/artifacts.py +206 -0
- nemo_platform/resources/evaluation/metric_jobs/results/results.py +512 -0
- nemo_platform/resources/evaluation/metric_jobs/results/row_scores.py +213 -0
- nemo_platform/resources/evaluation/metrics.py +3495 -0
- nemo_platform/resources/files/__init__.py +62 -0
- nemo_platform/resources/files/api.md +65 -0
- nemo_platform/resources/files/files.py +683 -0
- nemo_platform/resources/files/filesets.py +783 -0
- nemo_platform/resources/files/otlp/__init__.py +48 -0
- nemo_platform/resources/files/otlp/logs.py +337 -0
- nemo_platform/resources/files/otlp/otlp.py +117 -0
- nemo_platform/resources/guardrail/__init__.py +48 -0
- nemo_platform/resources/guardrail/api.md +116 -0
- nemo_platform/resources/guardrail/configs.py +679 -0
- nemo_platform/resources/guardrail/guardrail.py +463 -0
- nemo_platform/resources/iam/__init__.py +48 -0
- nemo_platform/resources/iam/api.md +22 -0
- nemo_platform/resources/iam/iam.py +117 -0
- nemo_platform/resources/iam/role_bindings.py +537 -0
- nemo_platform/resources/inference/__init__.py +118 -0
- nemo_platform/resources/inference/api.md +224 -0
- nemo_platform/resources/inference/deployment_configs/__init__.py +48 -0
- nemo_platform/resources/inference/deployment_configs/deployment_configs.py +756 -0
- nemo_platform/resources/inference/deployment_configs/versions.py +418 -0
- nemo_platform/resources/inference/deployments/__init__.py +48 -0
- nemo_platform/resources/inference/deployments/deployments.py +1017 -0
- nemo_platform/resources/inference/deployments/versions.py +434 -0
- nemo_platform/resources/inference/gateway/__init__.py +76 -0
- nemo_platform/resources/inference/gateway/gateway.py +181 -0
- nemo_platform/resources/inference/gateway/model.py +708 -0
- nemo_platform/resources/inference/gateway/openai/__init__.py +48 -0
- nemo_platform/resources/inference/gateway/openai/openai.py +700 -0
- nemo_platform/resources/inference/gateway/openai/v1/__init__.py +48 -0
- nemo_platform/resources/inference/gateway/openai/v1/models.py +290 -0
- nemo_platform/resources/inference/gateway/openai/v1/v1.py +117 -0
- nemo_platform/resources/inference/gateway/provider.py +749 -0
- nemo_platform/resources/inference/inference.py +277 -0
- nemo_platform/resources/inference/models.py +290 -0
- nemo_platform/resources/inference/providers.py +1049 -0
- nemo_platform/resources/inference/virtual_models.py +846 -0
- nemo_platform/resources/intake/__init__.py +132 -0
- nemo_platform/resources/intake/api.md +268 -0
- nemo_platform/resources/intake/apps/__init__.py +48 -0
- nemo_platform/resources/intake/apps/apps.py +718 -0
- nemo_platform/resources/intake/apps/tasks.py +731 -0
- nemo_platform/resources/intake/entries/__init__.py +48 -0
- nemo_platform/resources/intake/entries/entries.py +855 -0
- nemo_platform/resources/intake/entries/events.py +320 -0
- nemo_platform/resources/intake/evaluator_results.py +512 -0
- nemo_platform/resources/intake/exports/__init__.py +48 -0
- nemo_platform/resources/intake/exports/exports.py +229 -0
- nemo_platform/resources/intake/exports/jobs.py +464 -0
- nemo_platform/resources/intake/ingest/__init__.py +76 -0
- nemo_platform/resources/intake/ingest/atif.py +242 -0
- nemo_platform/resources/intake/ingest/chat_completions.py +270 -0
- nemo_platform/resources/intake/ingest/ingest.py +181 -0
- nemo_platform/resources/intake/ingest/otlp/__init__.py +48 -0
- nemo_platform/resources/intake/ingest/otlp/otlp.py +117 -0
- nemo_platform/resources/intake/ingest/otlp/v1/__init__.py +48 -0
- nemo_platform/resources/intake/ingest/otlp/v1/traces.py +183 -0
- nemo_platform/resources/intake/ingest/otlp/v1/v1.py +117 -0
- nemo_platform/resources/intake/intake.py +309 -0
- nemo_platform/resources/intake/spans/__init__.py +48 -0
- nemo_platform/resources/intake/spans/evaluator_results.py +197 -0
- nemo_platform/resources/intake/spans/spans.py +367 -0
- nemo_platform/resources/intake/traces.py +351 -0
- nemo_platform/resources/jobs/__init__.py +76 -0
- nemo_platform/resources/jobs/api.md +118 -0
- nemo_platform/resources/jobs/jobs.py +1300 -0
- nemo_platform/resources/jobs/results.py +555 -0
- nemo_platform/resources/jobs/steps.py +491 -0
- nemo_platform/resources/jobs/tasks.py +470 -0
- nemo_platform/resources/members/__init__.py +34 -0
- nemo_platform/resources/members/api.md +19 -0
- nemo_platform/resources/members/members.py +634 -0
- nemo_platform/resources/models/__init__.py +48 -0
- nemo_platform/resources/models/adapters.py +514 -0
- nemo_platform/resources/models/api.md +44 -0
- nemo_platform/resources/models/models.py +981 -0
- nemo_platform/resources/projects/__init__.py +34 -0
- nemo_platform/resources/projects/api.md +21 -0
- nemo_platform/resources/projects/projects.py +736 -0
- nemo_platform/resources/safe_synthesizer/__init__.py +48 -0
- nemo_platform/resources/safe_synthesizer/api.md +62 -0
- nemo_platform/resources/safe_synthesizer/jobs/__init__.py +48 -0
- nemo_platform/resources/safe_synthesizer/jobs/jobs.py +895 -0
- nemo_platform/resources/safe_synthesizer/jobs/results.py +819 -0
- nemo_platform/resources/safe_synthesizer/safe_synthesizer.py +117 -0
- nemo_platform/resources/secrets/__init__.py +48 -0
- nemo_platform/resources/secrets/admin.py +150 -0
- nemo_platform/resources/secrets/api.md +34 -0
- nemo_platform/resources/secrets/secrets.py +756 -0
- nemo_platform/resources/workspaces/__init__.py +34 -0
- nemo_platform/resources/workspaces/api.md +20 -0
- nemo_platform/resources/workspaces/workspaces.py +734 -0
- nemo_platform/skills/__init__.py +28 -0
- nemo_platform/skills/inference/SKILL.md +564 -0
- nemo_platform/skills/nemo-build-agent/SKILL.md +221 -0
- nemo_platform/skills/nemo-build-agent/references/templates/data-designer-config.py +80 -0
- nemo_platform/skills/nemo-evaluator/SKILL.md +140 -0
- nemo_platform/skills/nemo-explore/SKILL.md +70 -0
- nemo_platform/skills/nemo-files/SKILL.md +81 -0
- nemo_platform/skills/nemo-fine-tune/SKILL.md +43 -0
- nemo_platform/skills/nemo-guardrails/SKILL.md +519 -0
- nemo_platform/skills/nemo-secrets/SKILL.md +60 -0
- nemo_platform/skills/nemo-skill-selection/SKILL.md +146 -0
- nemo_platform/skills/nemo-spec/SKILL.md +76 -0
- nemo_platform/skills/nemo-spec/references/templates/agent-spec.md +68 -0
- nemo_platform/skills/nemo-status/SKILL.md +115 -0
- nemo_platform/skills/nemo-teardown/SKILL.md +185 -0
- nemo_platform/skills/nemo-try-agent/SKILL.md +102 -0
- nemo_platform/types/__init__.py +54 -0
- nemo_platform/types/adapters/__init__.py +24 -0
- nemo_platform/types/adapters/adapter_create_params.py +63 -0
- nemo_platform/types/adapters/adapter_entity_filter_param.py +56 -0
- nemo_platform/types/adapters/adapter_list_params.py +46 -0
- nemo_platform/types/adapters/adapter_patch_params.py +35 -0
- nemo_platform/types/adapters/adapters_page.py +37 -0
- nemo_platform/types/audit/__init__.py +18 -0
- nemo_platform/types/audit/jobs/__init__.py +18 -0
- nemo_platform/types/entities/__init__.py +26 -0
- nemo_platform/types/entities/entities_page.py +37 -0
- nemo_platform/types/entities/entity.py +63 -0
- nemo_platform/types/entities/entity_create_params.py +46 -0
- nemo_platform/types/entities/entity_delete_entity_by_name_params.py +31 -0
- nemo_platform/types/entities/entity_get_entity_by_name_params.py +31 -0
- nemo_platform/types/entities/entity_list_params.py +47 -0
- nemo_platform/types/entities/entity_update_entity_by_name_params.py +52 -0
- nemo_platform/types/evaluation/__init__.py +242 -0
- nemo_platform/types/evaluation/agent.py +68 -0
- nemo_platform/types/evaluation/agent_goal_accuracy_metric.py +92 -0
- nemo_platform/types/evaluation/agent_goal_accuracy_metric_param.py +69 -0
- nemo_platform/types/evaluation/agent_goal_accuracy_metric_param_param.py +70 -0
- nemo_platform/types/evaluation/agent_goal_accuracy_metric_response.py +88 -0
- nemo_platform/types/evaluation/agent_param.py +69 -0
- nemo_platform/types/evaluation/aggregate_range_score.py +65 -0
- nemo_platform/types/evaluation/aggregate_rubric_score.py +64 -0
- nemo_platform/types/evaluation/aggregated_metric_result.py +34 -0
- nemo_platform/types/evaluation/answer_accuracy_metric.py +89 -0
- nemo_platform/types/evaluation/answer_accuracy_metric_param.py +66 -0
- nemo_platform/types/evaluation/answer_accuracy_metric_param_param.py +67 -0
- nemo_platform/types/evaluation/answer_accuracy_metric_response.py +85 -0
- nemo_platform/types/evaluation/benchmark.py +81 -0
- nemo_platform/types/evaluation/benchmark_create_params.py +64 -0
- nemo_platform/types/evaluation/benchmark_create_response.py +26 -0
- nemo_platform/types/evaluation/benchmark_evaluation_job.py +75 -0
- nemo_platform/types/evaluation/benchmark_evaluation_jobs_list_filter_param.py +49 -0
- nemo_platform/types/evaluation/benchmark_evaluation_jobs_page.py +37 -0
- nemo_platform/types/evaluation/benchmark_evaluation_jobs_sort_field.py +22 -0
- nemo_platform/types/evaluation/benchmark_job_create_params.py +58 -0
- nemo_platform/types/evaluation/benchmark_job_get_logs_params.py +30 -0
- nemo_platform/types/evaluation/benchmark_job_list_params.py +44 -0
- nemo_platform/types/evaluation/benchmark_job_result.py +93 -0
- nemo_platform/types/evaluation/benchmark_job_result_list_params.py +116 -0
- nemo_platform/types/evaluation/benchmark_job_result_retrieve_params.py +50 -0
- nemo_platform/types/evaluation/benchmark_job_results_list_response.py +37 -0
- nemo_platform/types/evaluation/benchmark_jobs/__init__.py +18 -0
- nemo_platform/types/evaluation/benchmark_jobs/results/__init__.py +22 -0
- nemo_platform/types/evaluation/benchmark_jobs/results/benchmark_evaluation_result.py +30 -0
- nemo_platform/types/evaluation/benchmark_jobs/results/benchmark_metric_result.py +44 -0
- nemo_platform/types/evaluation/benchmark_jobs/results/row_score_download_params.py +28 -0
- nemo_platform/types/evaluation/benchmark_list_params.py +84 -0
- nemo_platform/types/evaluation/benchmark_offline_job.py +43 -0
- nemo_platform/types/evaluation/benchmark_offline_job_param.py +44 -0
- nemo_platform/types/evaluation/benchmark_online_agent_job.py +71 -0
- nemo_platform/types/evaluation/benchmark_online_agent_job_param.py +74 -0
- nemo_platform/types/evaluation/benchmark_online_job.py +66 -0
- nemo_platform/types/evaluation/benchmark_online_job_param.py +68 -0
- nemo_platform/types/evaluation/benchmark_ref.py +22 -0
- nemo_platform/types/evaluation/benchmark_retrieve_params.py +29 -0
- nemo_platform/types/evaluation/benchmark_retrieve_response.py +27 -0
- nemo_platform/types/evaluation/benchmarks_list_response.py +42 -0
- nemo_platform/types/evaluation/bleu_metric.py +76 -0
- nemo_platform/types/evaluation/bleu_metric_param.py +50 -0
- nemo_platform/types/evaluation/bleu_metric_param_param.py +52 -0
- nemo_platform/types/evaluation/bleu_metric_response.py +69 -0
- nemo_platform/types/evaluation/built_in_dataset.py +46 -0
- nemo_platform/types/evaluation/context_entity_recall_metric.py +89 -0
- nemo_platform/types/evaluation/context_entity_recall_metric_param.py +66 -0
- nemo_platform/types/evaluation/context_entity_recall_metric_param_param.py +67 -0
- nemo_platform/types/evaluation/context_entity_recall_metric_response.py +85 -0
- nemo_platform/types/evaluation/context_precision_metric.py +89 -0
- nemo_platform/types/evaluation/context_precision_metric_param.py +66 -0
- nemo_platform/types/evaluation/context_precision_metric_param_param.py +67 -0
- nemo_platform/types/evaluation/context_precision_metric_response.py +85 -0
- nemo_platform/types/evaluation/context_recall_metric.py +89 -0
- nemo_platform/types/evaluation/context_recall_metric_param.py +66 -0
- nemo_platform/types/evaluation/context_recall_metric_param_param.py +67 -0
- nemo_platform/types/evaluation/context_recall_metric_response.py +85 -0
- nemo_platform/types/evaluation/context_relevance_metric.py +89 -0
- nemo_platform/types/evaluation/context_relevance_metric_param.py +66 -0
- nemo_platform/types/evaluation/context_relevance_metric_param_param.py +67 -0
- nemo_platform/types/evaluation/context_relevance_metric_response.py +85 -0
- nemo_platform/types/evaluation/dataset_rows.py +35 -0
- nemo_platform/types/evaluation/dataset_rows_param.py +36 -0
- nemo_platform/types/evaluation/evaluate_dataset_rows_param.py +33 -0
- nemo_platform/types/evaluation/exact_match_metric.py +79 -0
- nemo_platform/types/evaluation/exact_match_metric_param.py +53 -0
- nemo_platform/types/evaluation/exact_match_metric_param_param.py +53 -0
- nemo_platform/types/evaluation/exact_match_metric_response.py +72 -0
- nemo_platform/types/evaluation/extended_benchmark.py +130 -0
- nemo_platform/types/evaluation/f1_metric.py +76 -0
- nemo_platform/types/evaluation/f1_metric_param.py +50 -0
- nemo_platform/types/evaluation/f1_metric_param_param.py +50 -0
- nemo_platform/types/evaluation/f1_metric_response.py +69 -0
- nemo_platform/types/evaluation/faithfulness_metric.py +89 -0
- nemo_platform/types/evaluation/faithfulness_metric_param.py +66 -0
- nemo_platform/types/evaluation/faithfulness_metric_param_param.py +67 -0
- nemo_platform/types/evaluation/faithfulness_metric_response.py +85 -0
- nemo_platform/types/evaluation/field_mapping.py +56 -0
- nemo_platform/types/evaluation/field_mapping_param.py +57 -0
- nemo_platform/types/evaluation/fileset.py +48 -0
- nemo_platform/types/evaluation/fileset_param.py +49 -0
- nemo_platform/types/evaluation/fileset_ref.py +22 -0
- nemo_platform/types/evaluation/histogram.py +30 -0
- nemo_platform/types/evaluation/histogram_bin.py +33 -0
- nemo_platform/types/evaluation/inference_params.py +65 -0
- nemo_platform/types/evaluation/inference_params_param.py +53 -0
- nemo_platform/types/evaluation/json_score_parser.py +35 -0
- nemo_platform/types/evaluation/json_score_parser_param.py +34 -0
- nemo_platform/types/evaluation/llm_judge_metric.py +126 -0
- nemo_platform/types/evaluation/llm_judge_metric_param.py +103 -0
- nemo_platform/types/evaluation/llm_judge_metric_param_param.py +105 -0
- nemo_platform/types/evaluation/llm_judge_metric_response.py +120 -0
- nemo_platform/types/evaluation/metric_create_params.py +959 -0
- nemo_platform/types/evaluation/metric_create_response.py +75 -0
- nemo_platform/types/evaluation/metric_evaluate_params.py +111 -0
- nemo_platform/types/evaluation/metric_evaluation_job.py +65 -0
- nemo_platform/types/evaluation/metric_evaluation_jobs_list_filter_param.py +49 -0
- nemo_platform/types/evaluation/metric_evaluation_jobs_page.py +37 -0
- nemo_platform/types/evaluation/metric_evaluation_jobs_sort_field.py +22 -0
- nemo_platform/types/evaluation/metric_evaluation_response.py +98 -0
- nemo_platform/types/evaluation/metric_evaluation_row_score.py +45 -0
- nemo_platform/types/evaluation/metric_job_create_params.py +48 -0
- nemo_platform/types/evaluation/metric_job_get_logs_params.py +30 -0
- nemo_platform/types/evaluation/metric_job_list_params.py +44 -0
- nemo_platform/types/evaluation/metric_job_result.py +93 -0
- nemo_platform/types/evaluation/metric_job_result_list_params.py +114 -0
- nemo_platform/types/evaluation/metric_job_result_retrieve_params.py +50 -0
- nemo_platform/types/evaluation/metric_job_results_list_response.py +37 -0
- nemo_platform/types/evaluation/metric_jobs/__init__.py +18 -0
- nemo_platform/types/evaluation/metric_jobs/results/__init__.py +20 -0
- nemo_platform/types/evaluation/metric_jobs/results/row_score_download_params.py +28 -0
- nemo_platform/types/evaluation/metric_list_params.py +73 -0
- nemo_platform/types/evaluation/metric_offline_job.py +106 -0
- nemo_platform/types/evaluation/metric_offline_job_param.py +107 -0
- nemo_platform/types/evaluation/metric_online_agent_job.py +133 -0
- nemo_platform/types/evaluation/metric_online_agent_job_param.py +135 -0
- nemo_platform/types/evaluation/metric_online_job.py +127 -0
- nemo_platform/types/evaluation/metric_online_job_param.py +129 -0
- nemo_platform/types/evaluation/metric_output.py +30 -0
- nemo_platform/types/evaluation/metric_ref.py +22 -0
- nemo_platform/types/evaluation/metric_retrieve_response.py +98 -0
- nemo_platform/types/evaluation/metric_retriever_job.py +64 -0
- nemo_platform/types/evaluation/metric_retriever_job_param.py +65 -0
- nemo_platform/types/evaluation/metric_type.py +47 -0
- nemo_platform/types/evaluation/metrics_list_response.py +90 -0
- nemo_platform/types/evaluation/model.py +44 -0
- nemo_platform/types/evaluation/model_param.py +44 -0
- nemo_platform/types/evaluation/model_ref.py +22 -0
- nemo_platform/types/evaluation/nemo_agent_toolkit_remote_metric.py +87 -0
- nemo_platform/types/evaluation/nemo_agent_toolkit_remote_metric_param.py +64 -0
- nemo_platform/types/evaluation/nemo_agent_toolkit_remote_metric_param_param.py +65 -0
- nemo_platform/types/evaluation/nemo_agent_toolkit_remote_metric_response.py +80 -0
- nemo_platform/types/evaluation/noise_sensitivity_metric.py +89 -0
- nemo_platform/types/evaluation/noise_sensitivity_metric_param.py +66 -0
- nemo_platform/types/evaluation/noise_sensitivity_metric_param_param.py +67 -0
- nemo_platform/types/evaluation/noise_sensitivity_metric_response.py +85 -0
- nemo_platform/types/evaluation/number_check_metric.py +104 -0
- nemo_platform/types/evaluation/number_check_metric_param.py +81 -0
- nemo_platform/types/evaluation/number_check_metric_param_param.py +83 -0
- nemo_platform/types/evaluation/number_check_metric_response.py +97 -0
- nemo_platform/types/evaluation/parameter.py +42 -0
- nemo_platform/types/evaluation/parameter_param.py +40 -0
- nemo_platform/types/evaluation/percentiles.py +54 -0
- nemo_platform/types/evaluation/range_score.py +56 -0
- nemo_platform/types/evaluation/range_score_param.py +57 -0
- nemo_platform/types/evaluation/reasoning_params.py +41 -0
- nemo_platform/types/evaluation/reasoning_params_param.py +41 -0
- nemo_platform/types/evaluation/regex_score_parser.py +38 -0
- nemo_platform/types/evaluation/regex_score_parser_param.py +37 -0
- nemo_platform/types/evaluation/remote_metric.py +91 -0
- nemo_platform/types/evaluation/remote_metric_param.py +68 -0
- nemo_platform/types/evaluation/remote_metric_param_param.py +69 -0
- nemo_platform/types/evaluation/remote_metric_response.py +84 -0
- nemo_platform/types/evaluation/remote_score.py +49 -0
- nemo_platform/types/evaluation/remote_score_param.py +50 -0
- nemo_platform/types/evaluation/response_groundedness_metric.py +89 -0
- nemo_platform/types/evaluation/response_groundedness_metric_param.py +66 -0
- nemo_platform/types/evaluation/response_groundedness_metric_param_param.py +67 -0
- nemo_platform/types/evaluation/response_groundedness_metric_response.py +85 -0
- nemo_platform/types/evaluation/response_relevancy_metric.py +95 -0
- nemo_platform/types/evaluation/response_relevancy_metric_param.py +74 -0
- nemo_platform/types/evaluation/response_relevancy_metric_param_param.py +75 -0
- nemo_platform/types/evaluation/response_relevancy_metric_response.py +93 -0
- nemo_platform/types/evaluation/retriever_pipeline.py +34 -0
- nemo_platform/types/evaluation/retriever_pipeline_param.py +35 -0
- nemo_platform/types/evaluation/rouge_metric.py +76 -0
- nemo_platform/types/evaluation/rouge_metric_param.py +53 -0
- nemo_platform/types/evaluation/rouge_metric_param_param.py +53 -0
- nemo_platform/types/evaluation/rouge_metric_response.py +69 -0
- nemo_platform/types/evaluation/row_score.py +59 -0
- nemo_platform/types/evaluation/rubric.py +40 -0
- nemo_platform/types/evaluation/rubric_param.py +40 -0
- nemo_platform/types/evaluation/rubric_score.py +54 -0
- nemo_platform/types/evaluation/rubric_score_param.py +55 -0
- nemo_platform/types/evaluation/rubric_score_stat.py +38 -0
- nemo_platform/types/evaluation/run_config.py +39 -0
- nemo_platform/types/evaluation/run_config_online.py +51 -0
- nemo_platform/types/evaluation/run_config_online_model.py +73 -0
- nemo_platform/types/evaluation/run_config_online_model_param.py +75 -0
- nemo_platform/types/evaluation/run_config_online_param.py +51 -0
- nemo_platform/types/evaluation/run_config_param.py +39 -0
- nemo_platform/types/evaluation/string_check_metric.py +82 -0
- nemo_platform/types/evaluation/string_check_metric_param.py +59 -0
- nemo_platform/types/evaluation/string_check_metric_param_param.py +61 -0
- nemo_platform/types/evaluation/string_check_metric_response.py +75 -0
- nemo_platform/types/evaluation/system_benchmark.py +71 -0
- nemo_platform/types/evaluation/system_benchmark_offline_job.py +58 -0
- nemo_platform/types/evaluation/system_benchmark_offline_job_param.py +60 -0
- nemo_platform/types/evaluation/system_benchmark_online_job.py +54 -0
- nemo_platform/types/evaluation/system_benchmark_online_job_param.py +55 -0
- nemo_platform/types/evaluation/system_metric.py +70 -0
- nemo_platform/types/evaluation/system_metric_param.py +50 -0
- nemo_platform/types/evaluation/system_metric_param_param.py +51 -0
- nemo_platform/types/evaluation/system_metric_response.py +66 -0
- nemo_platform/types/evaluation/tool_call_accuracy_metric.py +70 -0
- nemo_platform/types/evaluation/tool_call_accuracy_metric_param.py +44 -0
- nemo_platform/types/evaluation/tool_call_accuracy_metric_param_param.py +44 -0
- nemo_platform/types/evaluation/tool_call_accuracy_metric_response.py +63 -0
- nemo_platform/types/evaluation/tool_calling_metric.py +70 -0
- nemo_platform/types/evaluation/tool_calling_metric_param.py +47 -0
- nemo_platform/types/evaluation/tool_calling_metric_param_param.py +47 -0
- nemo_platform/types/evaluation/tool_calling_metric_response.py +63 -0
- nemo_platform/types/evaluation/topic_adherence_metric.py +92 -0
- nemo_platform/types/evaluation/topic_adherence_metric_param.py +69 -0
- nemo_platform/types/evaluation/topic_adherence_metric_param_param.py +70 -0
- nemo_platform/types/evaluation/topic_adherence_metric_response.py +88 -0
- nemo_platform/types/files/__init__.py +45 -0
- nemo_platform/types/files/cache_status.py +22 -0
- nemo_platform/types/files/dataset_metadata_content.py +46 -0
- nemo_platform/types/files/dataset_metadata_content_param.py +45 -0
- nemo_platform/types/files/file_list_files_params.py +35 -0
- nemo_platform/types/files/file_upload_file_params.py +28 -0
- nemo_platform/types/files/fileset.py +62 -0
- nemo_platform/types/files/fileset_create_params.py +74 -0
- nemo_platform/types/files/fileset_file.py +36 -0
- nemo_platform/types/files/fileset_filter_param.py +54 -0
- nemo_platform/types/files/fileset_list_params.py +47 -0
- nemo_platform/types/files/fileset_metadata_param.py +46 -0
- nemo_platform/types/files/fileset_metadata_param_param.py +47 -0
- nemo_platform/types/files/fileset_outputs_page.py +37 -0
- nemo_platform/types/files/fileset_purpose.py +22 -0
- nemo_platform/types/files/fileset_update_params.py +49 -0
- nemo_platform/types/files/huggingface_storage_config.py +60 -0
- nemo_platform/types/files/huggingface_storage_config_param.py +60 -0
- nemo_platform/types/files/list_fileset_files_response.py +27 -0
- nemo_platform/types/files/local_storage_config.py +39 -0
- nemo_platform/types/files/local_storage_config_param.py +38 -0
- nemo_platform/types/files/ngc_storage_config.py +66 -0
- nemo_platform/types/files/ngc_storage_config_param.py +66 -0
- nemo_platform/types/files/otlp/__init__.py +22 -0
- nemo_platform/types/files/otlp/log_query_params.py +36 -0
- nemo_platform/types/files/otlp/otel_export_logs_partial_success.py +34 -0
- nemo_platform/types/files/otlp/otel_export_logs_service_response.py +35 -0
- nemo_platform/types/files/s3_storage_config.py +85 -0
- nemo_platform/types/files/s3_storage_config_param.py +85 -0
- nemo_platform/types/files/secret_ref.py +22 -0
- nemo_platform/types/files/storage_config_type.py +22 -0
- nemo_platform/types/guardrail/__init__.py +165 -0
- nemo_platform/types/guardrail/action_rails.py +36 -0
- nemo_platform/types/guardrail/action_rails_param.py +38 -0
- nemo_platform/types/guardrail/activated_rail.py +61 -0
- nemo_platform/types/guardrail/ai_defense_rail_config.py +36 -0
- nemo_platform/types/guardrail/ai_defense_rail_config_param.py +36 -0
- nemo_platform/types/guardrail/auto_align_options.py +29 -0
- nemo_platform/types/guardrail/auto_align_options_param.py +30 -0
- nemo_platform/types/guardrail/auto_align_rail_config.py +35 -0
- nemo_platform/types/guardrail/auto_align_rail_config_param.py +37 -0
- nemo_platform/types/guardrail/cache_stats_config.py +32 -0
- nemo_platform/types/guardrail/cache_stats_config_param.py +32 -0
- nemo_platform/types/guardrail/chat_completion_assistant_message_param.py +45 -0
- nemo_platform/types/guardrail/chat_completion_content_part_image_param.py +34 -0
- nemo_platform/types/guardrail/chat_completion_content_part_text_param.py +32 -0
- nemo_platform/types/guardrail/chat_completion_function_message_param.py +35 -0
- nemo_platform/types/guardrail/chat_completion_message_tool_call_param.py +37 -0
- nemo_platform/types/guardrail/chat_completion_system_message_param.py +35 -0
- nemo_platform/types/guardrail/chat_completion_tool_message_param.py +35 -0
- nemo_platform/types/guardrail/chat_completion_user_message_param.py +41 -0
- nemo_platform/types/guardrail/clavata_rail_config.py +47 -0
- nemo_platform/types/guardrail/clavata_rail_config_param.py +48 -0
- nemo_platform/types/guardrail/clavata_rail_options.py +36 -0
- nemo_platform/types/guardrail/clavata_rail_options_param.py +38 -0
- nemo_platform/types/guardrail/config_create_params.py +36 -0
- nemo_platform/types/guardrail/config_list_params.py +47 -0
- nemo_platform/types/guardrail/config_update_params.py +33 -0
- nemo_platform/types/guardrail/content_safety_config.py +34 -0
- nemo_platform/types/guardrail/content_safety_config_param.py +35 -0
- nemo_platform/types/guardrail/crowd_strike_aidr_rail_config.py +29 -0
- nemo_platform/types/guardrail/crowd_strike_aidr_rail_config_param.py +29 -0
- nemo_platform/types/guardrail/dialog_rails.py +34 -0
- nemo_platform/types/guardrail/dialog_rails_param.py +35 -0
- nemo_platform/types/guardrail/executed_action.py +48 -0
- nemo_platform/types/guardrail/fact_checking_rail_config.py +31 -0
- nemo_platform/types/guardrail/fact_checking_rail_config_param.py +32 -0
- nemo_platform/types/guardrail/fiddler_guardrails.py +35 -0
- nemo_platform/types/guardrail/fiddler_guardrails_param.py +35 -0
- nemo_platform/types/guardrail/function_call_param.py +35 -0
- nemo_platform/types/guardrail/function_param.py +35 -0
- nemo_platform/types/guardrail/g_li_ner_detection.py +51 -0
- nemo_platform/types/guardrail/g_li_ner_detection_options.py +29 -0
- nemo_platform/types/guardrail/g_li_ner_detection_options_param.py +31 -0
- nemo_platform/types/guardrail/g_li_ner_detection_param.py +52 -0
- nemo_platform/types/guardrail/generation_log.py +44 -0
- nemo_platform/types/guardrail/generation_log_options_param.py +50 -0
- nemo_platform/types/guardrail/generation_options_param.py +55 -0
- nemo_platform/types/guardrail/generation_rails_options_param.py +53 -0
- nemo_platform/types/guardrail/generation_stats.py +56 -0
- nemo_platform/types/guardrail/guardrail_check_params.py +164 -0
- nemo_platform/types/guardrail/guardrail_check_response.py +36 -0
- nemo_platform/types/guardrail/guardrail_config.py +59 -0
- nemo_platform/types/guardrail/guardrail_config_filter_param.py +49 -0
- nemo_platform/types/guardrail/guardrail_configs_page.py +37 -0
- nemo_platform/types/guardrail/guardrails_ai_rail_config.py +33 -0
- nemo_platform/types/guardrail/guardrails_ai_rail_config_param.py +35 -0
- nemo_platform/types/guardrail/guardrails_ai_validator_config.py +44 -0
- nemo_platform/types/guardrail/guardrails_ai_validator_config_param.py +45 -0
- nemo_platform/types/guardrail/guardrails_data.py +40 -0
- nemo_platform/types/guardrail/guardrails_data_param.py +67 -0
- nemo_platform/types/guardrail/image_u_rl_param.py +32 -0
- nemo_platform/types/guardrail/injection_detection.py +49 -0
- nemo_platform/types/guardrail/injection_detection_param.py +52 -0
- nemo_platform/types/guardrail/input_rails.py +32 -0
- nemo_platform/types/guardrail/input_rails_param.py +34 -0
- nemo_platform/types/guardrail/instruction.py +30 -0
- nemo_platform/types/guardrail/instruction_param.py +32 -0
- nemo_platform/types/guardrail/jailbreak_detection_config.py +52 -0
- nemo_platform/types/guardrail/jailbreak_detection_config_param.py +58 -0
- nemo_platform/types/guardrail/llm_call_info.py +63 -0
- nemo_platform/types/guardrail/log_adapter_config.py +41 -0
- nemo_platform/types/guardrail/log_adapter_config_param.py +27 -0
- nemo_platform/types/guardrail/message_template.py +30 -0
- nemo_platform/types/guardrail/message_template_param.py +32 -0
- nemo_platform/types/guardrail/model.py +55 -0
- nemo_platform/types/guardrail/model_cache_config.py +36 -0
- nemo_platform/types/guardrail/model_cache_config_param.py +37 -0
- nemo_platform/types/guardrail/model_param.py +55 -0
- nemo_platform/types/guardrail/model_parameters.py +51 -0
- nemo_platform/types/guardrail/model_parameters_param.py +38 -0
- nemo_platform/types/guardrail/multilingual_config.py +40 -0
- nemo_platform/types/guardrail/multilingual_config_param.py +41 -0
- nemo_platform/types/guardrail/output_rails.py +44 -0
- nemo_platform/types/guardrail/output_rails_param.py +46 -0
- nemo_platform/types/guardrail/output_rails_streaming_config.py +44 -0
- nemo_platform/types/guardrail/output_rails_streaming_config_param.py +44 -0
- nemo_platform/types/guardrail/pangea_rail_config.py +33 -0
- nemo_platform/types/guardrail/pangea_rail_config_param.py +34 -0
- nemo_platform/types/guardrail/pangea_rail_options.py +31 -0
- nemo_platform/types/guardrail/pangea_rail_options_param.py +33 -0
- nemo_platform/types/guardrail/patronus_evaluate_api_params.py +38 -0
- nemo_platform/types/guardrail/patronus_evaluate_api_params_param.py +40 -0
- nemo_platform/types/guardrail/patronus_evaluate_config.py +30 -0
- nemo_platform/types/guardrail/patronus_evaluate_config_param.py +31 -0
- nemo_platform/types/guardrail/patronus_evaluation_success_strategy.py +22 -0
- nemo_platform/types/guardrail/patronus_rail_config.py +33 -0
- nemo_platform/types/guardrail/patronus_rail_config_param.py +34 -0
- nemo_platform/types/guardrail/private_ai_detection.py +39 -0
- nemo_platform/types/guardrail/private_ai_detection_options.py +29 -0
- nemo_platform/types/guardrail/private_ai_detection_options_param.py +31 -0
- nemo_platform/types/guardrail/private_ai_detection_param.py +40 -0
- nemo_platform/types/guardrail/rail_status.py +26 -0
- nemo_platform/types/guardrail/rails.py +73 -0
- nemo_platform/types/guardrail/rails_config.py +79 -0
- nemo_platform/types/guardrail/rails_config_data.py +94 -0
- nemo_platform/types/guardrail/rails_config_data_param.py +95 -0
- nemo_platform/types/guardrail/rails_config_param.py +81 -0
- nemo_platform/types/guardrail/rails_param.py +74 -0
- nemo_platform/types/guardrail/reasoning_config.py +32 -0
- nemo_platform/types/guardrail/reasoning_config_param.py +32 -0
- nemo_platform/types/guardrail/regex_detection.py +36 -0
- nemo_platform/types/guardrail/regex_detection_options.py +32 -0
- nemo_platform/types/guardrail/regex_detection_options_param.py +34 -0
- nemo_platform/types/guardrail/regex_detection_param.py +37 -0
- nemo_platform/types/guardrail/retrieval_rails.py +29 -0
- nemo_platform/types/guardrail/retrieval_rails_param.py +31 -0
- nemo_platform/types/guardrail/sensitive_data_detection.py +43 -0
- nemo_platform/types/guardrail/sensitive_data_detection_options.py +37 -0
- nemo_platform/types/guardrail/sensitive_data_detection_options_param.py +39 -0
- nemo_platform/types/guardrail/sensitive_data_detection_param.py +45 -0
- nemo_platform/types/guardrail/single_call_config.py +31 -0
- nemo_platform/types/guardrail/single_call_config_param.py +31 -0
- nemo_platform/types/guardrail/status_enum.py +22 -0
- nemo_platform/types/guardrail/task_prompt.py +63 -0
- nemo_platform/types/guardrail/task_prompt_param.py +65 -0
- nemo_platform/types/guardrail/tool_input_rails.py +36 -0
- nemo_platform/types/guardrail/tool_input_rails_param.py +38 -0
- nemo_platform/types/guardrail/tool_output_rails.py +36 -0
- nemo_platform/types/guardrail/tool_output_rails_param.py +38 -0
- nemo_platform/types/guardrail/tracing_config.py +48 -0
- nemo_platform/types/guardrail/tracing_config_param.py +50 -0
- nemo_platform/types/guardrail/trend_micro_rail_config.py +51 -0
- nemo_platform/types/guardrail/trend_micro_rail_config_param.py +51 -0
- nemo_platform/types/guardrail/user_messages_config.py +42 -0
- nemo_platform/types/guardrail/user_messages_config_param.py +42 -0
- nemo_platform/types/iam/__init__.py +26 -0
- nemo_platform/types/iam/date_range_filter_param.py +36 -0
- nemo_platform/types/iam/role_binding.py +42 -0
- nemo_platform/types/iam/role_binding_create_params.py +39 -0
- nemo_platform/types/iam/role_binding_delete_params.py +30 -0
- nemo_platform/types/iam/role_binding_filter_param.py +49 -0
- nemo_platform/types/iam/role_binding_list_params.py +44 -0
- nemo_platform/types/iam/role_bindings_page.py +37 -0
- nemo_platform/types/inference/__init__.py +60 -0
- nemo_platform/types/inference/deployment_config_create_params.py +47 -0
- nemo_platform/types/inference/deployment_config_list_params.py +46 -0
- nemo_platform/types/inference/deployment_config_update_params.py +37 -0
- nemo_platform/types/inference/deployment_configs/__init__.py +20 -0
- nemo_platform/types/inference/deployment_configs/version_list_response.py +25 -0
- nemo_platform/types/inference/deployment_create_params.py +45 -0
- nemo_platform/types/inference/deployment_list_models_response.py +23 -0
- nemo_platform/types/inference/deployment_list_params.py +52 -0
- nemo_platform/types/inference/deployment_update_params.py +35 -0
- nemo_platform/types/inference/deployment_update_status_params.py +42 -0
- nemo_platform/types/inference/deployments/__init__.py +20 -0
- nemo_platform/types/inference/deployments/version_list_response.py +25 -0
- nemo_platform/types/inference/gateway/__init__.py +38 -0
- nemo_platform/types/inference/gateway/model_patch_params.py +31 -0
- nemo_platform/types/inference/gateway/model_patch_response.py +23 -0
- nemo_platform/types/inference/gateway/model_post_params.py +31 -0
- nemo_platform/types/inference/gateway/model_post_response.py +23 -0
- nemo_platform/types/inference/gateway/model_put_params.py +31 -0
- nemo_platform/types/inference/gateway/model_put_response.py +23 -0
- nemo_platform/types/inference/gateway/openai/__init__.py +18 -0
- nemo_platform/types/inference/gateway/openai/v1/__init__.py +21 -0
- nemo_platform/types/inference/gateway/openai/v1/openai_list_models_resp.py +31 -0
- nemo_platform/types/inference/gateway/openai/v1/openai_model_resp.py +34 -0
- nemo_platform/types/inference/gateway/openai_patch_params.py +29 -0
- nemo_platform/types/inference/gateway/openai_patch_response.py +23 -0
- nemo_platform/types/inference/gateway/openai_post_params.py +29 -0
- nemo_platform/types/inference/gateway/openai_post_response.py +23 -0
- nemo_platform/types/inference/gateway/openai_put_params.py +29 -0
- nemo_platform/types/inference/gateway/openai_put_response.py +23 -0
- nemo_platform/types/inference/gateway/provider_patch_params.py +31 -0
- nemo_platform/types/inference/gateway/provider_patch_response.py +23 -0
- nemo_platform/types/inference/gateway/provider_post_params.py +31 -0
- nemo_platform/types/inference/gateway/provider_post_response.py +23 -0
- nemo_platform/types/inference/gateway/provider_put_params.py +31 -0
- nemo_platform/types/inference/gateway/provider_put_response.py +23 -0
- nemo_platform/types/inference/gateway/provider_ready_response.py +23 -0
- nemo_platform/types/inference/k8s_nim_operator_config.py +57 -0
- nemo_platform/types/inference/k8s_nim_operator_config_param.py +58 -0
- nemo_platform/types/inference/middleware_call.py +55 -0
- nemo_platform/types/inference/middleware_call_param.py +56 -0
- nemo_platform/types/inference/model_deployment.py +97 -0
- nemo_platform/types/inference/model_deployment_config.py +76 -0
- nemo_platform/types/inference/model_deployment_config_filter_param.py +49 -0
- nemo_platform/types/inference/model_deployment_configs_page.py +37 -0
- nemo_platform/types/inference/model_deployment_filter_param.py +56 -0
- nemo_platform/types/inference/model_deployment_status.py +24 -0
- nemo_platform/types/inference/model_deployment_status_history_item.py +37 -0
- nemo_platform/types/inference/model_deployments_page.py +37 -0
- nemo_platform/types/inference/model_provider.py +134 -0
- nemo_platform/types/inference/model_provider_filter_param.py +56 -0
- nemo_platform/types/inference/model_provider_sort.py +24 -0
- nemo_platform/types/inference/model_provider_status.py +24 -0
- nemo_platform/types/inference/model_providers_page.py +37 -0
- nemo_platform/types/inference/model_type.py +22 -0
- nemo_platform/types/inference/nim_deployment.py +96 -0
- nemo_platform/types/inference/nim_deployment_param.py +93 -0
- nemo_platform/types/inference/provider_create_params.py +94 -0
- nemo_platform/types/inference/provider_list_params.py +47 -0
- nemo_platform/types/inference/provider_update_params.py +87 -0
- nemo_platform/types/inference/provider_update_status_params.py +48 -0
- nemo_platform/types/inference/served_model_mapping.py +35 -0
- nemo_platform/types/inference/served_model_mapping_param.py +32 -0
- nemo_platform/types/inference/virtual_model.py +91 -0
- nemo_platform/types/inference/virtual_model_create_params.py +83 -0
- nemo_platform/types/inference/virtual_model_inference_config.py +32 -0
- nemo_platform/types/inference/virtual_model_inference_config_param.py +34 -0
- nemo_platform/types/inference/virtual_model_list_params.py +35 -0
- nemo_platform/types/inference/virtual_model_patch_params.py +80 -0
- nemo_platform/types/inference/virtual_models_page.py +37 -0
- nemo_platform/types/intake/__init__.py +86 -0
- nemo_platform/types/intake/app.py +51 -0
- nemo_platform/types/intake/app_create_params.py +38 -0
- nemo_platform/types/intake/app_filter_param.py +46 -0
- nemo_platform/types/intake/app_list_params.py +44 -0
- nemo_platform/types/intake/app_patch_params.py +35 -0
- nemo_platform/types/intake/app_sort_field.py +22 -0
- nemo_platform/types/intake/apps/__init__.py +26 -0
- nemo_platform/types/intake/apps/task.py +54 -0
- nemo_platform/types/intake/apps/task_create_params.py +40 -0
- nemo_platform/types/intake/apps/task_filter_param.py +49 -0
- nemo_platform/types/intake/apps/task_list_params.py +44 -0
- nemo_platform/types/intake/apps/task_patch_params.py +37 -0
- nemo_platform/types/intake/apps/task_sort_field.py +22 -0
- nemo_platform/types/intake/apps/tasks_page.py +37 -0
- nemo_platform/types/intake/apps_page.py +37 -0
- nemo_platform/types/intake/entries/__init__.py +20 -0
- nemo_platform/types/intake/entries/event_create_params.py +40 -0
- nemo_platform/types/intake/entry.py +98 -0
- nemo_platform/types/intake/entry_context.py +79 -0
- nemo_platform/types/intake/entry_context_filter_param.py +41 -0
- nemo_platform/types/intake/entry_context_param.py +82 -0
- nemo_platform/types/intake/entry_create_params.py +85 -0
- nemo_platform/types/intake/entry_data.py +48 -0
- nemo_platform/types/intake/entry_data_param.py +51 -0
- nemo_platform/types/intake/entry_filter_param.py +85 -0
- nemo_platform/types/intake/entry_list_params.py +47 -0
- nemo_platform/types/intake/entry_patch_params.py +79 -0
- nemo_platform/types/intake/entry_sort_field.py +22 -0
- nemo_platform/types/intake/entry_user_rating_filter_param.py +31 -0
- nemo_platform/types/intake/entrys_page.py +37 -0
- nemo_platform/types/intake/evaluation_context_param.py +41 -0
- nemo_platform/types/intake/evaluator_result.py +52 -0
- nemo_platform/types/intake/evaluator_result_create_params.py +52 -0
- nemo_platform/types/intake/evaluator_result_data_type.py +22 -0
- nemo_platform/types/intake/evaluator_result_event.py +67 -0
- nemo_platform/types/intake/evaluator_result_event_param.py +69 -0
- nemo_platform/types/intake/evaluator_result_filter_param.py +49 -0
- nemo_platform/types/intake/evaluator_result_list_params.py +43 -0
- nemo_platform/types/intake/evaluator_result_sort_field.py +22 -0
- nemo_platform/types/intake/evaluator_results_page.py +37 -0
- nemo_platform/types/intake/export_config_param.py +44 -0
- nemo_platform/types/intake/export_config_param_param.py +45 -0
- nemo_platform/types/intake/export_preview_params.py +34 -0
- nemo_platform/types/intake/export_preview_response.py +39 -0
- nemo_platform/types/intake/exports/__init__.py +28 -0
- nemo_platform/types/intake/exports/export_config.py +44 -0
- nemo_platform/types/intake/exports/export_job.py +76 -0
- nemo_platform/types/intake/exports/export_job_filter_param.py +50 -0
- nemo_platform/types/intake/exports/export_job_sort_field.py +22 -0
- nemo_platform/types/intake/exports/export_jobs_page.py +37 -0
- nemo_platform/types/intake/exports/export_status_details.py +35 -0
- nemo_platform/types/intake/exports/job_create_params.py +40 -0
- nemo_platform/types/intake/exports/job_list_params.py +46 -0
- nemo_platform/types/intake/exports/job_status.py +22 -0
- nemo_platform/types/intake/flexible_entry_request.py +63 -0
- nemo_platform/types/intake/flexible_entry_request_param.py +51 -0
- nemo_platform/types/intake/flexible_entry_response.py +62 -0
- nemo_platform/types/intake/flexible_entry_response_param.py +49 -0
- nemo_platform/types/intake/flexible_message.py +56 -0
- nemo_platform/types/intake/flexible_message_param.py +43 -0
- nemo_platform/types/intake/float_filter_param.py +32 -0
- nemo_platform/types/intake/ingest/__init__.py +37 -0
- nemo_platform/types/intake/ingest/atif_agent_param.py +35 -0
- nemo_platform/types/intake/ingest/atif_content_part_image_param.py +30 -0
- nemo_platform/types/intake/ingest/atif_content_part_param.py +28 -0
- nemo_platform/types/intake/ingest/atif_content_part_text_param.py +28 -0
- nemo_platform/types/intake/ingest/atif_create_params.py +52 -0
- nemo_platform/types/intake/ingest/atif_final_metrics_param.py +37 -0
- nemo_platform/types/intake/ingest/atif_image_source_param.py +28 -0
- nemo_platform/types/intake/ingest/atif_metrics_param.py +41 -0
- nemo_platform/types/intake/ingest/atif_observation_param.py +29 -0
- nemo_platform/types/intake/ingest/atif_observation_result_param.py +36 -0
- nemo_platform/types/intake/ingest/atif_step_agent_param.py +58 -0
- nemo_platform/types/intake/ingest/atif_step_param.py +29 -0
- nemo_platform/types/intake/ingest/atif_step_system_param.py +43 -0
- nemo_platform/types/intake/ingest/atif_step_user_param.py +43 -0
- nemo_platform/types/intake/ingest/atif_subagent_trajectory_ref_param.py +33 -0
- nemo_platform/types/intake/ingest/atif_tool_call_param.py +31 -0
- nemo_platform/types/intake/ingest/chat_completion_create_params.py +66 -0
- nemo_platform/types/intake/ingest/chat_completions_ingest_response.py +26 -0
- nemo_platform/types/intake/ingest/otlp/__init__.py +18 -0
- nemo_platform/types/intake/ingest/otlp/v1/__init__.py +20 -0
- nemo_platform/types/intake/ingest/otlp/v1/ingest_response.py +26 -0
- nemo_platform/types/intake/message_role.py +22 -0
- nemo_platform/types/intake/reviewer_annotation_event.py +95 -0
- nemo_platform/types/intake/reviewer_annotation_event_param.py +97 -0
- nemo_platform/types/intake/span.py +100 -0
- nemo_platform/types/intake/span_evaluation_context.py +40 -0
- nemo_platform/types/intake/span_filter_param.py +95 -0
- nemo_platform/types/intake/span_kind.py +24 -0
- nemo_platform/types/intake/span_list_params.py +46 -0
- nemo_platform/types/intake/span_sort_field.py +22 -0
- nemo_platform/types/intake/span_status.py +22 -0
- nemo_platform/types/intake/spans/__init__.py +20 -0
- nemo_platform/types/intake/spans/evaluator_result_list_response.py +25 -0
- nemo_platform/types/intake/spans_page.py +37 -0
- nemo_platform/types/intake/thumb_direction.py +22 -0
- nemo_platform/types/intake/trace.py +65 -0
- nemo_platform/types/intake/trace_filter_param.py +60 -0
- nemo_platform/types/intake/trace_list_params.py +49 -0
- nemo_platform/types/intake/trace_retrieve_params.py +32 -0
- nemo_platform/types/intake/trace_sort_field.py +22 -0
- nemo_platform/types/intake/traces_page.py +37 -0
- nemo_platform/types/intake/usage.py +65 -0
- nemo_platform/types/intake/usage_param.py +68 -0
- nemo_platform/types/intake/user_action_event.py +65 -0
- nemo_platform/types/intake/user_action_event_param.py +68 -0
- nemo_platform/types/intake/user_feedback_event.py +84 -0
- nemo_platform/types/intake/user_feedback_event_param.py +86 -0
- nemo_platform/types/intake/user_rating.py +68 -0
- nemo_platform/types/intake/user_rating_param.py +70 -0
- nemo_platform/types/jobs/__init__.py +95 -0
- nemo_platform/types/jobs/compute_resource_spec.py +32 -0
- nemo_platform/types/jobs/compute_resource_spec_param.py +32 -0
- nemo_platform/types/jobs/compute_resources.py +46 -0
- nemo_platform/types/jobs/compute_resources_param.py +47 -0
- nemo_platform/types/jobs/container_spec.py +35 -0
- nemo_platform/types/jobs/container_spec_param.py +37 -0
- nemo_platform/types/jobs/cpu_execution_provider.py +46 -0
- nemo_platform/types/jobs/cpu_execution_provider_param.py +46 -0
- nemo_platform/types/jobs/distributed_gpu_execution_provider.py +46 -0
- nemo_platform/types/jobs/distributed_gpu_execution_provider_param.py +46 -0
- nemo_platform/types/jobs/docker_job_execution_profile.py +43 -0
- nemo_platform/types/jobs/docker_job_execution_profile_config.py +52 -0
- nemo_platform/types/jobs/docker_job_network_config.py +27 -0
- nemo_platform/types/jobs/docker_job_storage_config.py +36 -0
- nemo_platform/types/jobs/docker_volume_mount.py +47 -0
- nemo_platform/types/jobs/e2e_job_execution_profile.py +43 -0
- nemo_platform/types/jobs/gpu_execution_provider.py +46 -0
- nemo_platform/types/jobs/gpu_execution_provider_param.py +46 -0
- nemo_platform/types/jobs/image_pull_secret.py +27 -0
- nemo_platform/types/jobs/job_create_params.py +46 -0
- nemo_platform/types/jobs/job_execution_profile_config.py +42 -0
- nemo_platform/types/jobs/job_get_logs_params.py +41 -0
- nemo_platform/types/jobs/job_list_execution_profiles_response.py +37 -0
- nemo_platform/types/jobs/job_list_params.py +47 -0
- nemo_platform/types/jobs/job_update_status_details_params.py +29 -0
- nemo_platform/types/jobs/kubernetes_empty_dir_volume.py +32 -0
- nemo_platform/types/jobs/kubernetes_job_execution_profile.py +43 -0
- nemo_platform/types/jobs/kubernetes_job_execution_profile_config.py +101 -0
- nemo_platform/types/jobs/kubernetes_job_storage_config.py +40 -0
- nemo_platform/types/jobs/kubernetes_object_metadata.py +28 -0
- nemo_platform/types/jobs/kubernetes_persistent_volume_claim.py +32 -0
- nemo_platform/types/jobs/kubernetes_volume.py +37 -0
- nemo_platform/types/jobs/kubernetes_volume_mount.py +38 -0
- nemo_platform/types/jobs/platform_job_environment_variable.py +36 -0
- nemo_platform/types/jobs/platform_job_environment_variable_param.py +37 -0
- nemo_platform/types/jobs/platform_job_list_task_response.py +29 -0
- nemo_platform/types/jobs/platform_job_response.py +75 -0
- nemo_platform/types/jobs/platform_job_responses_page.py +37 -0
- nemo_platform/types/jobs/platform_job_secret_environment_variable_ref.py +27 -0
- nemo_platform/types/jobs/platform_job_secret_environment_variable_ref_param.py +29 -0
- nemo_platform/types/jobs/platform_job_sort_field.py +22 -0
- nemo_platform/types/jobs/platform_job_spec.py +30 -0
- nemo_platform/types/jobs/platform_job_spec_param.py +32 -0
- nemo_platform/types/jobs/platform_job_step.py +75 -0
- nemo_platform/types/jobs/platform_job_step_spec.py +63 -0
- nemo_platform/types/jobs/platform_job_step_spec_param.py +65 -0
- nemo_platform/types/jobs/platform_job_step_with_context.py +67 -0
- nemo_platform/types/jobs/platform_job_step_with_contexts_page.py +37 -0
- nemo_platform/types/jobs/platform_job_steps_list_filter_param.py +38 -0
- nemo_platform/types/jobs/platform_job_task.py +75 -0
- nemo_platform/types/jobs/platform_jobs_list_filter_param.py +51 -0
- nemo_platform/types/jobs/result_create_params.py +34 -0
- nemo_platform/types/jobs/result_list_params.py +34 -0
- nemo_platform/types/jobs/step_lifecycle.py +37 -0
- nemo_platform/types/jobs/step_lifecycle_param.py +37 -0
- nemo_platform/types/jobs/step_list_params.py +44 -0
- nemo_platform/types/jobs/step_update_status_params.py +44 -0
- nemo_platform/types/jobs/subprocess_execution_provider.py +33 -0
- nemo_platform/types/jobs/subprocess_execution_provider_param.py +34 -0
- nemo_platform/types/jobs/subprocess_job_execution_profile.py +36 -0
- nemo_platform/types/jobs/subprocess_job_execution_profile_config.py +49 -0
- nemo_platform/types/jobs/task_create_or_update_params.py +46 -0
- nemo_platform/types/jobs/volcano_job_execution_profile.py +39 -0
- nemo_platform/types/jobs/volcano_job_execution_profile_config.py +114 -0
- nemo_platform/types/members/__init__.py +24 -0
- nemo_platform/types/members/member_create_params.py +40 -0
- nemo_platform/types/members/member_delete_params.py +32 -0
- nemo_platform/types/members/member_update_params.py +37 -0
- nemo_platform/types/members/workspace_member.py +39 -0
- nemo_platform/types/members/workspace_member_list_response.py +29 -0
- nemo_platform/types/models/__init__.py +34 -0
- nemo_platform/types/models/adapter.py +73 -0
- nemo_platform/types/models/adapter_create_params.py +54 -0
- nemo_platform/types/models/adapter_update_params.py +37 -0
- nemo_platform/types/models/base_model_filter_param.py +29 -0
- nemo_platform/types/models/finetuning_type_filter_param.py +31 -0
- nemo_platform/types/models/lora.py +30 -0
- nemo_platform/types/models/lora_param.py +30 -0
- nemo_platform/types/models/model_create_params.py +93 -0
- nemo_platform/types/models/model_entity.py +112 -0
- nemo_platform/types/models/model_entity_filter_param.py +72 -0
- nemo_platform/types/models/model_entity_sort_field.py +22 -0
- nemo_platform/types/models/model_entitys_page.py +37 -0
- nemo_platform/types/models/model_list_params.py +50 -0
- nemo_platform/types/models/model_retrieve_params.py +29 -0
- nemo_platform/types/models/model_update_params.py +86 -0
- nemo_platform/types/projects/__init__.py +25 -0
- nemo_platform/types/projects/project.py +45 -0
- nemo_platform/types/projects/project_create_params.py +37 -0
- nemo_platform/types/projects/project_list_params.py +49 -0
- nemo_platform/types/projects/project_sort_field.py +22 -0
- nemo_platform/types/projects/project_update_params.py +29 -0
- nemo_platform/types/projects/projects_page.py +37 -0
- nemo_platform/types/safe_synthesizer/__init__.py +68 -0
- nemo_platform/types/safe_synthesizer/classify_config.py +41 -0
- nemo_platform/types/safe_synthesizer/classify_config_param.py +43 -0
- nemo_platform/types/safe_synthesizer/column.py +46 -0
- nemo_platform/types/safe_synthesizer/column_actions.py +36 -0
- nemo_platform/types/safe_synthesizer/column_actions_param.py +38 -0
- nemo_platform/types/safe_synthesizer/column_param.py +49 -0
- nemo_platform/types/safe_synthesizer/data_parameters.py +69 -0
- nemo_platform/types/safe_synthesizer/data_parameters_param.py +69 -0
- nemo_platform/types/safe_synthesizer/differential_privacy_hyperparams.py +48 -0
- nemo_platform/types/safe_synthesizer/differential_privacy_hyperparams_param.py +48 -0
- nemo_platform/types/safe_synthesizer/evaluation_parameters.py +64 -0
- nemo_platform/types/safe_synthesizer/evaluation_parameters_param.py +66 -0
- nemo_platform/types/safe_synthesizer/generate_parameters.py +104 -0
- nemo_platform/types/safe_synthesizer/generate_parameters_param.py +102 -0
- nemo_platform/types/safe_synthesizer/gliner_config.py +41 -0
- nemo_platform/types/safe_synthesizer/gliner_config_param.py +41 -0
- nemo_platform/types/safe_synthesizer/globals.py +45 -0
- nemo_platform/types/safe_synthesizer/globals_param.py +47 -0
- nemo_platform/types/safe_synthesizer/job_create_params.py +46 -0
- nemo_platform/types/safe_synthesizer/job_get_logs_params.py +30 -0
- nemo_platform/types/safe_synthesizer/job_list_params.py +44 -0
- nemo_platform/types/safe_synthesizer/jobs/__init__.py +21 -0
- nemo_platform/types/safe_synthesizer/jobs/safe_synthesizer_summary.py +95 -0
- nemo_platform/types/safe_synthesizer/jobs/safe_synthesizer_timing.py +41 -0
- nemo_platform/types/safe_synthesizer/ner_config.py +42 -0
- nemo_platform/types/safe_synthesizer/ner_config_param.py +44 -0
- nemo_platform/types/safe_synthesizer/pii_replacer_config.py +40 -0
- nemo_platform/types/safe_synthesizer/pii_replacer_config_param.py +42 -0
- nemo_platform/types/safe_synthesizer/row.py +50 -0
- nemo_platform/types/safe_synthesizer/row_actions.py +33 -0
- nemo_platform/types/safe_synthesizer/row_actions_param.py +35 -0
- nemo_platform/types/safe_synthesizer/row_param.py +53 -0
- nemo_platform/types/safe_synthesizer/safe_synthesizer_job.py +63 -0
- nemo_platform/types/safe_synthesizer/safe_synthesizer_job_config.py +55 -0
- nemo_platform/types/safe_synthesizer/safe_synthesizer_job_config_param.py +56 -0
- nemo_platform/types/safe_synthesizer/safe_synthesizer_jobs_list_filter_param.py +49 -0
- nemo_platform/types/safe_synthesizer/safe_synthesizer_jobs_page.py +37 -0
- nemo_platform/types/safe_synthesizer/safe_synthesizer_jobs_sort_field.py +22 -0
- nemo_platform/types/safe_synthesizer/safe_synthesizer_parameters.py +91 -0
- nemo_platform/types/safe_synthesizer/safe_synthesizer_parameters_param.py +92 -0
- nemo_platform/types/safe_synthesizer/step_definition.py +39 -0
- nemo_platform/types/safe_synthesizer/step_definition_param.py +41 -0
- nemo_platform/types/safe_synthesizer/time_series_parameters.py +73 -0
- nemo_platform/types/safe_synthesizer/time_series_parameters_param.py +74 -0
- nemo_platform/types/safe_synthesizer/training_hyperparams.py +165 -0
- nemo_platform/types/safe_synthesizer/training_hyperparams_param.py +167 -0
- nemo_platform/types/safe_synthesizer/validation_parameters.py +54 -0
- nemo_platform/types/safe_synthesizer/validation_parameters_param.py +54 -0
- nemo_platform/types/secrets/__init__.py +28 -0
- nemo_platform/types/secrets/platform_secret_access_response.py +33 -0
- nemo_platform/types/secrets/platform_secret_admin_rotation_response.py +28 -0
- nemo_platform/types/secrets/platform_secret_response.py +40 -0
- nemo_platform/types/secrets/platform_secret_responses_page.py +37 -0
- nemo_platform/types/secrets/secret_create_params.py +39 -0
- nemo_platform/types/secrets/secret_list_params.py +32 -0
- nemo_platform/types/secrets/secret_update_params.py +32 -0
- nemo_platform/types/shared/__init__.py +50 -0
- nemo_platform/types/shared/api_endpoint_data.py +43 -0
- nemo_platform/types/shared/auth_context.py +48 -0
- nemo_platform/types/shared/auth_discovery_response.py +32 -0
- nemo_platform/types/shared/backend_format.py +22 -0
- nemo_platform/types/shared/datetime_filter.py +33 -0
- nemo_platform/types/shared/delete_response.py +33 -0
- nemo_platform/types/shared/error_response.py +46 -0
- nemo_platform/types/shared/field_error.py +28 -0
- nemo_platform/types/shared/file_storage_type.py +22 -0
- nemo_platform/types/shared/fileset_metadata.py +46 -0
- nemo_platform/types/shared/finetuning_type.py +48 -0
- nemo_platform/types/shared/generic_sort_field.py +22 -0
- nemo_platform/types/shared/http_validation_error.py +27 -0
- nemo_platform/types/shared/linear_layer_spec.py +33 -0
- nemo_platform/types/shared/mamba_config.py +44 -0
- nemo_platform/types/shared/mo_e_config.py +41 -0
- nemo_platform/types/shared/model_metadata_content.py +38 -0
- nemo_platform/types/shared/model_spec.py +111 -0
- nemo_platform/types/shared/oidc_discovery_response.py +42 -0
- nemo_platform/types/shared/pagination_data.py +37 -0
- nemo_platform/types/shared/platform_job_list_result_response.py +27 -0
- nemo_platform/types/shared/platform_job_log.py +34 -0
- nemo_platform/types/shared/platform_job_log_page.py +33 -0
- nemo_platform/types/shared/platform_job_result_response.py +44 -0
- nemo_platform/types/shared/platform_job_status.py +24 -0
- nemo_platform/types/shared/platform_job_status_response.py +48 -0
- nemo_platform/types/shared/platform_job_step_status_response.py +48 -0
- nemo_platform/types/shared/platform_job_task_status_response.py +47 -0
- nemo_platform/types/shared/prompt_data.py +47 -0
- nemo_platform/types/shared/sliding_window_config.py +27 -0
- nemo_platform/types/shared/tool_call_config.py +46 -0
- nemo_platform/types/shared/tool_calling_metadata_content.py +48 -0
- nemo_platform/types/shared/validation_error.py +34 -0
- nemo_platform/types/shared_params/__init__.py +33 -0
- nemo_platform/types/shared_params/api_endpoint_data.py +38 -0
- nemo_platform/types/shared_params/backend_format.py +24 -0
- nemo_platform/types/shared_params/datetime_filter.py +34 -0
- nemo_platform/types/shared_params/file_storage_type.py +24 -0
- nemo_platform/types/shared_params/finetuning_type.py +50 -0
- nemo_platform/types/shared_params/generic_sort_field.py +24 -0
- nemo_platform/types/shared_params/linear_layer_spec.py +35 -0
- nemo_platform/types/shared_params/mamba_config.py +44 -0
- nemo_platform/types/shared_params/mo_e_config.py +41 -0
- nemo_platform/types/shared_params/model_metadata_content.py +39 -0
- nemo_platform/types/shared_params/model_spec.py +113 -0
- nemo_platform/types/shared_params/platform_job_status.py +26 -0
- nemo_platform/types/shared_params/prompt_data.py +48 -0
- nemo_platform/types/shared_params/sliding_window_config.py +29 -0
- nemo_platform/types/shared_params/tool_call_config.py +46 -0
- nemo_platform/types/shared_params/tool_calling_metadata_content.py +48 -0
- nemo_platform/types/workspaces/__init__.py +24 -0
- nemo_platform/types/workspaces/workspace.py +48 -0
- nemo_platform/types/workspaces/workspace_create_params.py +41 -0
- nemo_platform/types/workspaces/workspace_list_params.py +47 -0
- nemo_platform/types/workspaces/workspace_update_params.py +27 -0
- nemo_platform/types/workspaces/workspaces_page.py +37 -0
- nemo_platform/ui/__init__.py +15 -0
- nemo_platform/ui/output.py +109 -0
- nemo_platform/ui/prompts.py +678 -0
- nemo_platform_plugin/.agents/skills/creating-a-plugin/SKILL.md +275 -0
- nemo_platform_plugin/.agents/skills/plugin-config/SKILL.md +168 -0
- nemo_platform_plugin/.agents/skills/plugin-controller/SKILL.md +320 -0
- nemo_platform_plugin/.agents/skills/plugin-entities/SKILL.md +290 -0
- nemo_platform_plugin/.agents/skills/plugin-function/SKILL.md +292 -0
- nemo_platform_plugin/.agents/skills/plugin-inference-middleware/SKILL.md +346 -0
- nemo_platform_plugin/.agents/skills/plugin-job/SKILL.md +247 -0
- nemo_platform_plugin/.agents/skills/plugin-platform-services/SKILL.md +239 -0
- nemo_platform_plugin/.agents/skills/plugin-platform-services/services-reference.md +192 -0
- nemo_platform_plugin/.agents/skills/plugin-service/SKILL.md +181 -0
- nemo_platform_plugin/.agents/skills/plugin-service/crud-example.md +353 -0
- nemo_platform_plugin/.agents/skills/plugin-testing/SKILL.md +206 -0
- nemo_platform_plugin/README.md +43 -0
- nemo_platform_plugin/_base.py +53 -0
- nemo_platform_plugin/_spec_flags.py +573 -0
- nemo_platform_plugin/api/filter.py +189 -0
- nemo_platform_plugin/api/parsed_filter.py +288 -0
- nemo_platform_plugin/api/text_filter.py +291 -0
- nemo_platform_plugin/cli.py +152 -0
- nemo_platform_plugin/cli_errors.py +232 -0
- nemo_platform_plugin/cli_renderer.py +92 -0
- nemo_platform_plugin/commands.py +1433 -0
- nemo_platform_plugin/config.py +844 -0
- nemo_platform_plugin/controller.py +148 -0
- nemo_platform_plugin/dependencies.py +64 -0
- nemo_platform_plugin/discovery.py +484 -0
- nemo_platform_plugin/docs/ARCHITECTURE.md +160 -0
- nemo_platform_plugin/docs/CONFIG.md +151 -0
- nemo_platform_plugin/docs/CONTROLLER.md +209 -0
- nemo_platform_plugin/docs/ENTITY.md +186 -0
- nemo_platform_plugin/docs/INFERENCE_MIDDLEWARE.md +408 -0
- nemo_platform_plugin/docs/JOB.md +237 -0
- nemo_platform_plugin/docs/QUICKSTART.md +306 -0
- nemo_platform_plugin/docs/SERVICE.md +302 -0
- nemo_platform_plugin/entities.py +793 -0
- nemo_platform_plugin/entity.py +79 -0
- nemo_platform_plugin/entity_client.py +54 -0
- nemo_platform_plugin/filter_ops.py +169 -0
- nemo_platform_plugin/function.py +299 -0
- nemo_platform_plugin/function_context.py +61 -0
- nemo_platform_plugin/functions/frames.py +69 -0
- nemo_platform_plugin/functions/routes.py +454 -0
- nemo_platform_plugin/inference_middleware.py +1191 -0
- nemo_platform_plugin/interface.py +28 -0
- nemo_platform_plugin/job.py +370 -0
- nemo_platform_plugin/job_context.py +86 -0
- nemo_platform_plugin/job_results.py +209 -0
- nemo_platform_plugin/jobs/_cli_options.py +204 -0
- nemo_platform_plugin/jobs/api_factory.py +1178 -0
- nemo_platform_plugin/jobs/constants.py +27 -0
- nemo_platform_plugin/jobs/docker.py +76 -0
- nemo_platform_plugin/jobs/exceptions.py +8 -0
- nemo_platform_plugin/jobs/file_manager.py +238 -0
- nemo_platform_plugin/jobs/openapi_utils.py +174 -0
- nemo_platform_plugin/jobs/profile.py +110 -0
- nemo_platform_plugin/jobs/result_manager.py +291 -0
- nemo_platform_plugin/jobs/routes.py +297 -0
- nemo_platform_plugin/jobs/schemas.py +174 -0
- nemo_platform_plugin/refs.py +154 -0
- nemo_platform_plugin/run_dependencies.py +137 -0
- nemo_platform_plugin/scheduler.py +537 -0
- nemo_platform_plugin/schema.py +216 -0
- nemo_platform_plugin/sdk.py +34 -0
- nemo_platform_plugin/seed.py +71 -0
- nemo_platform_plugin/service.py +130 -0
- nemo_platform_plugin/tasks/dispatcher.py +226 -0
- nemo_platform_plugin-0.1.0.dist-info/METADATA +88 -0
- nemo_platform_plugin-0.1.0.dist-info/RECORD +1224 -0
- nemo_platform_plugin-0.1.0.dist-info/WHEEL +4 -0
|
@@ -0,0 +1,1191 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
"""Inference middleware plugin interface — what plugin authors implement.
|
|
5
|
+
|
|
6
|
+
Plugin authors subclass :class:`NemoInferenceMiddleware` and register a
|
|
7
|
+
class under the ``nemo.inference_middleware`` entry-point group in their
|
|
8
|
+
plugin's ``pyproject.toml``. IGW discovers and loads these plugins at
|
|
9
|
+
startup.
|
|
10
|
+
|
|
11
|
+
Example::
|
|
12
|
+
|
|
13
|
+
# nemo_switchyard_plugin/middleware.py
|
|
14
|
+
from nemo_platform_plugin.inference_middleware import (
|
|
15
|
+
InferenceMiddlewareContext,
|
|
16
|
+
InferenceRequest,
|
|
17
|
+
InferenceResponse,
|
|
18
|
+
ImmediateResponse,
|
|
19
|
+
NemoInferenceMiddleware,
|
|
20
|
+
VirtualModel,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
class SwitchyardMiddleware(NemoInferenceMiddleware):
|
|
24
|
+
async def on_startup(self) -> None:
|
|
25
|
+
# Validate configured model entities exist at startup
|
|
26
|
+
entities = self.list_model_entities_for_workspace("my-workspace")
|
|
27
|
+
...
|
|
28
|
+
|
|
29
|
+
async def get_middleware_config(
|
|
30
|
+
self, config_type: str, config_id: str
|
|
31
|
+
) -> Any:
|
|
32
|
+
# Plugin owns config storage — fetch from entity store
|
|
33
|
+
ws, name = config_id.split("/", 1)
|
|
34
|
+
return await self._entity_client.get(RouteLLMConfig, workspace=ws, name=name)
|
|
35
|
+
|
|
36
|
+
async def validate_middleware_config(
|
|
37
|
+
self, config_type: str, config: Any
|
|
38
|
+
) -> Any:
|
|
39
|
+
if config_type == "routellm_config":
|
|
40
|
+
return RouteLLMConfig.model_validate(config)
|
|
41
|
+
raise ValueError(f"Unknown config_type: {config_type!r}")
|
|
42
|
+
|
|
43
|
+
async def process_request(
|
|
44
|
+
self,
|
|
45
|
+
ctx: InferenceMiddlewareContext,
|
|
46
|
+
request: InferenceRequest,
|
|
47
|
+
middleware_config: Any,
|
|
48
|
+
) -> InferenceRequest | ImmediateResponse:
|
|
49
|
+
chosen_model = self._run_routellm(request.body, middleware_config)
|
|
50
|
+
request.body["model"] = chosen_model
|
|
51
|
+
return request
|
|
52
|
+
|
|
53
|
+
async def process_response(
|
|
54
|
+
self,
|
|
55
|
+
ctx: InferenceMiddlewareContext,
|
|
56
|
+
response: InferenceResponse,
|
|
57
|
+
middleware_config: Any,
|
|
58
|
+
) -> InferenceResponse:
|
|
59
|
+
# ctx.original_request holds what the client sent (before any plugin ran)
|
|
60
|
+
# ctx.proxied_request holds what was forwarded to the backend
|
|
61
|
+
# ctx.state("my-plugin").get("key") retrieves state set in process_request
|
|
62
|
+
return response
|
|
63
|
+
|
|
64
|
+
# pyproject.toml:
|
|
65
|
+
# [project.entry-points."nemo.inference_middleware"]
|
|
66
|
+
# nemo-switchyard = "nemo_switchyard_plugin.middleware:SwitchyardMiddleware"
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
from __future__ import annotations
|
|
70
|
+
|
|
71
|
+
from abc import ABC
|
|
72
|
+
from dataclasses import dataclass, field
|
|
73
|
+
from enum import Enum
|
|
74
|
+
from typing import Any, AsyncIterator, Protocol, TypeAlias, Union, runtime_checkable
|
|
75
|
+
|
|
76
|
+
import anthropic.types as anthropic_types
|
|
77
|
+
import anthropic.types.message_create_params as anthropic_params
|
|
78
|
+
import openai.types.chat as openai_chat_types
|
|
79
|
+
import openai.types.chat.completion_create_params as openai_chat_params
|
|
80
|
+
import openai.types.responses.response_create_params as openai_responses_params
|
|
81
|
+
from nemo_platform_plugin.entity import NemoEntity
|
|
82
|
+
from pydantic import BaseModel, Field
|
|
83
|
+
|
|
84
|
+
TypedResponse: TypeAlias = Union[openai_chat_types.ChatCompletion, anthropic_types.Message]
|
|
85
|
+
OpenAIResponseChunk: TypeAlias = openai_chat_types.ChatCompletionChunk
|
|
86
|
+
AnthropicResponseChunk: TypeAlias = anthropic_types.RawMessageStreamEvent
|
|
87
|
+
TypedResponseChunk: TypeAlias = Union[OpenAIResponseChunk, AnthropicResponseChunk]
|
|
88
|
+
TypedResponseResult: TypeAlias = Union[TypedResponse, AsyncIterator[TypedResponseChunk]]
|
|
89
|
+
|
|
90
|
+
TypedRequest: TypeAlias = Union[
|
|
91
|
+
openai_chat_params.CompletionCreateParamsBase,
|
|
92
|
+
anthropic_params.MessageCreateParamsBase,
|
|
93
|
+
openai_responses_params.ResponseCreateParamsBase,
|
|
94
|
+
]
|
|
95
|
+
"""Union of the SDK TypedDict param types for each inbound API format.
|
|
96
|
+
|
|
97
|
+
All three are TypedDicts — plain dicts at runtime. This alias exists for
|
|
98
|
+
static type checking. Plugins that need path-based dispatch should use
|
|
99
|
+
``request.path``, not ``isinstance``, since isinstance on TypedDict types
|
|
100
|
+
just checks ``isinstance(x, dict)``.
|
|
101
|
+
"""
|
|
102
|
+
|
|
103
|
+
# ---------------------------------------------------------------------------
|
|
104
|
+
# VirtualModel entity and MiddlewareCall schema
|
|
105
|
+
# ---------------------------------------------------------------------------
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
class MiddlewareCall(BaseModel):
|
|
109
|
+
"""One entry in a VirtualModel middleware pipeline.
|
|
110
|
+
|
|
111
|
+
Declares which plugin to invoke and how to resolve its configuration.
|
|
112
|
+
Exactly one of ``config`` (inline dict) or ``config_id`` (entity reference)
|
|
113
|
+
should be provided. ``config_type`` is always required regardless of which
|
|
114
|
+
is used — it is the discriminator that tells IGW (and the plugin) which
|
|
115
|
+
config schema applies.
|
|
116
|
+
|
|
117
|
+
Attributes:
|
|
118
|
+
name: The entry-point key of the plugin to invoke
|
|
119
|
+
(e.g. ``"nemo-switchyard"``). Must match the plugin's
|
|
120
|
+
``nemo.inference_middleware`` entry-point key.
|
|
121
|
+
config_type: Always required. Maps to the ``entity_type`` of the plugin's
|
|
122
|
+
config ``NemoEntity`` subclass (e.g. ``"routellm_config"``). Used by
|
|
123
|
+
IGW to call :meth:`~NemoInferenceMiddleware.validate_middleware_config`
|
|
124
|
+
with the right discriminator, and by the plugin to dispatch to the
|
|
125
|
+
correct schema when it supports multiple config types.
|
|
126
|
+
config: Inline config dict. Mutually exclusive with ``config_id``.
|
|
127
|
+
config_id: ``"workspace/name"`` reference to a stored config entity.
|
|
128
|
+
Mutually exclusive with ``config``. IGW resolves this by calling
|
|
129
|
+
:meth:`~NemoInferenceMiddleware.get_middleware_config` on the plugin.
|
|
130
|
+
"""
|
|
131
|
+
|
|
132
|
+
name: str
|
|
133
|
+
config_type: str
|
|
134
|
+
config: dict[str, Any] | None = None
|
|
135
|
+
config_id: str | None = None
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class BackendFormat(str, Enum):
|
|
139
|
+
"""Inference backend API wire formats understood by IGW and middleware plugins."""
|
|
140
|
+
|
|
141
|
+
OPENAI_CHAT = "OPENAI_CHAT"
|
|
142
|
+
ANTHROPIC_MESSAGES = "ANTHROPIC_MESSAGES"
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
class VirtualModelInferenceConfig(BaseModel):
|
|
146
|
+
"""Inference configuration for one model entity referenced by a VirtualModel."""
|
|
147
|
+
|
|
148
|
+
model: str
|
|
149
|
+
"""Model entity reference in ``"workspace/name"`` format."""
|
|
150
|
+
|
|
151
|
+
backend_format: BackendFormat | None = Field(
|
|
152
|
+
default=None,
|
|
153
|
+
description="Optional backend format override for this VirtualModel entry.",
|
|
154
|
+
json_schema_extra={"nullable": True},
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
_AUTOPROVISIONED_DESC = (
|
|
159
|
+
"Marks this VirtualModel as controller-managed. The Models controller will delete it once no "
|
|
160
|
+
"ModelProvider serves the matching entity. Setting this manually opts the VirtualModel into "
|
|
161
|
+
"that cleanup behavior."
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
class VirtualModel(NemoEntity, entity_type="virtual_model"):
|
|
166
|
+
"""Logical inference route.
|
|
167
|
+
|
|
168
|
+
Maps a user-facing model name to an optional default model entity and
|
|
169
|
+
defines ordered middleware pipelines for the request, response, and
|
|
170
|
+
post-response phases.
|
|
171
|
+
|
|
172
|
+
When a caller sets ``model: "workspace/my-virtual-model"`` in an inference
|
|
173
|
+
request, IGW resolves the ``VirtualModel`` instead of a ``ModelEntity``
|
|
174
|
+
directly. If ``default_model_entity`` is set, IGW writes it into
|
|
175
|
+
``request["model"]`` before the request middleware pipeline runs. Middleware
|
|
176
|
+
may mutate ``request["model"]`` freely. After the pipeline completes, IGW
|
|
177
|
+
reads ``request["model"]``, resolves it to a ``ModelProvider`` via the
|
|
178
|
+
``ModelCache``, and proxies.
|
|
179
|
+
|
|
180
|
+
The ``ModelProviderReconciler`` auto-creates a passthrough ``VirtualModel``
|
|
181
|
+
for each discovered model (same workspace and name as the ``ModelEntity``,
|
|
182
|
+
empty middleware lists, ``default_model_entity`` pointing to that entity).
|
|
183
|
+
All existing inference requests continue to work without changes.
|
|
184
|
+
"""
|
|
185
|
+
|
|
186
|
+
default_model_entity: str | None = None
|
|
187
|
+
"""``"workspace/model-entity-name"`` written into ``request["model"]`` before
|
|
188
|
+
the request middleware pipeline runs. If ``None``, no value is written — a
|
|
189
|
+
request middleware plugin must handle the backend call itself and return an
|
|
190
|
+
:class:`InferenceResponse` or ``AsyncIterator``."""
|
|
191
|
+
|
|
192
|
+
autoprovisioned: bool = Field(
|
|
193
|
+
default=False,
|
|
194
|
+
description=_AUTOPROVISIONED_DESC,
|
|
195
|
+
)
|
|
196
|
+
"""Whether this VirtualModel was automatically created by the
|
|
197
|
+
ModelProviderReconciler for a discovered model entity."""
|
|
198
|
+
|
|
199
|
+
models: list[VirtualModelInferenceConfig] = Field(default_factory=list)
|
|
200
|
+
"""Model entity references used by this VirtualModel. A per-entry
|
|
201
|
+
``backend_format`` overrides the referenced ModelEntity value for requests
|
|
202
|
+
resolved through this VirtualModel."""
|
|
203
|
+
|
|
204
|
+
request_middleware: list[MiddlewareCall] = []
|
|
205
|
+
"""Ordered list of middleware plugins applied before proxying."""
|
|
206
|
+
|
|
207
|
+
response_middleware: list[MiddlewareCall] = []
|
|
208
|
+
"""Ordered list of middleware plugins applied after the backend response is
|
|
209
|
+
received, before returning it to the caller."""
|
|
210
|
+
|
|
211
|
+
post_response_middleware: list[MiddlewareCall] = []
|
|
212
|
+
"""Ordered list of middleware plugins invoked after the response has been
|
|
213
|
+
returned to the caller. Intended for fire-and-forget work (e.g. logging,
|
|
214
|
+
analytics) that must not block or modify the response."""
|
|
215
|
+
|
|
216
|
+
override_proxy: str | None = None
|
|
217
|
+
"""Optional. Names a plugin-provided proxy implementation IGW should use
|
|
218
|
+
instead of its default ``aiohttp`` proxy. Format: ``"plugin-name.proxy-name"``.
|
|
219
|
+
If unset, IGW performs the proxy itself."""
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
# ---------------------------------------------------------------------------
|
|
223
|
+
# Public types
|
|
224
|
+
# ---------------------------------------------------------------------------
|
|
225
|
+
|
|
226
|
+
ResponseResult = Union[dict[str, Any], AsyncIterator[dict[str, Any]]]
|
|
227
|
+
"""The underlying response data flowing through the response middleware chain.
|
|
228
|
+
|
|
229
|
+
- ``dict[str, Any]`` — Non-streaming response parsed from the backend.
|
|
230
|
+
- ``AsyncIterator[dict[str, Any]]`` — Streaming response (sequence of chunk dicts).
|
|
231
|
+
"""
|
|
232
|
+
|
|
233
|
+
|
|
234
|
+
@dataclass
|
|
235
|
+
class InferenceRequest:
|
|
236
|
+
"""Typed envelope for request pipeline data.
|
|
237
|
+
|
|
238
|
+
Passed to :meth:`NemoInferenceMiddleware.process_request` and returned from it.
|
|
239
|
+
Plugins may mutate ``body``, ``headers``, and ``path`` in-place and return
|
|
240
|
+
``self``, or construct a new instance — either style is valid.
|
|
241
|
+
|
|
242
|
+
All three fields are required. When constructing a new instance instead of
|
|
243
|
+
mutating in-place, always copy ``path`` from the incoming request::
|
|
244
|
+
|
|
245
|
+
# correct
|
|
246
|
+
return InferenceRequest(
|
|
247
|
+
body={**request.body, "model": chosen},
|
|
248
|
+
headers=request.headers,
|
|
249
|
+
path=request.path,
|
|
250
|
+
)
|
|
251
|
+
|
|
252
|
+
Omitting ``path`` is a compile-time error. This prevents the silent 404
|
|
253
|
+
that would result from sending the request to the backend root URL.
|
|
254
|
+
|
|
255
|
+
``typed_body`` does not need to be copied or re-derived manually when
|
|
256
|
+
constructing a new instance. IGW automatically re-derives ``typed_body``
|
|
257
|
+
from ``body`` and ``path`` between every plugin in the request middleware
|
|
258
|
+
chain, so the next plugin always receives a fresh, consistent typed view
|
|
259
|
+
regardless of what the previous plugin returned.
|
|
260
|
+
|
|
261
|
+
Attributes:
|
|
262
|
+
body: OpenAI-compatible request body dict (e.g. ``{"model": ..., "messages": [...]}``.
|
|
263
|
+
When called, ``body["model"]`` contains the model entity written by IGW from
|
|
264
|
+
``VirtualModel.default_model_entity`` (if set). Middleware may freely rewrite it.
|
|
265
|
+
headers: HTTP request headers forwarded to each plugin in the chain.
|
|
266
|
+
path: Backend-relative path (e.g. ``"v1/chat/completions"``). IGW sets the
|
|
267
|
+
initial value from the incoming request URI. Middleware may rewrite this to
|
|
268
|
+
any arbitrary path and IGW will proxy to that path instead.
|
|
269
|
+
typed_body: SDK-typed view of the request body validated against the TypedDict
|
|
270
|
+
schema for this path. ``None`` when the path is unknown or body validation
|
|
271
|
+
fails.
|
|
272
|
+
|
|
273
|
+
Mirrors ``InferenceResponse.typed_body``: just as
|
|
274
|
+
``response.typed_body`` is the typed view of ``result``,
|
|
275
|
+
``request.typed_body`` is the typed view of ``body``.
|
|
276
|
+
|
|
277
|
+
All three SDK request param types are TypedDicts — plain dicts at runtime.
|
|
278
|
+
This field is validated by IGW before the request middleware chain runs.
|
|
279
|
+
Plugins that need cross-format awareness read ``request.path`` to determine
|
|
280
|
+
format and use this as a type-checked alias for ``body``.
|
|
281
|
+
|
|
282
|
+
Parsed non-fatally: a body that fails TypedDict validation is not an error
|
|
283
|
+
— the plugin receives ``typed_body=None`` and falls back to ``body`` or
|
|
284
|
+
raises a descriptive error as needed.
|
|
285
|
+
"""
|
|
286
|
+
|
|
287
|
+
body: dict[str, Any]
|
|
288
|
+
headers: dict[str, str]
|
|
289
|
+
path: str
|
|
290
|
+
typed_body: TypedRequest | None = None
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
@dataclass
|
|
294
|
+
class InferenceResponse:
|
|
295
|
+
"""Typed envelope for response pipeline data.
|
|
296
|
+
|
|
297
|
+
Passed to :meth:`NemoInferenceMiddleware.process_response` and returned from it.
|
|
298
|
+
Plugins may mutate the canonical response view plus ``headers`` in-place and
|
|
299
|
+
return ``self``, or construct a new instance — either style is valid.
|
|
300
|
+
``typed_body`` is populated by IGW when it can parse the payload for the
|
|
301
|
+
resolved backend format.
|
|
302
|
+
|
|
303
|
+
Canonical response contract: for non-streaming responses, when
|
|
304
|
+
``typed_body`` is not ``None``, it is the canonical response view and IGW
|
|
305
|
+
serializes it instead of ``result``. Streaming ``typed_body`` is a
|
|
306
|
+
middleware-only typed view; IGW serializes the raw ``result`` stream. When
|
|
307
|
+
``typed_body`` is ``None``, ``result`` is canonical. Middleware should
|
|
308
|
+
mutate exactly one canonical view. IGW does not keep ``result`` and
|
|
309
|
+
``typed_body`` synchronized between plugins.
|
|
310
|
+
|
|
311
|
+
Plugins can manipulate the response payload or headers in the following ways:
|
|
312
|
+
|
|
313
|
+
- Mutate existing payload fields (for example, redact
|
|
314
|
+
``choices[0].message.content``) by mutating ``typed_body`` when available,
|
|
315
|
+
or ``result`` when no typed view exists.
|
|
316
|
+
- Add new top-level response fields (for example, guardrails metadata)
|
|
317
|
+
by writing to ``response_body_annotations``.
|
|
318
|
+
- Modify HTTP response headers by mutating ``headers``.
|
|
319
|
+
|
|
320
|
+
Attributes:
|
|
321
|
+
result: The response data — either a ``dict[str, Any]`` (non-streaming) or an
|
|
322
|
+
``AsyncIterator[dict[str, Any]]`` (streaming). Passed to the next plugin in
|
|
323
|
+
the chain, or returned to the caller if this is the last plugin. For
|
|
324
|
+
non-streaming responses, mutate this only when ``typed_body`` is ``None``.
|
|
325
|
+
For streaming responses, mutate or replace this when changing the outbound
|
|
326
|
+
client stream.
|
|
327
|
+
headers: HTTP response headers returned to the caller. Mutate to add or modify
|
|
328
|
+
headers (e.g. ``X-Guardrails-Status``). Changes flow through the return value.
|
|
329
|
+
typed_body: SDK-native parsed response data for middleware that wants
|
|
330
|
+
typed access. ``None`` when the backend format is unknown or parsing fails.
|
|
331
|
+
For non-streaming responses, if this is non-``None``, it is canonical.
|
|
332
|
+
For streaming responses, it is a middleware-only view over the raw stream.
|
|
333
|
+
If a plugin needs to return a non-streaming shape that does not fit the
|
|
334
|
+
typed SDK schema, it must set ``response.typed_body = None`` and mutate
|
|
335
|
+
``response.result`` instead.
|
|
336
|
+
|
|
337
|
+
Mirrors ``InferenceRequest.typed_body``: just as ``request.typed_body`` is
|
|
338
|
+
the typed view of ``body``, ``response.typed_body`` is the typed view of
|
|
339
|
+
``result``.
|
|
340
|
+
response_body_annotations: Top-level fields to be merged into the final
|
|
341
|
+
response body after all middleware have run. Use this — not ``result``
|
|
342
|
+
or ``typed_body`` — when adding fields that do not belong to the
|
|
343
|
+
OpenAI/Anthropic payload schema (e.g. guardrails metadata, custom
|
|
344
|
+
plugin telemetry). For non-streaming responses, IGW merges these into
|
|
345
|
+
the serialized payload just before returning to the caller. For
|
|
346
|
+
streaming responses, annotations are not injected in the initial
|
|
347
|
+
implementation.
|
|
348
|
+
|
|
349
|
+
Once an :class:`InferenceResponse` exists, this field is the
|
|
350
|
+
canonical response-annotation owner. IGW may seed it from
|
|
351
|
+
:attr:`InferenceMiddlewareContext.response_body_annotations` when
|
|
352
|
+
building the envelope, but later response middleware can read,
|
|
353
|
+
preserve, modify, or remove annotations here.
|
|
354
|
+
|
|
355
|
+
Keys in ``response_body_annotations`` take precedence
|
|
356
|
+
over payload keys on collision. Use plugin-scoped names (e.g.
|
|
357
|
+
``"guardrails_data"``, not ``"status"``) to avoid cross-plugin collisions.
|
|
358
|
+
"""
|
|
359
|
+
|
|
360
|
+
result: ResponseResult
|
|
361
|
+
headers: dict[str, str]
|
|
362
|
+
typed_body: TypedResponseResult | None = None
|
|
363
|
+
response_body_annotations: dict[str, Any] = field(default_factory=dict)
|
|
364
|
+
|
|
365
|
+
|
|
366
|
+
@dataclass
|
|
367
|
+
class ImmediateResponse:
|
|
368
|
+
"""Plugin-provided response that short-circuits the IGW proxy.
|
|
369
|
+
|
|
370
|
+
Return this from :meth:`NemoInferenceMiddleware.process_request` to signal
|
|
371
|
+
that the plugin has handled the request itself and IGW should skip the
|
|
372
|
+
backend proxy. IGW passes ``data`` to the response middleware chain.
|
|
373
|
+
|
|
374
|
+
``data`` is a :data:`ResponseResult` — either a ``dict[str, Any]`` for a
|
|
375
|
+
non-streaming response, or an ``AsyncIterator[dict[str, Any]]`` for a
|
|
376
|
+
streaming response.
|
|
377
|
+
|
|
378
|
+
``response_body_annotations`` follows the same contract as
|
|
379
|
+
:attr:`InferenceResponse.response_body_annotations`; use it to add
|
|
380
|
+
top-level response fields on short-circuited responses.
|
|
381
|
+
|
|
382
|
+
Example::
|
|
383
|
+
|
|
384
|
+
async def process_request(
|
|
385
|
+
self, ctx, request: InferenceRequest, middleware_config
|
|
386
|
+
) -> InferenceRequest | ImmediateResponse:
|
|
387
|
+
result = await self._call_my_model(request.body)
|
|
388
|
+
return ImmediateResponse(data=result) # skip proxy
|
|
389
|
+
"""
|
|
390
|
+
|
|
391
|
+
data: ResponseResult
|
|
392
|
+
response_body_annotations: dict[str, Any] = field(default_factory=dict)
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
class PluginStateNamespace:
|
|
396
|
+
"""Per-plugin scratch space inside :class:`InferenceMiddlewareContext`.
|
|
397
|
+
|
|
398
|
+
Returned by ``ctx.state("my-plugin")``. Keys are automatically namespaced
|
|
399
|
+
by the plugin name so plugins cannot accidentally collide with each other::
|
|
400
|
+
|
|
401
|
+
state = ctx.state("my-plugin")
|
|
402
|
+
state.set("token", auth_token) # stored as "my-plugin:token"
|
|
403
|
+
token = state.get("token")
|
|
404
|
+
state.has("token") # True
|
|
405
|
+
state.delete("token")
|
|
406
|
+
|
|
407
|
+
The underlying store is shared across the entire request so data set by
|
|
408
|
+
one plugin in ``process_request`` is visible to the same plugin (and any
|
|
409
|
+
other plugin that knows the key) in ``process_response``.
|
|
410
|
+
"""
|
|
411
|
+
|
|
412
|
+
def __init__(self, *, plugin_name: str, _store: dict[str, Any]) -> None:
|
|
413
|
+
self._prefix = f"{plugin_name}:"
|
|
414
|
+
self._store = _store
|
|
415
|
+
|
|
416
|
+
def set(self, key: str, value: Any) -> None:
|
|
417
|
+
"""Store *value* under *key* (namespaced to this plugin)."""
|
|
418
|
+
self._store[self._prefix + key] = value
|
|
419
|
+
|
|
420
|
+
def get(self, key: str, default: Any = None) -> Any:
|
|
421
|
+
"""Return the value for *key*, or *default* if not set."""
|
|
422
|
+
return self._store.get(self._prefix + key, default)
|
|
423
|
+
|
|
424
|
+
def delete(self, key: str) -> None:
|
|
425
|
+
"""Remove *key* from state (no-op if not present)."""
|
|
426
|
+
self._store.pop(self._prefix + key, None)
|
|
427
|
+
|
|
428
|
+
def has(self, key: str) -> bool:
|
|
429
|
+
"""Return ``True`` if *key* is present in state."""
|
|
430
|
+
return (self._prefix + key) in self._store
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
@dataclass
|
|
434
|
+
class InferenceMiddlewareContext:
|
|
435
|
+
"""Per-request context constructed once by IGW and passed to every middleware hook.
|
|
436
|
+
|
|
437
|
+
Plugins should not construct this themselves — IGW creates exactly one
|
|
438
|
+
instance per VirtualModel request and passes it to every ``process_request``
|
|
439
|
+
and ``process_response`` call that runs for that request.
|
|
440
|
+
|
|
441
|
+
The read-only fields (``request_id``, ``workspace``, ``virtual_model_name``,
|
|
442
|
+
``original_request``, ``proxied_request``) are IGW-owned invariants.
|
|
443
|
+
``state()`` provides the plugin-owned scratch space for cross-hook communication.
|
|
444
|
+
|
|
445
|
+
Attributes:
|
|
446
|
+
request_id: Unique identifier for this request, taken from the incoming
|
|
447
|
+
``X-Request-ID`` header or generated by IGW.
|
|
448
|
+
virtual_model_name: Name of the :class:`VirtualModel` being served
|
|
449
|
+
(``"workspace/name"`` format not included here — just the ``name``).
|
|
450
|
+
workspace: Workspace owning the VirtualModel.
|
|
451
|
+
original_request: The request as IGW received it, after seeding
|
|
452
|
+
``body["model"]`` from ``VirtualModel.default_model_entity`` but before
|
|
453
|
+
any request middleware plugin ran. Read-only by convention.
|
|
454
|
+
Available in both ``process_request`` and ``process_response``.
|
|
455
|
+
proxied_request: The request as it was forwarded to the backend — set by IGW
|
|
456
|
+
after the full request middleware chain completes, before the response
|
|
457
|
+
middleware chain runs. ``None`` during ``process_request`` and when an
|
|
458
|
+
:class:`ImmediateResponse` short-circuited the proxy. Read-only by
|
|
459
|
+
convention.
|
|
460
|
+
backend_format: Resolved backend API format used to parse typed responses.
|
|
461
|
+
Defaults to ``None`` until IGW has resolved the request target.
|
|
462
|
+
response_body_annotations: Top-level fields to merge into the final
|
|
463
|
+
response body after all middleware have run. Request middleware can
|
|
464
|
+
use this when it needs to annotate the eventual backend response
|
|
465
|
+
before an :class:`InferenceResponse` exists. This is a staging
|
|
466
|
+
bridge only: IGW copies these values into
|
|
467
|
+
:attr:`InferenceResponse.response_body_annotations` when it builds
|
|
468
|
+
the response envelope, and final serialization uses the
|
|
469
|
+
``InferenceResponse`` field.
|
|
470
|
+
"""
|
|
471
|
+
|
|
472
|
+
request_id: str
|
|
473
|
+
virtual_model_name: str
|
|
474
|
+
workspace: str
|
|
475
|
+
original_request: InferenceRequest
|
|
476
|
+
proxied_request: InferenceRequest | None = None
|
|
477
|
+
backend_format: BackendFormat | None = None
|
|
478
|
+
response_body_annotations: dict[str, Any] = field(default_factory=dict)
|
|
479
|
+
_state: dict[str, Any] = field(default_factory=dict, init=False, repr=False)
|
|
480
|
+
|
|
481
|
+
def state(self, plugin_name: str) -> PluginStateNamespace:
|
|
482
|
+
"""Return the :class:`PluginStateNamespace` for *plugin_name*.
|
|
483
|
+
|
|
484
|
+
Each call returns a lightweight wrapper around the same shared store —
|
|
485
|
+
creating multiple wrappers for the same name is safe.
|
|
486
|
+
|
|
487
|
+
Args:
|
|
488
|
+
plugin_name: The entry-point key of the plugin (e.g. ``"nemo-guardrails"``).
|
|
489
|
+
Use your own plugin name to avoid colliding with other plugins' state.
|
|
490
|
+
"""
|
|
491
|
+
return PluginStateNamespace(plugin_name=plugin_name, _store=self._state)
|
|
492
|
+
|
|
493
|
+
|
|
494
|
+
@dataclass
|
|
495
|
+
class ModelProviderInferenceTarget:
|
|
496
|
+
"""Provider gateway URL and served model name for a direct inference call.
|
|
497
|
+
|
|
498
|
+
Returned by :meth:`NemoInferenceMiddleware.get_inference_url_and_model`.
|
|
499
|
+
Both values are resolved from the same provider selection, guaranteeing
|
|
500
|
+
they are mutually consistent.
|
|
501
|
+
|
|
502
|
+
Use ``model_provider_gateway_url`` as the OpenAI client base URL and
|
|
503
|
+
``served_model_name`` as the value for ``body["model"]``::
|
|
504
|
+
|
|
505
|
+
target = self.get_inference_url_and_model("ws/llama-70b")
|
|
506
|
+
response = await client.post(
|
|
507
|
+
f"{target.model_provider_gateway_url}/chat/completions",
|
|
508
|
+
json={**body, "model": target.served_model_name},
|
|
509
|
+
)
|
|
510
|
+
"""
|
|
511
|
+
|
|
512
|
+
model_provider_gateway_url: str
|
|
513
|
+
"""IGW provider gateway URL — routes directly to the backend provider,
|
|
514
|
+
bypassing virtual model routing and the middleware chain."""
|
|
515
|
+
|
|
516
|
+
served_model_name: str
|
|
517
|
+
"""The raw model ID the backend expects in ``body["model"]``
|
|
518
|
+
(e.g. ``"meta/llama-3.1-70b-instruct"``)."""
|
|
519
|
+
|
|
520
|
+
|
|
521
|
+
@dataclass
|
|
522
|
+
class OpenAICompatibleInferenceTarget:
|
|
523
|
+
"""OpenAI-compatible IGW URL and VirtualModel ID for routed inference calls.
|
|
524
|
+
|
|
525
|
+
Returned by :meth:`NemoInferenceMiddleware.get_openai_compatible_inference_url_and_model`.
|
|
526
|
+
Use this when plugin-owned model calls should go through IGW's OpenAI-compatible
|
|
527
|
+
VirtualModel route instead of calling a provider directly.
|
|
528
|
+
"""
|
|
529
|
+
|
|
530
|
+
openai_base_url: str
|
|
531
|
+
"""OpenAI-compatible IGW base URL ending in ``/v1``."""
|
|
532
|
+
|
|
533
|
+
model: str
|
|
534
|
+
"""Workspace-qualified VirtualModel ID to send in ``body["model"]``."""
|
|
535
|
+
|
|
536
|
+
|
|
537
|
+
RequestResult = Union[InferenceRequest, ImmediateResponse]
|
|
538
|
+
"""Return type for :meth:`NemoInferenceMiddleware.process_request`.
|
|
539
|
+
|
|
540
|
+
- :class:`InferenceRequest` — IGW proxies the (possibly modified) request.
|
|
541
|
+
- :class:`ImmediateResponse` — Plugin handled the request itself; IGW skips the
|
|
542
|
+
proxy and passes ``data`` (a :data:`ResponseResult`) to the response middleware chain.
|
|
543
|
+
"""
|
|
544
|
+
|
|
545
|
+
# ---------------------------------------------------------------------------
|
|
546
|
+
# Platform entity Protocols
|
|
547
|
+
# ---------------------------------------------------------------------------
|
|
548
|
+
|
|
549
|
+
|
|
550
|
+
@runtime_checkable
|
|
551
|
+
class ModelSpec(Protocol):
|
|
552
|
+
"""Structural view of a model's specification.
|
|
553
|
+
|
|
554
|
+
Concrete type: ``nmp.core.models.schemas.ModelSpec``.
|
|
555
|
+
"""
|
|
556
|
+
|
|
557
|
+
is_chat: bool | None
|
|
558
|
+
"""Whether this model is a chat/instruction-tuned model."""
|
|
559
|
+
|
|
560
|
+
is_embedding_model: bool
|
|
561
|
+
"""Whether this model produces embeddings rather than completions."""
|
|
562
|
+
|
|
563
|
+
context_size: int | None
|
|
564
|
+
"""Maximum context window in tokens, or ``None`` if unspecified."""
|
|
565
|
+
|
|
566
|
+
family: str
|
|
567
|
+
"""Model family identifier (e.g. ``"llama"``, ``"mistral"``)."""
|
|
568
|
+
|
|
569
|
+
|
|
570
|
+
@runtime_checkable
|
|
571
|
+
class ModelEntity(Protocol):
|
|
572
|
+
"""Structural view of a registered model entity.
|
|
573
|
+
|
|
574
|
+
Concrete type: ``nmp.core.models.schemas.ModelEntity``.
|
|
575
|
+
Defined here as a Protocol so ``nemo_platform_plugin`` does not depend on the
|
|
576
|
+
models service package.
|
|
577
|
+
|
|
578
|
+
When the models service is migrated to define ``ModelEntity`` as a
|
|
579
|
+
``NemoEntity`` subclass in ``nemo_platform_plugin``, this Protocol is replaced
|
|
580
|
+
in-place — plugin authors' import paths and field access are unchanged.
|
|
581
|
+
"""
|
|
582
|
+
|
|
583
|
+
workspace: str
|
|
584
|
+
"""Workspace this entity belongs to."""
|
|
585
|
+
|
|
586
|
+
name: str
|
|
587
|
+
"""Entity name within the workspace."""
|
|
588
|
+
|
|
589
|
+
spec: ModelSpec | None
|
|
590
|
+
"""Model specification — capabilities, architecture family, context size.
|
|
591
|
+
``None`` for externally-hosted models registered without a spec."""
|
|
592
|
+
|
|
593
|
+
finetuning_type: str | None
|
|
594
|
+
"""How this model was fine-tuned (e.g. ``"lora_merged"``, ``"all_weights"``),
|
|
595
|
+
or ``None`` for base models."""
|
|
596
|
+
|
|
597
|
+
backend_format: BackendFormat | None
|
|
598
|
+
"""Inference API wire format expected by the backend, or ``None`` when unset.
|
|
599
|
+
IGW treats ``None`` as ``OPENAI_CHAT`` during routing."""
|
|
600
|
+
|
|
601
|
+
providers: list[ModelProvider]
|
|
602
|
+
"""All :class:`ModelProvider`\\ s currently serving this model entity.
|
|
603
|
+
Empty if no provider is actively serving it."""
|
|
604
|
+
|
|
605
|
+
|
|
606
|
+
@runtime_checkable
|
|
607
|
+
class ModelProvider(Protocol):
|
|
608
|
+
"""Structural view of a model provider as seen by inference middleware.
|
|
609
|
+
|
|
610
|
+
Concrete type: ``nmp.core.models.entities.ModelProvider``.
|
|
611
|
+
Defined here as a Protocol so ``nemo_platform_plugin`` does not depend on the
|
|
612
|
+
models service package.
|
|
613
|
+
"""
|
|
614
|
+
|
|
615
|
+
workspace: str
|
|
616
|
+
"""Workspace this provider belongs to."""
|
|
617
|
+
|
|
618
|
+
name: str
|
|
619
|
+
"""Provider name within the workspace."""
|
|
620
|
+
|
|
621
|
+
host_url: str
|
|
622
|
+
"""Base URL of the backend inference service (e.g. ``"http://nim-svc:8080"``)."""
|
|
623
|
+
|
|
624
|
+
|
|
625
|
+
# ---------------------------------------------------------------------------
|
|
626
|
+
# Cache accessor Protocol
|
|
627
|
+
# ---------------------------------------------------------------------------
|
|
628
|
+
|
|
629
|
+
|
|
630
|
+
class InferenceMiddlewareCacheAccessor(Protocol):
|
|
631
|
+
"""Interface IGW must satisfy to inject read-only platform cache access into plugins.
|
|
632
|
+
|
|
633
|
+
IGW constructs a concrete implementation and passes it to each plugin
|
|
634
|
+
via :meth:`NemoInferenceMiddleware._inject_cache` before calling
|
|
635
|
+
``on_startup()``. Plugin authors reference this type in tests to build
|
|
636
|
+
typed mocks::
|
|
637
|
+
|
|
638
|
+
cache = MagicMock(spec=InferenceMiddlewareCacheAccessor)
|
|
639
|
+
cache.get_model_providers_for_model.return_value = [...]
|
|
640
|
+
plugin._inject_cache(cache)
|
|
641
|
+
"""
|
|
642
|
+
|
|
643
|
+
def get_model_providers_for_model(self, model_entity_id: str) -> list[ModelProvider]: ...
|
|
644
|
+
|
|
645
|
+
def get_model_entity(self, model_entity_id: str) -> ModelEntity | None: ...
|
|
646
|
+
|
|
647
|
+
def list_model_entities_for_workspace(self, workspace: str | None = None) -> list[str]: ...
|
|
648
|
+
|
|
649
|
+
def get_virtual_model(self, virtual_model_id: str) -> VirtualModel | None: ...
|
|
650
|
+
|
|
651
|
+
def list_virtual_models_for_workspace(self, workspace: str) -> list[str]: ...
|
|
652
|
+
|
|
653
|
+
def get_inference_url_and_model(
|
|
654
|
+
self,
|
|
655
|
+
model_entity_id: str,
|
|
656
|
+
append_v1_suffix: bool = True,
|
|
657
|
+
) -> ModelProviderInferenceTarget: ...
|
|
658
|
+
|
|
659
|
+
def get_backend_format(self, virtual_model_id: str, model_entity_id: str) -> BackendFormat | None: ...
|
|
660
|
+
|
|
661
|
+
def get_openai_compatible_inference_url_and_model(
|
|
662
|
+
self, virtual_model_id: str
|
|
663
|
+
) -> OpenAICompatibleInferenceTarget: ...
|
|
664
|
+
|
|
665
|
+
|
|
666
|
+
# ---------------------------------------------------------------------------
|
|
667
|
+
# Exceptions
|
|
668
|
+
# ---------------------------------------------------------------------------
|
|
669
|
+
|
|
670
|
+
|
|
671
|
+
class InferenceMiddlewareError(Exception):
|
|
672
|
+
"""Typed exception for handled error conditions in inference middleware.
|
|
673
|
+
|
|
674
|
+
Raise from :meth:`~NemoInferenceMiddleware.process_request` or
|
|
675
|
+
:meth:`~NemoInferenceMiddleware.process_response` to signal an error
|
|
676
|
+
with a specific HTTP status code. IGW catches this and maps
|
|
677
|
+
``status_code`` and ``detail`` to an OpenAI-compatible HTTP error
|
|
678
|
+
response. Unhandled exceptions (generic ``Exception``) map to 500.
|
|
679
|
+
|
|
680
|
+
Example::
|
|
681
|
+
|
|
682
|
+
async def process_request(self, body, headers, config) -> RequestResult:
|
|
683
|
+
raise InferenceMiddlewareError("quota exceeded", status_code=429)
|
|
684
|
+
"""
|
|
685
|
+
|
|
686
|
+
def __init__(self, detail: str, *, status_code: int = 500) -> None:
|
|
687
|
+
super().__init__(detail)
|
|
688
|
+
self.detail = detail
|
|
689
|
+
self.status_code = status_code
|
|
690
|
+
|
|
691
|
+
|
|
692
|
+
class InferenceMiddlewareUnavailableError(InferenceMiddlewareError):
|
|
693
|
+
"""The plugin's upstream service is temporarily unavailable.
|
|
694
|
+
|
|
695
|
+
Use when the plugin depends on an external service (e.g. a guardrails
|
|
696
|
+
service, a routing classifier endpoint) that cannot be reached.
|
|
697
|
+
Defaults to HTTP 503.
|
|
698
|
+
"""
|
|
699
|
+
|
|
700
|
+
def __init__(
|
|
701
|
+
self,
|
|
702
|
+
detail: str = "Middleware service unavailable",
|
|
703
|
+
*,
|
|
704
|
+
status_code: int = 503,
|
|
705
|
+
) -> None:
|
|
706
|
+
super().__init__(detail, status_code=status_code)
|
|
707
|
+
|
|
708
|
+
|
|
709
|
+
class MiddlewareConfigNotFoundError(InferenceMiddlewareError):
|
|
710
|
+
"""The referenced middleware config entity does not exist.
|
|
711
|
+
|
|
712
|
+
Plugins MUST raise this from :meth:`NemoInferenceMiddleware.get_middleware_config`
|
|
713
|
+
when the underlying entity store returns a definitive 404 — either because the
|
|
714
|
+
user deleted the config out from under a referencing VirtualModel, or because
|
|
715
|
+
they referenced a ``config_id`` that was never created.
|
|
716
|
+
|
|
717
|
+
IGW uses this exception as the explicit signal to evict any previously-resolved
|
|
718
|
+
middleware for VirtualModels that reference this config and to mark those
|
|
719
|
+
VirtualModels as broken until the situation is resolved (either the config is
|
|
720
|
+
recreated, or the VirtualModel is updated to drop the dangling reference).
|
|
721
|
+
|
|
722
|
+
Distinguish this from:
|
|
723
|
+
|
|
724
|
+
- :class:`ValueError` — the config exists but is malformed (e.g. missing
|
|
725
|
+
required fields). IGW also evicts on this, treating it as caller-shape input.
|
|
726
|
+
- Any other exception — treated as transient (network blip, plugin's upstream
|
|
727
|
+
service unhealthy). IGW preserves the previously-resolved config so a brief
|
|
728
|
+
outage cannot flap the cache.
|
|
729
|
+
|
|
730
|
+
Status code defaults to 404 so that the VirtualModel CRUD endpoints surface
|
|
731
|
+
a clean "config not found" error when a user submits a ``config_id`` that does
|
|
732
|
+
not resolve at create / update time.
|
|
733
|
+
"""
|
|
734
|
+
|
|
735
|
+
def __init__(self, config_id: str, *, detail: str | None = None) -> None:
|
|
736
|
+
super().__init__(
|
|
737
|
+
detail or f"Middleware config {config_id!r} not found",
|
|
738
|
+
status_code=404,
|
|
739
|
+
)
|
|
740
|
+
self.config_id = config_id
|
|
741
|
+
|
|
742
|
+
|
|
743
|
+
# ---------------------------------------------------------------------------
|
|
744
|
+
# NemoInferenceMiddleware ABC
|
|
745
|
+
# ---------------------------------------------------------------------------
|
|
746
|
+
|
|
747
|
+
|
|
748
|
+
class NemoInferenceMiddleware(ABC):
|
|
749
|
+
"""Plugin interface for in-process inference middleware in IGW.
|
|
750
|
+
|
|
751
|
+
Register via the ``nemo.inference_middleware`` entry-point group in your
|
|
752
|
+
plugin's ``pyproject.toml``. The entry-point key is the plugin identity —
|
|
753
|
+
it is what ``MiddlewareCall.name`` references in VirtualModel configs::
|
|
754
|
+
|
|
755
|
+
[project.entry-points."nemo.inference_middleware"]
|
|
756
|
+
nemo-switchyard = "nemo_switchyard_plugin.middleware:SwitchyardMiddleware"
|
|
757
|
+
|
|
758
|
+
Both :meth:`process_request` and :meth:`process_response` are optional.
|
|
759
|
+
Implement whichever phases your plugin participates in — request-only,
|
|
760
|
+
response-only, or both. Unimplemented hooks pass through unchanged.
|
|
761
|
+
|
|
762
|
+
Implement :meth:`get_middleware_config` if your VirtualModel configurations
|
|
763
|
+
reference stored config entities via ``MiddlewareCall.config_id``. IGW calls
|
|
764
|
+
this at VirtualModel create/update time and on each polling cycle — never
|
|
765
|
+
per-request.
|
|
766
|
+
|
|
767
|
+
Cache accessor methods (:meth:`get_model_providers_for_model`,
|
|
768
|
+
:meth:`get_model_entity`, :meth:`list_model_entities_for_workspace`,
|
|
769
|
+
:meth:`get_virtual_model`, :meth:`list_virtual_models_for_workspace`,
|
|
770
|
+
:meth:`get_inference_url_and_model`, :meth:`get_backend_format`, and
|
|
771
|
+
:meth:`get_openai_compatible_inference_url_and_model`) are injected by IGW before
|
|
772
|
+
:meth:`on_startup` is called. Calling them before injection raises
|
|
773
|
+
``RuntimeError``.
|
|
774
|
+
"""
|
|
775
|
+
|
|
776
|
+
def __init__(self) -> None:
|
|
777
|
+
self._cache: InferenceMiddlewareCacheAccessor | None = None
|
|
778
|
+
|
|
779
|
+
# ------------------------------------------------------------------
|
|
780
|
+
# IGW-called injection point (not part of the plugin author API)
|
|
781
|
+
# ------------------------------------------------------------------
|
|
782
|
+
|
|
783
|
+
def _inject_cache(self, cache: InferenceMiddlewareCacheAccessor) -> None:
|
|
784
|
+
"""Called by IGW to inject read-only cache access before on_startup().
|
|
785
|
+
|
|
786
|
+
Plugin authors must not call this method directly.
|
|
787
|
+
"""
|
|
788
|
+
self._cache = cache
|
|
789
|
+
|
|
790
|
+
def _get_cache(self, method_name: str) -> InferenceMiddlewareCacheAccessor:
|
|
791
|
+
if self._cache is None:
|
|
792
|
+
raise RuntimeError(
|
|
793
|
+
f"{method_name}() is not available before IGW injects the cache. "
|
|
794
|
+
f"Call {method_name}() from on_startup() or later."
|
|
795
|
+
)
|
|
796
|
+
return self._cache
|
|
797
|
+
|
|
798
|
+
# ------------------------------------------------------------------
|
|
799
|
+
# Lifecycle hooks — override as needed; all default to no-ops
|
|
800
|
+
# ------------------------------------------------------------------
|
|
801
|
+
|
|
802
|
+
async def on_startup(self) -> None:
|
|
803
|
+
"""One-time initialization — load ML models, build HTTP clients, etc.
|
|
804
|
+
|
|
805
|
+
Called once by IGW before the service starts handling requests.
|
|
806
|
+
Cache accessor methods are available at this point.
|
|
807
|
+
Default: no-op.
|
|
808
|
+
"""
|
|
809
|
+
|
|
810
|
+
async def on_shutdown(self) -> None:
|
|
811
|
+
"""Cleanup on graceful shutdown.
|
|
812
|
+
|
|
813
|
+
Called once by IGW after requests stop being served.
|
|
814
|
+
Default: no-op.
|
|
815
|
+
"""
|
|
816
|
+
|
|
817
|
+
async def on_virtual_model_upserted(self, virtual_model: VirtualModel) -> None:
|
|
818
|
+
"""Called when a VirtualModel referencing this plugin is created or updated.
|
|
819
|
+
|
|
820
|
+
Use to pre-warm per-VirtualModel resources (e.g. load a RouteLLM
|
|
821
|
+
classifier for this VirtualModel's strong/weak model pair, or
|
|
822
|
+
pre-fetch and cache a guardrails config).
|
|
823
|
+
Default: no-op.
|
|
824
|
+
"""
|
|
825
|
+
|
|
826
|
+
async def on_virtual_model_destroyed(self, virtual_model: VirtualModel) -> None:
|
|
827
|
+
"""Called when a VirtualModel referencing this plugin is removed.
|
|
828
|
+
|
|
829
|
+
Use to release resources that were warmed for that VirtualModel.
|
|
830
|
+
Default: no-op.
|
|
831
|
+
"""
|
|
832
|
+
|
|
833
|
+
# ------------------------------------------------------------------
|
|
834
|
+
# IGW-injected cache accessors — available from on_startup() onward
|
|
835
|
+
# ------------------------------------------------------------------
|
|
836
|
+
|
|
837
|
+
def get_model_providers_for_model(self, model_entity_id: str) -> list[ModelProvider]:
|
|
838
|
+
"""Return all ModelProviders currently serving ``model_entity_id``.
|
|
839
|
+
|
|
840
|
+
``model_entity_id`` format: ``"workspace/name"``. Returns an empty
|
|
841
|
+
list if the model entity is not in the cache.
|
|
842
|
+
|
|
843
|
+
Primary use: latency-aware or availability-aware routing — inspect
|
|
844
|
+
each provider's ``host_url`` to measure round-trip times and select
|
|
845
|
+
the best backend, or detect that a backend is unavailable and failover.
|
|
846
|
+
|
|
847
|
+
Raises:
|
|
848
|
+
RuntimeError: If called before IGW has injected the cache.
|
|
849
|
+
"""
|
|
850
|
+
return self._get_cache("get_model_providers_for_model").get_model_providers_for_model(model_entity_id)
|
|
851
|
+
|
|
852
|
+
def get_model_entity(self, model_entity_id: str) -> ModelEntity | None:
|
|
853
|
+
"""Return the ModelEntity for ``model_entity_id``, or ``None`` if not found.
|
|
854
|
+
|
|
855
|
+
``model_entity_id`` format: ``"workspace/name"``.
|
|
856
|
+
|
|
857
|
+
Primary use: inspecting model capabilities at startup or request time —
|
|
858
|
+
e.g. checking ``entity.spec.is_chat`` to verify the model type is
|
|
859
|
+
appropriate for the plugin's operation, or reading ``finetuning_type``
|
|
860
|
+
to apply fine-tune-specific routing logic.
|
|
861
|
+
|
|
862
|
+
Raises:
|
|
863
|
+
RuntimeError: If called before IGW has injected the cache.
|
|
864
|
+
"""
|
|
865
|
+
return self._get_cache("get_model_entity").get_model_entity(model_entity_id)
|
|
866
|
+
|
|
867
|
+
def list_model_entities_for_workspace(self, workspace: str | None = None) -> list[str]:
|
|
868
|
+
"""Return model entity IDs (``"workspace/name"``) known to IGW.
|
|
869
|
+
|
|
870
|
+
Pass ``workspace`` to filter to a single workspace; omit for all workspaces.
|
|
871
|
+
|
|
872
|
+
Primary use: startup validation — confirm that model entities referenced
|
|
873
|
+
in plugin config (e.g. ``strong_model``, ``weak_model``) actually exist
|
|
874
|
+
before the first request arrives.
|
|
875
|
+
|
|
876
|
+
Raises:
|
|
877
|
+
RuntimeError: If called before IGW has injected the cache.
|
|
878
|
+
"""
|
|
879
|
+
return self._get_cache("list_model_entities_for_workspace").list_model_entities_for_workspace(workspace)
|
|
880
|
+
|
|
881
|
+
def get_virtual_model(self, virtual_model_id: str) -> VirtualModel | None:
|
|
882
|
+
"""Return the VirtualModel for ``virtual_model_id``, or ``None`` if not found.
|
|
883
|
+
|
|
884
|
+
``virtual_model_id`` format: ``"workspace/name"``.
|
|
885
|
+
|
|
886
|
+
Primary use: a meta-routing plugin that routes between VirtualModels
|
|
887
|
+
reads the target VirtualModel's ``default_model_entity`` and middleware
|
|
888
|
+
chain before writing into ``body["model"]``.
|
|
889
|
+
|
|
890
|
+
Raises:
|
|
891
|
+
RuntimeError: If called before IGW has injected the cache.
|
|
892
|
+
"""
|
|
893
|
+
return self._get_cache("get_virtual_model").get_virtual_model(virtual_model_id)
|
|
894
|
+
|
|
895
|
+
def list_virtual_models_for_workspace(self, workspace: str) -> list[str]:
|
|
896
|
+
"""Return VirtualModel IDs (``"workspace/name"``) in ``workspace``.
|
|
897
|
+
|
|
898
|
+
Primary use: a meta-routing plugin that discovers all VirtualModels
|
|
899
|
+
in a workspace to build a routing table at startup.
|
|
900
|
+
|
|
901
|
+
Raises:
|
|
902
|
+
RuntimeError: If called before IGW has injected the cache.
|
|
903
|
+
"""
|
|
904
|
+
return self._get_cache("list_virtual_models_for_workspace").list_virtual_models_for_workspace(workspace)
|
|
905
|
+
|
|
906
|
+
def get_inference_url_and_model(
|
|
907
|
+
self,
|
|
908
|
+
model_entity_id: str,
|
|
909
|
+
append_v1_suffix: bool = True,
|
|
910
|
+
) -> ModelProviderInferenceTarget:
|
|
911
|
+
"""Return the IGW provider gateway URL and served model name for ``model_entity_id``.
|
|
912
|
+
|
|
913
|
+
Both values are resolved from the same provider (the first provider in
|
|
914
|
+
IGW's model cache for this entity, consistent with how IGW itself selects
|
|
915
|
+
a provider at proxy time), ensuring they are mutually consistent.
|
|
916
|
+
|
|
917
|
+
Use ``result.model_provider_gateway_url`` as the base URL and
|
|
918
|
+
``result.served_model_name`` as the value for ``body["model"]``. Use
|
|
919
|
+
:meth:`get_backend_format` separately when translating request or
|
|
920
|
+
response bodies for a VirtualModel route.
|
|
921
|
+
|
|
922
|
+
The provider gateway route bypasses virtual model routing and the middleware
|
|
923
|
+
chain entirely — calling it from within a middleware plugin does not
|
|
924
|
+
cause recursion::
|
|
925
|
+
|
|
926
|
+
target = self.get_inference_url_and_model("ws/llama-70b")
|
|
927
|
+
response = await httpx.post(
|
|
928
|
+
f"{target.model_provider_gateway_url}/chat/completions",
|
|
929
|
+
json={**body, "model": target.served_model_name},
|
|
930
|
+
)
|
|
931
|
+
|
|
932
|
+
For plugins that perform latency-aware routing across multiple providers,
|
|
933
|
+
use :meth:`get_model_providers_for_model` to inspect all providers and
|
|
934
|
+
construct per-provider URLs via the platform SDK instead.
|
|
935
|
+
|
|
936
|
+
Args:
|
|
937
|
+
model_entity_id: ``"workspace/name"`` of the model entity.
|
|
938
|
+
append_v1_suffix: Append ``/v1`` to the provider gateway URL.
|
|
939
|
+
Set ``False`` if the URL will be used with a path that includes
|
|
940
|
+
its own version prefix, or if the provider URL already ends with
|
|
941
|
+
``/v1``. Defaults to ``True``.
|
|
942
|
+
|
|
943
|
+
Raises:
|
|
944
|
+
RuntimeError: If called before IGW has injected the cache.
|
|
945
|
+
KeyError: If ``model_entity_id`` is not in the cache.
|
|
946
|
+
"""
|
|
947
|
+
return self._get_cache("get_inference_url_and_model").get_inference_url_and_model(
|
|
948
|
+
model_entity_id, append_v1_suffix
|
|
949
|
+
)
|
|
950
|
+
|
|
951
|
+
def get_backend_format(self, virtual_model_id: str, model_entity_id: str) -> BackendFormat | None:
|
|
952
|
+
"""Return the backend API format for ``model_entity_id`` within a VirtualModel route.
|
|
953
|
+
|
|
954
|
+
Resolves a matching VirtualModel ``models`` entry override first, then
|
|
955
|
+
falls back to the ModelEntity ``backend_format`` value. Returns ``None``
|
|
956
|
+
when neither is set, leaving fallback behavior to the caller. Use this
|
|
957
|
+
when a middleware plugin needs to translate request or response bodies
|
|
958
|
+
for a backend selected from a VirtualModel.
|
|
959
|
+
|
|
960
|
+
Args:
|
|
961
|
+
virtual_model_id: ``"workspace/name"`` of the VirtualModel route.
|
|
962
|
+
model_entity_id: ``"workspace/name"`` of the selected ModelEntity.
|
|
963
|
+
|
|
964
|
+
Raises:
|
|
965
|
+
RuntimeError: If called before IGW has injected the cache.
|
|
966
|
+
KeyError: If either ID is invalid or not in the cache.
|
|
967
|
+
"""
|
|
968
|
+
return self._get_cache("get_backend_format").get_backend_format(virtual_model_id, model_entity_id)
|
|
969
|
+
|
|
970
|
+
def get_openai_compatible_inference_url_and_model(self, virtual_model_id: str) -> OpenAICompatibleInferenceTarget:
|
|
971
|
+
"""Return the OpenAI-compatible IGW URL and model for ``virtual_model_id``.
|
|
972
|
+
|
|
973
|
+
Unlike :meth:`get_inference_url_and_model`, this helper does not resolve
|
|
974
|
+
to a backend provider or served model name. It preserves IGW VirtualModel
|
|
975
|
+
routing by returning an OpenAI-compatible base URL and the original
|
|
976
|
+
workspace-qualified VirtualModel ID.
|
|
977
|
+
|
|
978
|
+
Raises:
|
|
979
|
+
RuntimeError: If called before IGW has injected the cache.
|
|
980
|
+
KeyError: If ``virtual_model_id`` is not in the cache.
|
|
981
|
+
"""
|
|
982
|
+
return self._get_cache(
|
|
983
|
+
"get_openai_compatible_inference_url_and_model"
|
|
984
|
+
).get_openai_compatible_inference_url_and_model(virtual_model_id)
|
|
985
|
+
|
|
986
|
+
# ------------------------------------------------------------------
|
|
987
|
+
# Plugin-implemented config methods — IGW calls these on the plugin
|
|
988
|
+
# ------------------------------------------------------------------
|
|
989
|
+
|
|
990
|
+
async def get_middleware_config(self, config_type: str, config_id: str) -> Any:
|
|
991
|
+
"""Fetch a stored config entity of ``config_type`` with id ``config_id``.
|
|
992
|
+
|
|
993
|
+
IGW calls this method at VirtualModel create/update time (to resolve
|
|
994
|
+
``MiddlewareCall.config_id`` references before caching) and on every
|
|
995
|
+
polling cycle (to pick up config entity changes — no stale configs).
|
|
996
|
+
It is never called at per-request time.
|
|
997
|
+
|
|
998
|
+
Plugin authors implement this method to fetch from wherever they store
|
|
999
|
+
configs — typically the entity store via ``NemoEntitiesClient``. Only
|
|
1000
|
+
needed if your plugin exposes its own ``NemoService`` CRUD API for config
|
|
1001
|
+
entities and users reference those entities via ``MiddlewareCall.config_id``.
|
|
1002
|
+
If all configs are inline (``MiddlewareCall.config``), this method need
|
|
1003
|
+
not be implemented.
|
|
1004
|
+
|
|
1005
|
+
``config_id`` format: ``"workspace/name"``.
|
|
1006
|
+
|
|
1007
|
+
Args:
|
|
1008
|
+
config_type: The ``MiddlewareCall.config_type`` value — the
|
|
1009
|
+
``entity_type`` of the plugin's config ``NemoEntity`` subclass
|
|
1010
|
+
(e.g. ``"routellm_config"``). Use this to dispatch to the right
|
|
1011
|
+
entity type when a plugin supports multiple config schemas.
|
|
1012
|
+
config_id: The ``"workspace/name"`` reference from
|
|
1013
|
+
:class:`~nemo_platform_plugin.inference_middleware.MiddlewareCall`.
|
|
1014
|
+
|
|
1015
|
+
Returns:
|
|
1016
|
+
The resolved config object, in whatever form the plugin chooses.
|
|
1017
|
+
This value is passed to :meth:`validate_middleware_config`, and
|
|
1018
|
+
then the validated result is passed to :meth:`process_request` /
|
|
1019
|
+
:meth:`process_response` as the ``config`` argument.
|
|
1020
|
+
|
|
1021
|
+
Raises:
|
|
1022
|
+
MiddlewareConfigNotFoundError: The referenced entity does not exist
|
|
1023
|
+
(deleted, or never created). IGW evicts any previously-resolved
|
|
1024
|
+
middleware for VirtualModels that reference this ``config_id``
|
|
1025
|
+
and marks them as broken until the config is recreated or the
|
|
1026
|
+
reference is removed. Plugins MUST raise this — not :class:`ValueError`
|
|
1027
|
+
— on a definitive 404 from their upstream store, otherwise IGW
|
|
1028
|
+
cannot distinguish deletion from a transient fetch failure and
|
|
1029
|
+
the previously-resolved config will persist indefinitely.
|
|
1030
|
+
ValueError: The entity exists but is malformed (missing required
|
|
1031
|
+
fields, invalid shape). IGW also evicts on this and treats it
|
|
1032
|
+
as caller-shape input.
|
|
1033
|
+
NotImplementedError: Default. IGW catches this and returns a 4xx
|
|
1034
|
+
to the caller informing them that ``config_id`` is not supported
|
|
1035
|
+
by this plugin. Override if your VirtualModel configurations use
|
|
1036
|
+
``config_id``.
|
|
1037
|
+
|
|
1038
|
+
Any other exception is treated as transient (network blip, plugin's
|
|
1039
|
+
upstream service unhealthy) — IGW preserves the previously-resolved
|
|
1040
|
+
config so a brief outage cannot flap the cache.
|
|
1041
|
+
"""
|
|
1042
|
+
raise NotImplementedError(
|
|
1043
|
+
f"{type(self).__name__} does not implement get_middleware_config(). "
|
|
1044
|
+
f"Override this method if your MiddlewareCall entries use config_id, "
|
|
1045
|
+
f"or use inline config (MiddlewareCall.config) instead."
|
|
1046
|
+
)
|
|
1047
|
+
|
|
1048
|
+
async def validate_middleware_config(self, config_type: str, config: Any) -> Any:
|
|
1049
|
+
"""Validate and coerce a config object for ``config_type``.
|
|
1050
|
+
|
|
1051
|
+
IGW calls this method at VirtualModel create/update time — both for
|
|
1052
|
+
inline ``config`` dicts and for objects returned by
|
|
1053
|
+
:meth:`get_middleware_config`. Use to enforce schema constraints and
|
|
1054
|
+
return a fully-typed config object.
|
|
1055
|
+
|
|
1056
|
+
The validated return value is cached by IGW and passed verbatim to
|
|
1057
|
+
:meth:`process_request` or :meth:`process_response` as the ``config``
|
|
1058
|
+
argument. Never called at per-request time.
|
|
1059
|
+
|
|
1060
|
+
Args:
|
|
1061
|
+
config_type: The ``MiddlewareCall.config_type`` value. Use this
|
|
1062
|
+
to dispatch to the right validation schema when a plugin
|
|
1063
|
+
supports multiple config types (e.g. ``"routellm_config"``
|
|
1064
|
+
vs. ``"streaming_data_log_config"`` for Switchyard).
|
|
1065
|
+
config: The raw config object — either an inline ``dict`` from
|
|
1066
|
+
``MiddlewareCall.config``, or the object returned by
|
|
1067
|
+
:meth:`get_middleware_config`.
|
|
1068
|
+
|
|
1069
|
+
Returns:
|
|
1070
|
+
The validated config (may be the original dict, a Pydantic model
|
|
1071
|
+
instance, or any typed object the plugin chooses).
|
|
1072
|
+
|
|
1073
|
+
Raises:
|
|
1074
|
+
ValueError: If the config is invalid for this plugin and
|
|
1075
|
+
``config_type``. IGW will reject the VirtualModel
|
|
1076
|
+
create/update request.
|
|
1077
|
+
|
|
1078
|
+
Default: return ``config`` unchanged (pass-through). Override to
|
|
1079
|
+
add schema validation.
|
|
1080
|
+
"""
|
|
1081
|
+
return config
|
|
1082
|
+
|
|
1083
|
+
# ------------------------------------------------------------------
|
|
1084
|
+
# Request / response hooks — override as needed; both default to pass-through
|
|
1085
|
+
# ------------------------------------------------------------------
|
|
1086
|
+
|
|
1087
|
+
async def process_request(
|
|
1088
|
+
self,
|
|
1089
|
+
ctx: InferenceMiddlewareContext,
|
|
1090
|
+
request: InferenceRequest,
|
|
1091
|
+
middleware_config: Any,
|
|
1092
|
+
) -> InferenceRequest | ImmediateResponse:
|
|
1093
|
+
"""Process the inference request before it is proxied to the ModelProvider.
|
|
1094
|
+
|
|
1095
|
+
Receive ``request`` (body + headers + path), optionally modify it, and return
|
|
1096
|
+
the updated :class:`InferenceRequest`. Mutate ``request.body``,
|
|
1097
|
+
``request.headers``, and/or ``request.path`` in-place and return ``request``,
|
|
1098
|
+
or construct and return a new :class:`InferenceRequest`.
|
|
1099
|
+
|
|
1100
|
+
Use ``ctx.state("my-plugin").set(key, value)`` to store data that
|
|
1101
|
+
``process_response`` will need. ``ctx.original_request`` provides a
|
|
1102
|
+
read-only snapshot of the request as it entered this plugin chain.
|
|
1103
|
+
|
|
1104
|
+
Args:
|
|
1105
|
+
ctx: Per-request context — routing metadata, original request snapshot,
|
|
1106
|
+
and plugin scratch space. ``ctx.proxied_request`` is ``None`` here
|
|
1107
|
+
(it is set by IGW after the request chain finishes).
|
|
1108
|
+
request: The current :class:`InferenceRequest`. When called,
|
|
1109
|
+
``request.body["model"]`` contains the model entity name written by
|
|
1110
|
+
IGW from ``VirtualModel.default_model_entity`` (if set). Middleware
|
|
1111
|
+
may rewrite ``request.body["model"]`` to any valid model entity name
|
|
1112
|
+
and IGW will resolve and proxy it. Middleware may also rewrite
|
|
1113
|
+
``request.path`` to change the backend URI.
|
|
1114
|
+
middleware_config: The validated, cached config — the value returned
|
|
1115
|
+
by :meth:`validate_middleware_config` at VirtualModel cache-build
|
|
1116
|
+
time. Never resolved per-request.
|
|
1117
|
+
|
|
1118
|
+
Returns:
|
|
1119
|
+
- :class:`InferenceRequest`: The modified request. IGW resolves
|
|
1120
|
+
``request.body["model"]`` to a ``ModelProvider`` and proxies.
|
|
1121
|
+
- :class:`ImmediateResponse`: Plugin handled the request itself. IGW
|
|
1122
|
+
skips the proxy and passes ``data`` (a :data:`ResponseResult`) to
|
|
1123
|
+
the response middleware chain.
|
|
1124
|
+
|
|
1125
|
+
Raises:
|
|
1126
|
+
InferenceMiddlewareUnavailableError: A service the plugin depends on
|
|
1127
|
+
is unavailable. IGW returns 503 by default.
|
|
1128
|
+
InferenceMiddlewareError: Any other handled error with a custom
|
|
1129
|
+
``status_code``.
|
|
1130
|
+
|
|
1131
|
+
Default: return ``request`` unchanged — IGW proxies the request as-is.
|
|
1132
|
+
"""
|
|
1133
|
+
return request
|
|
1134
|
+
|
|
1135
|
+
async def process_response(
|
|
1136
|
+
self,
|
|
1137
|
+
ctx: InferenceMiddlewareContext,
|
|
1138
|
+
response: InferenceResponse,
|
|
1139
|
+
middleware_config: Any,
|
|
1140
|
+
) -> InferenceResponse:
|
|
1141
|
+
"""Process the inference response after it is received from the ModelProvider.
|
|
1142
|
+
|
|
1143
|
+
Receive ``response`` (result + headers, and possibly ``typed_result``),
|
|
1144
|
+
optionally modify it, and return the updated :class:`InferenceResponse`.
|
|
1145
|
+
|
|
1146
|
+
``ctx.original_request`` provides the read-only client request (available
|
|
1147
|
+
from the request phase). ``ctx.proxied_request`` provides the request that
|
|
1148
|
+
was forwarded to the backend (``None`` when an :class:`ImmediateResponse`
|
|
1149
|
+
short-circuited the proxy). Use ``ctx.state("my-plugin").get(key)`` to
|
|
1150
|
+
retrieve data stored during ``process_request``.
|
|
1151
|
+
|
|
1152
|
+
Canonical response contract: for non-streaming responses, when
|
|
1153
|
+
``response.typed_body`` is not ``None``, mutate or replace
|
|
1154
|
+
``response.typed_body`` and leave ``response.result`` as the raw
|
|
1155
|
+
fallback. For streaming responses, ``response.typed_body`` is a
|
|
1156
|
+
middleware-only typed view and IGW serializes ``response.result``. When
|
|
1157
|
+
``response.typed_body`` is ``None``, mutate ``response.result``. IGW
|
|
1158
|
+
does not synchronize the two views between plugins. If you need to return
|
|
1159
|
+
a non-streaming shape that does not fit the typed SDK schema, set
|
|
1160
|
+
``response.typed_body = None`` and mutate ``response.result``.
|
|
1161
|
+
|
|
1162
|
+
Args:
|
|
1163
|
+
ctx: Per-request context. ``ctx.original_request`` is the client
|
|
1164
|
+
request (before any plugin ran). ``ctx.proxied_request`` is what
|
|
1165
|
+
IGW forwarded to the backend (``None`` for :class:`ImmediateResponse`
|
|
1166
|
+
paths).
|
|
1167
|
+
response: The current :class:`InferenceResponse`. ``response.result``
|
|
1168
|
+
is either a ``dict[str, Any]`` (non-streaming) or an
|
|
1169
|
+
``AsyncIterator[dict[str, Any]]`` (streaming). For non-streaming
|
|
1170
|
+
responses, a non-``None`` ``response.typed_body`` is the canonical
|
|
1171
|
+
parsed SDK-native response object. For streaming responses,
|
|
1172
|
+
``response.typed_body`` is a middleware-only parsed view and
|
|
1173
|
+
``response.result`` is the outbound client stream. Modify
|
|
1174
|
+
``response.headers`` to add or change headers returned to the caller.
|
|
1175
|
+
middleware_config: The validated, cached config (same semantics as in
|
|
1176
|
+
:meth:`process_request`).
|
|
1177
|
+
|
|
1178
|
+
Returns:
|
|
1179
|
+
An :class:`InferenceResponse`, possibly with a modified ``result`` or
|
|
1180
|
+
``headers``. Passed to the next plugin in the response middleware chain,
|
|
1181
|
+
or returned to the caller if this is the last plugin.
|
|
1182
|
+
|
|
1183
|
+
Raises:
|
|
1184
|
+
InferenceMiddlewareUnavailableError: A service the plugin depends on
|
|
1185
|
+
is unavailable. IGW returns 503 by default.
|
|
1186
|
+
InferenceMiddlewareError: Any other handled error with a custom
|
|
1187
|
+
``status_code``.
|
|
1188
|
+
|
|
1189
|
+
Default: pass-through (return ``response`` unchanged).
|
|
1190
|
+
"""
|
|
1191
|
+
return response
|