Files
wehub-resource-sync 2114ccd278
CI / Lint & Test (Python 3.13) (push) Failing after 2s
CI / Lint & Test (Python 3.14) (push) Failing after 1s
CI / Lint & Test (Python 3.12) (push) Failing after 2s
CI / DCO Check (push) Has been skipped
Scorecard supply-chain security / Scorecard analysis (push) Failing after 2s
chore: import upstream snapshot with attribution
2026-07-13 12:23:39 +08:00

107 lines
3.9 KiB
Python

# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Shared constants for skillspector (env-driven where applicable)."""
import logging
import os
from skillspector.providers import get_metadata_provider
logger = logging.getLogger(__name__)
# % of model's max tokens used for input. 1-MAX_INPUT_TOKENS_PCT is used for output.
MAX_INPUT_TOKENS_PCT = 0.75
# Fallback context length when no metadata API or registry entry is available.
DEFAULT_CONTEXT_LENGTH = 128_000
# Risk score threshold above which a scan is treated as unsafe.
RISK_THRESHOLD = 50
# Default-model selection lives on each provider (see providers/<name>/provider.py
# for ``DEFAULT_MODEL`` and ``SLOT_DEFAULTS``). The active provider's
# ``resolve_model`` runs the waterfall: ``SKILLSPECTOR_MODEL`` env > slot
# default > general default. OSS users pointing at build.nvidia.com or
# stock OpenAI inherit ``NvBuildProvider``'s default model automatically.
_provider = get_metadata_provider()
# Exposed for analyzers that need a final fallback symbol (e.g.,
# ``model = state.model or MODEL_CONFIG[ANALYZER_ID] or _SKILLSPECTOR_DEFAULT_MODEL``).
_SKILLSPECTOR_DEFAULT_MODEL = _provider.DEFAULT_MODEL
_MODEL_SLOTS: tuple[str, ...] = (
"default",
"mcp_least_privilege",
"mcp_rug_pull",
"mcp_tool_poisoning",
"semantic_developer_intent",
"semantic_quality_policy",
"semantic_security_discovery",
"meta_analyzer",
)
def _resolve_slot_model(slot: str) -> str:
"""Resolve the model for *slot* with per-slot env var override support.
Precedence: ``SKILLSPECTOR_MODEL_{SLOT}`` env var > provider
``resolve_model(slot)`` (which itself runs ``SKILLSPECTOR_MODEL`` env >
provider slot default > provider ``DEFAULT_MODEL``).
"""
env_key = f"SKILLSPECTOR_MODEL_{slot.upper()}"
env_val = os.environ.get(env_key, "").strip()
if env_val:
return env_val
return _provider.resolve_model(slot)
MODEL_CONFIG: dict[str, str] = {slot: _resolve_slot_model(slot) for slot in _MODEL_SLOTS}
def _validate_model_config() -> None:
"""Warn about models not found in the provider's model registry.
When ``SKILLSPECTOR_STRICT_MODEL_VALIDATION=true``, raises
``ValueError`` instead of logging warnings.
"""
unknown: list[str] = []
for slot, model in MODEL_CONFIG.items():
ctx = _provider.get_context_length(model) # type: ignore[attr-defined]
if ctx is None:
unknown.append(f" {slot}: {model}")
logger.warning(
"Model '%s' (slot: %s) not found in model_registry.yaml. "
"Using fallback context length (%d). Token budgeting may be "
"inaccurate — add the model to the registry or verify the "
"model ID.",
model,
slot,
DEFAULT_CONTEXT_LENGTH,
)
strict = os.environ.get("SKILLSPECTOR_STRICT_MODEL_VALIDATION", "").lower() == "true"
if strict and unknown:
raise ValueError(
"Strict model validation enabled. Unknown models:\n"
+ "\n".join(unknown)
+ "\nAdd them to model_registry.yaml or disable "
"SKILLSPECTOR_STRICT_MODEL_VALIDATION."
)
_validate_model_config()
# Log level: from env or fallback (DEBUG, INFO, WARNING, ERROR).
SKILLSPECTOR_LOG_LEVEL = os.environ.get("SKILLSPECTOR_LOG_LEVEL", "WARNING")