auditkit 1.0.0__tar.gz
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.
- auditkit-1.0.0/.github/workflows/patch-release.yml +376 -0
- auditkit-1.0.0/.gitignore +17 -0
- auditkit-1.0.0/AGENTS.md +94 -0
- auditkit-1.0.0/CITATION.cff +36 -0
- auditkit-1.0.0/LICENSE.md +92 -0
- auditkit-1.0.0/PKG-INFO +396 -0
- auditkit-1.0.0/README.md +232 -0
- auditkit-1.0.0/docs/BUGS.md +356 -0
- auditkit-1.0.0/docs/CNAME +1 -0
- auditkit-1.0.0/docs/COMPARISON.docx +0 -0
- auditkit-1.0.0/docs/GUIDE.md +1014 -0
- auditkit-1.0.0/docs/RELEASE.md +684 -0
- auditkit-1.0.0/docs/VLLM_KNOWN_ISSUES.md +312 -0
- auditkit-1.0.0/docs/about/glossary.md +20 -0
- auditkit-1.0.0/docs/about/platform-integration.md +378 -0
- auditkit-1.0.0/docs/annotators.md +305 -0
- auditkit-1.0.0/docs/api.md +39 -0
- auditkit-1.0.0/docs/architecture/data-model.md +430 -0
- auditkit-1.0.0/docs/architecture/system-design.md +345 -0
- auditkit-1.0.0/docs/assets/auditkit-logo-dark.png +0 -0
- auditkit-1.0.0/docs/assets/auditkit-logo-light.png +0 -0
- auditkit-1.0.0/docs/assets/extra.css +336 -0
- auditkit-1.0.0/docs/assets/extra.js +14 -0
- auditkit-1.0.0/docs/assets/favicon.png +0 -0
- auditkit-1.0.0/docs/assets/icon.png +0 -0
- auditkit-1.0.0/docs/assets/icon.svg +23 -0
- auditkit-1.0.0/docs/assets/logo.svg +27 -0
- auditkit-1.0.0/docs/best_practices/scorers.md +161 -0
- auditkit-1.0.0/docs/cli.md +138 -0
- auditkit-1.0.0/docs/community/changelog.md +373 -0
- auditkit-1.0.0/docs/community/contributing.md +62 -0
- auditkit-1.0.0/docs/community/faq.md +78 -0
- auditkit-1.0.0/docs/community/roadmap.md +46 -0
- auditkit-1.0.0/docs/configuration.md +55 -0
- auditkit-1.0.0/docs/cookbook/llm_judge.md +137 -0
- auditkit-1.0.0/docs/cookbook/rag_evaluation.md +177 -0
- auditkit-1.0.0/docs/development.md +55 -0
- auditkit-1.0.0/docs/encoder_judge.md +434 -0
- auditkit-1.0.0/docs/encoder_judge_prebuilts.md +161 -0
- auditkit-1.0.0/docs/examples/custom_scorer.md +121 -0
- auditkit-1.0.0/docs/examples/experiments.md +28 -0
- auditkit-1.0.0/docs/examples/many_datasets.md +165 -0
- auditkit-1.0.0/docs/examples/model_comparison.md +185 -0
- auditkit-1.0.0/docs/examples/quickstart.md +17 -0
- auditkit-1.0.0/docs/experiments.md +70 -0
- auditkit-1.0.0/docs/getting_started.md +68 -0
- auditkit-1.0.0/docs/guard_models.md +495 -0
- auditkit-1.0.0/docs/index.md +119 -0
- auditkit-1.0.0/docs/integrations.md +145 -0
- auditkit-1.0.0/docs/known_issues.md +111 -0
- auditkit-1.0.0/docs/llm_judge_rendering.md +185 -0
- auditkit-1.0.0/docs/metrics.md +128 -0
- auditkit-1.0.0/docs/model_backends.md +67 -0
- auditkit-1.0.0/docs/reports.md +39 -0
- auditkit-1.0.0/docs/requirements.txt +7 -0
- auditkit-1.0.0/docs/scenarios.md +48 -0
- auditkit-1.0.0/docs/scorers_reference.md +171 -0
- auditkit-1.0.0/examples/01_full_evaluation_pipeline.ipynb +639 -0
- auditkit-1.0.0/examples/02_generation_across_hf_families.ipynb +379 -0
- auditkit-1.0.0/examples/03_custom_annotators.ipynb +421 -0
- auditkit-1.0.0/examples/04_metrics_deep_dive.ipynb +510 -0
- auditkit-1.0.0/examples/05_data_types.ipynb +387 -0
- auditkit-1.0.0/examples/06_model_comparison.ipynb +362 -0
- auditkit-1.0.0/examples/07_annotators_across_models.ipynb +496 -0
- auditkit-1.0.0/examples/08_compare_result_deep_dive.ipynb +330 -0
- auditkit-1.0.0/examples/09_guard_judge_implementation_check.ipynb +526 -0
- auditkit-1.0.0/examples/10_guard_judge_legit_models.ipynb +445 -0
- auditkit-1.0.0/examples/11_encoder_judge_prebuilts.ipynb +441 -0
- auditkit-1.0.0/examples/12_performance_metrics_demo.ipynb +16470 -0
- auditkit-1.0.0/examples/README.md +80 -0
- auditkit-1.0.0/examples/applications/01_application_pruned_llama_boolq.ipynb +17660 -0
- auditkit-1.0.0/examples/applications/02_application_healthcare_pubmedqa.ipynb +285 -0
- auditkit-1.0.0/examples/applications/03_application_finance_10k_qa.ipynb +16180 -0
- auditkit-1.0.0/examples/applications/04_application_ecommerce_review_triage.ipynb +260 -0
- auditkit-1.0.0/examples/applications/05_application_education_arc_tutor.ipynb +281 -0
- auditkit-1.0.0/examples/applications/06_application_enterprise_search_rag.ipynb +294 -0
- auditkit-1.0.0/examples/applications/07_application_bert_nli_judge.ipynb +343 -0
- auditkit-1.0.0/examples/applications/README.md +53 -0
- auditkit-1.0.0/examples/applications/SUMMARY.md +96 -0
- auditkit-1.0.0/examples/auditkit.yaml +54 -0
- auditkit-1.0.0/examples/model_comparison_notebook.py +189 -0
- auditkit-1.0.0/examples/stress_tests/README.md +106 -0
- auditkit-1.0.0/examples/stress_tests/test_stress_gated_model.py +124 -0
- auditkit-1.0.0/examples/stress_tests/test_stress_open_model_load.py +153 -0
- auditkit-1.0.0/mkdocs.yml +166 -0
- auditkit-1.0.0/pyproject.toml +66 -0
- auditkit-1.0.0/scripts/__init__.py +1 -0
- auditkit-1.0.0/scripts/release.py +358 -0
- auditkit-1.0.0/src/auditkit/README.md +99 -0
- auditkit-1.0.0/src/auditkit/__init__.py +177 -0
- auditkit-1.0.0/src/auditkit/__main__.py +3 -0
- auditkit-1.0.0/src/auditkit/_bootstrap.py +77 -0
- auditkit-1.0.0/src/auditkit/_identity_guard.py +99 -0
- auditkit-1.0.0/src/auditkit/adapter.py +264 -0
- auditkit-1.0.0/src/auditkit/annotator.py +339 -0
- auditkit-1.0.0/src/auditkit/api.py +502 -0
- auditkit-1.0.0/src/auditkit/assets/auditkit_logo.png +0 -0
- auditkit-1.0.0/src/auditkit/cache.py +47 -0
- auditkit-1.0.0/src/auditkit/cli.py +417 -0
- auditkit-1.0.0/src/auditkit/comparison.py +563 -0
- auditkit-1.0.0/src/auditkit/diff.py +265 -0
- auditkit-1.0.0/src/auditkit/errors.py +54 -0
- auditkit-1.0.0/src/auditkit/evaluator.py +20 -0
- auditkit-1.0.0/src/auditkit/experiment.py +145 -0
- auditkit-1.0.0/src/auditkit/hf_publish.py +262 -0
- auditkit-1.0.0/src/auditkit/lmeval_engine.py +550 -0
- auditkit-1.0.0/src/auditkit/loaders.py +121 -0
- auditkit-1.0.0/src/auditkit/logs.py +18 -0
- auditkit-1.0.0/src/auditkit/metric.py +199 -0
- auditkit-1.0.0/src/auditkit/metrics/README.md +15 -0
- auditkit-1.0.0/src/auditkit/metrics/__init__.py +0 -0
- auditkit-1.0.0/src/auditkit/metrics/code.py +222 -0
- auditkit-1.0.0/src/auditkit/metrics/embedding.py +131 -0
- auditkit-1.0.0/src/auditkit/metrics/encoder_judge.py +423 -0
- auditkit-1.0.0/src/auditkit/metrics/generation.py +331 -0
- auditkit-1.0.0/src/auditkit/metrics/guard.py +412 -0
- auditkit-1.0.0/src/auditkit/metrics/hallucination.py +45 -0
- auditkit-1.0.0/src/auditkit/metrics/judge.py +547 -0
- auditkit-1.0.0/src/auditkit/metrics/pairwise.py +153 -0
- auditkit-1.0.0/src/auditkit/metrics/perf.py +53 -0
- auditkit-1.0.0/src/auditkit/metrics/rag.py +149 -0
- auditkit-1.0.0/src/auditkit/metrics/security.py +64 -0
- auditkit-1.0.0/src/auditkit/metrics/toxicity.py +238 -0
- auditkit-1.0.0/src/auditkit/model/README.md +16 -0
- auditkit-1.0.0/src/auditkit/model/__init__.py +485 -0
- auditkit-1.0.0/src/auditkit/model/anthropic.py +94 -0
- auditkit-1.0.0/src/auditkit/model/api_gen.py +133 -0
- auditkit-1.0.0/src/auditkit/model/groq_gen.py +121 -0
- auditkit-1.0.0/src/auditkit/model/hf_gen.py +385 -0
- auditkit-1.0.0/src/auditkit/model/lexsi.py +155 -0
- auditkit-1.0.0/src/auditkit/model/litellm_gen.py +65 -0
- auditkit-1.0.0/src/auditkit/model/openai.py +90 -0
- auditkit-1.0.0/src/auditkit/model/openrouter_gen.py +152 -0
- auditkit-1.0.0/src/auditkit/model/vllm_gen.py +316 -0
- auditkit-1.0.0/src/auditkit/model_compare.py +655 -0
- auditkit-1.0.0/src/auditkit/redteam/README.md +9 -0
- auditkit-1.0.0/src/auditkit/redteam/__init__.py +26 -0
- auditkit-1.0.0/src/auditkit/redteam/detector.py +37 -0
- auditkit-1.0.0/src/auditkit/redteam/detectors/README.md +5 -0
- auditkit-1.0.0/src/auditkit/redteam/detectors/builtin.py +126 -0
- auditkit-1.0.0/src/auditkit/redteam/probe.py +39 -0
- auditkit-1.0.0/src/auditkit/redteam/probes/README.md +5 -0
- auditkit-1.0.0/src/auditkit/redteam/probes/builtin.py +85 -0
- auditkit-1.0.0/src/auditkit/redteam/runner.py +206 -0
- auditkit-1.0.0/src/auditkit/registry.py +65 -0
- auditkit-1.0.0/src/auditkit/report.py +278 -0
- auditkit-1.0.0/src/auditkit/report_format.py +52 -0
- auditkit-1.0.0/src/auditkit/router.py +54 -0
- auditkit-1.0.0/src/auditkit/runner.py +575 -0
- auditkit-1.0.0/src/auditkit/runspec.py +159 -0
- auditkit-1.0.0/src/auditkit/sample.py +40 -0
- auditkit-1.0.0/src/auditkit/scenario.py +88 -0
- auditkit-1.0.0/src/auditkit/scenarios/README.md +10 -0
- auditkit-1.0.0/src/auditkit/scenarios/__init__.py +4 -0
- auditkit-1.0.0/src/auditkit/scenarios/arc.py +33 -0
- auditkit-1.0.0/src/auditkit/scenarios/gsm8k.py +32 -0
- auditkit-1.0.0/src/auditkit/scenarios/hellaswag.py +33 -0
- auditkit-1.0.0/src/auditkit/scenarios/humaneval.py +32 -0
- auditkit-1.0.0/src/auditkit/scenarios/mmlu.py +34 -0
- auditkit-1.0.0/src/auditkit/scenarios/truthfulqa.py +33 -0
- auditkit-1.0.0/src/auditkit/score.py +165 -0
- auditkit-1.0.0/src/auditkit/scorers.py +117 -0
- auditkit-1.0.0/src/auditkit/scoring.py +79 -0
- auditkit-1.0.0/src/auditkit/types.py +69 -0
- auditkit-1.0.0/tests/README.md +16 -0
- auditkit-1.0.0/tests/__init__.py +0 -0
- auditkit-1.0.0/tests/test_adapter.py +35 -0
- auditkit-1.0.0/tests/test_adapter_params.py +69 -0
- auditkit-1.0.0/tests/test_annotator.py +732 -0
- auditkit-1.0.0/tests/test_api.py +355 -0
- auditkit-1.0.0/tests/test_api_backend.py +108 -0
- auditkit-1.0.0/tests/test_benchmark.py +339 -0
- auditkit-1.0.0/tests/test_chat_messages.py +289 -0
- auditkit-1.0.0/tests/test_cli.py +92 -0
- auditkit-1.0.0/tests/test_code_metrics.py +365 -0
- auditkit-1.0.0/tests/test_compare.py +624 -0
- auditkit-1.0.0/tests/test_comparison.py +558 -0
- auditkit-1.0.0/tests/test_core_engine.py +88 -0
- auditkit-1.0.0/tests/test_custom_judge_pipeline.py +156 -0
- auditkit-1.0.0/tests/test_diff.py +257 -0
- auditkit-1.0.0/tests/test_embedding_metrics.py +110 -0
- auditkit-1.0.0/tests/test_encoder_judge.py +643 -0
- auditkit-1.0.0/tests/test_errors.py +27 -0
- auditkit-1.0.0/tests/test_evaluate_many.py +109 -0
- auditkit-1.0.0/tests/test_execute_concurrency.py +68 -0
- auditkit-1.0.0/tests/test_experiment.py +106 -0
- auditkit-1.0.0/tests/test_fingerprint_stability.py +86 -0
- auditkit-1.0.0/tests/test_generation_kwargs.py +884 -0
- auditkit-1.0.0/tests/test_generation_metrics.py +116 -0
- auditkit-1.0.0/tests/test_guard.py +433 -0
- auditkit-1.0.0/tests/test_hallucination_metrics.py +30 -0
- auditkit-1.0.0/tests/test_hf_gen_logits_sanitizer.py +137 -0
- auditkit-1.0.0/tests/test_hf_wire_format.py +55 -0
- auditkit-1.0.0/tests/test_integration.py +237 -0
- auditkit-1.0.0/tests/test_judge.py +100 -0
- auditkit-1.0.0/tests/test_judge_flow.py +109 -0
- auditkit-1.0.0/tests/test_llm_judge.py +282 -0
- auditkit-1.0.0/tests/test_lmeval_engine.py +506 -0
- auditkit-1.0.0/tests/test_lmeval_real_pipeline.py +147 -0
- auditkit-1.0.0/tests/test_loaders.py +79 -0
- auditkit-1.0.0/tests/test_metric.py +73 -0
- auditkit-1.0.0/tests/test_metrics_via_pipeline.py +283 -0
- auditkit-1.0.0/tests/test_model.py +160 -0
- auditkit-1.0.0/tests/test_model_backends.py +107 -0
- auditkit-1.0.0/tests/test_pairwise_metrics.py +120 -0
- auditkit-1.0.0/tests/test_pipeline_live_hf.py +319 -0
- auditkit-1.0.0/tests/test_practical.py +135 -0
- auditkit-1.0.0/tests/test_rag_metrics.py +149 -0
- auditkit-1.0.0/tests/test_redteam.py +103 -0
- auditkit-1.0.0/tests/test_registry.py +71 -0
- auditkit-1.0.0/tests/test_release.py +163 -0
- auditkit-1.0.0/tests/test_router.py +72 -0
- auditkit-1.0.0/tests/test_runner.py +424 -0
- auditkit-1.0.0/tests/test_sample.py +47 -0
- auditkit-1.0.0/tests/test_scenarios.py +35 -0
- auditkit-1.0.0/tests/test_score.py +107 -0
- auditkit-1.0.0/tests/test_security_perf.py +139 -0
- auditkit-1.0.0/tests/test_token_usage_and_cost.py +224 -0
- auditkit-1.0.0/tests/test_toxicity_metrics.py +130 -0
- auditkit-1.0.0/tests/test_types.py +19 -0
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
name: Automated patch release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request_target:
|
|
5
|
+
branches: [main]
|
|
6
|
+
types: [closed]
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
concurrency:
|
|
10
|
+
group: auditkit-patch-release
|
|
11
|
+
cancel-in-progress: false
|
|
12
|
+
|
|
13
|
+
permissions:
|
|
14
|
+
contents: read
|
|
15
|
+
pull-requests: read
|
|
16
|
+
|
|
17
|
+
env:
|
|
18
|
+
PYPI_PROJECT_NAME: auditkit
|
|
19
|
+
PACKAGE_DISPLAY_NAME: auditkit
|
|
20
|
+
|
|
21
|
+
jobs:
|
|
22
|
+
plan:
|
|
23
|
+
name: Inspect release state
|
|
24
|
+
if: github.event_name == 'workflow_dispatch' || github.event.pull_request.merged == true
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
outputs:
|
|
27
|
+
action: ${{ steps.plan.outputs.action }}
|
|
28
|
+
version: ${{ steps.plan.outputs.version }}
|
|
29
|
+
state: ${{ steps.plan.outputs.state }}
|
|
30
|
+
reason: ${{ steps.plan.outputs.reason }}
|
|
31
|
+
source-ref: ${{ steps.plan.outputs.source-ref }}
|
|
32
|
+
tag-exists: ${{ steps.plan.outputs.tag-exists }}
|
|
33
|
+
release-exists: ${{ steps.plan.outputs.release-exists }}
|
|
34
|
+
pypi-exists: ${{ steps.plan.outputs.pypi-exists }}
|
|
35
|
+
steps:
|
|
36
|
+
- name: Check out the trusted merged source
|
|
37
|
+
uses: actions/checkout@v6
|
|
38
|
+
with:
|
|
39
|
+
ref: ${{ github.event.pull_request.merge_commit_sha || github.ref }}
|
|
40
|
+
fetch-depth: 0
|
|
41
|
+
persist-credentials: false
|
|
42
|
+
|
|
43
|
+
- uses: actions/setup-python@v6
|
|
44
|
+
with:
|
|
45
|
+
python-version: "3.12"
|
|
46
|
+
|
|
47
|
+
- name: Classify trigger and external release state
|
|
48
|
+
id: plan
|
|
49
|
+
env:
|
|
50
|
+
GH_TOKEN: ${{ github.token }}
|
|
51
|
+
EVENT_NAME: ${{ github.event_name }}
|
|
52
|
+
shell: bash
|
|
53
|
+
run: |
|
|
54
|
+
set -euo pipefail
|
|
55
|
+
current_version=$(python scripts/release.py current-version)
|
|
56
|
+
source_sha=$(git rev-parse HEAD)
|
|
57
|
+
trigger=dispatch
|
|
58
|
+
requested_version=$current_version
|
|
59
|
+
|
|
60
|
+
if [[ "$EVENT_NAME" == "pull_request_target" ]]; then
|
|
61
|
+
trigger=normal
|
|
62
|
+
fi
|
|
63
|
+
|
|
64
|
+
latest_response=$(mktemp)
|
|
65
|
+
latest_status=$(curl --silent --show-error --location \
|
|
66
|
+
--header "Authorization: Bearer $GH_TOKEN" \
|
|
67
|
+
--header "Accept: application/vnd.github+json" \
|
|
68
|
+
--output "$latest_response" --write-out '%{http_code}' \
|
|
69
|
+
"https://api.github.com/repos/$GITHUB_REPOSITORY/releases/latest")
|
|
70
|
+
if [[ "$latest_status" == "200" ]]; then
|
|
71
|
+
latest_version=$(python -c \
|
|
72
|
+
'import json,sys; print(json.load(open(sys.argv[1]))["tag_name"])' \
|
|
73
|
+
"$latest_response")
|
|
74
|
+
requested_version=$(python -c \
|
|
75
|
+
'import sys; from scripts.release import next_patch; print(next_patch(sys.argv[1]))' \
|
|
76
|
+
"$latest_version")
|
|
77
|
+
|
|
78
|
+
if git show-ref --verify --quiet "refs/tags/$latest_version"; then
|
|
79
|
+
latest_commit=$(git rev-list -n 1 "$latest_version")
|
|
80
|
+
latest_parent=$(git rev-parse "$latest_commit^" 2>/dev/null || true)
|
|
81
|
+
if [[ "$latest_commit" == "$source_sha" || "$latest_parent" == "$source_sha" ]]; then
|
|
82
|
+
requested_version=$latest_version
|
|
83
|
+
fi
|
|
84
|
+
fi
|
|
85
|
+
elif [[ "$latest_status" != "404" ]]; then
|
|
86
|
+
echo "::error::Latest GitHub release lookup failed with HTTP $latest_status."
|
|
87
|
+
exit 1
|
|
88
|
+
fi
|
|
89
|
+
|
|
90
|
+
tag_exists=false
|
|
91
|
+
tag_annotated=true
|
|
92
|
+
tag_matches_source=true
|
|
93
|
+
source_ref=$source_sha
|
|
94
|
+
if git show-ref --verify --quiet "refs/tags/$requested_version"; then
|
|
95
|
+
tag_exists=true
|
|
96
|
+
source_ref="refs/tags/$requested_version"
|
|
97
|
+
if [[ "$(git cat-file -t "$requested_version")" != "tag" ]]; then
|
|
98
|
+
tag_annotated=false
|
|
99
|
+
fi
|
|
100
|
+
tag_commit=$(git rev-list -n 1 "$requested_version")
|
|
101
|
+
tag_parent=$(git rev-parse "$tag_commit^" 2>/dev/null || true)
|
|
102
|
+
if [[ "$tag_commit" != "$source_sha" && "$tag_parent" != "$source_sha" ]]; then
|
|
103
|
+
tag_matches_source=false
|
|
104
|
+
fi
|
|
105
|
+
|
|
106
|
+
version_tree=$(mktemp -d)
|
|
107
|
+
mkdir -p "$version_tree/src/auditkit" "$version_tree/scripts"
|
|
108
|
+
cp scripts/release.py "$version_tree/scripts/release.py"
|
|
109
|
+
for version_file in pyproject.toml src/auditkit/__init__.py CITATION.cff; do
|
|
110
|
+
git show "$requested_version:$version_file" > "$version_tree/$version_file"
|
|
111
|
+
done
|
|
112
|
+
if ! (cd "$version_tree" && python scripts/release.py validate-version "$requested_version"); then
|
|
113
|
+
tag_matches_source=false
|
|
114
|
+
fi
|
|
115
|
+
fi
|
|
116
|
+
|
|
117
|
+
release_response=$(mktemp)
|
|
118
|
+
release_status=$(curl --silent --show-error --location \
|
|
119
|
+
--header "Authorization: Bearer $GH_TOKEN" \
|
|
120
|
+
--header "Accept: application/vnd.github+json" \
|
|
121
|
+
--output "$release_response" --write-out '%{http_code}' \
|
|
122
|
+
"https://api.github.com/repos/$GITHUB_REPOSITORY/releases/tags/$requested_version")
|
|
123
|
+
release_exists=false
|
|
124
|
+
release_matches_tag=true
|
|
125
|
+
if [[ "$release_status" == "200" ]]; then
|
|
126
|
+
release_exists=true
|
|
127
|
+
if ! python - "$release_response" "$requested_version" <<'PY'
|
|
128
|
+
import json
|
|
129
|
+
import sys
|
|
130
|
+
|
|
131
|
+
release = json.load(open(sys.argv[1], encoding="utf-8"))
|
|
132
|
+
expected = sys.argv[2]
|
|
133
|
+
valid = (
|
|
134
|
+
release.get("tag_name") == expected
|
|
135
|
+
and release.get("name") == expected
|
|
136
|
+
and isinstance(release.get("draft"), bool)
|
|
137
|
+
and release.get("prerelease") is False
|
|
138
|
+
)
|
|
139
|
+
raise SystemExit(0 if valid else 1)
|
|
140
|
+
PY
|
|
141
|
+
then
|
|
142
|
+
release_matches_tag=false
|
|
143
|
+
fi
|
|
144
|
+
elif [[ "$release_status" != "404" ]]; then
|
|
145
|
+
echo "::error::GitHub release lookup failed with HTTP $release_status."
|
|
146
|
+
exit 1
|
|
147
|
+
fi
|
|
148
|
+
|
|
149
|
+
pypi_response=$(mktemp)
|
|
150
|
+
pypi_status=$(curl --silent --show-error --location \
|
|
151
|
+
--output "$pypi_response" --write-out '%{http_code}' \
|
|
152
|
+
"https://pypi.org/pypi/$PYPI_PROJECT_NAME/$requested_version/json")
|
|
153
|
+
pypi_exists=false
|
|
154
|
+
if [[ "$pypi_status" == "200" ]]; then
|
|
155
|
+
pypi_exists=true
|
|
156
|
+
python - "$pypi_response" "$requested_version" <<'PY'
|
|
157
|
+
import json
|
|
158
|
+
import sys
|
|
159
|
+
|
|
160
|
+
payload = json.load(open(sys.argv[1], encoding="utf-8"))
|
|
161
|
+
if payload.get("info", {}).get("version") != sys.argv[2]:
|
|
162
|
+
raise SystemExit("PyPI returned metadata for an unexpected version")
|
|
163
|
+
PY
|
|
164
|
+
elif [[ "$pypi_status" != "404" ]]; then
|
|
165
|
+
echo "::error::PyPI lookup failed with HTTP $pypi_status."
|
|
166
|
+
exit 1
|
|
167
|
+
fi
|
|
168
|
+
|
|
169
|
+
decision=$(python scripts/release.py plan \
|
|
170
|
+
--trigger "$trigger" --version "$requested_version" \
|
|
171
|
+
--tag "$tag_exists" --release "$release_exists" --pypi "$pypi_exists" \
|
|
172
|
+
--tag-annotated "$tag_annotated" \
|
|
173
|
+
--tag-matches-source "$tag_matches_source" \
|
|
174
|
+
--release-matches-tag "$release_matches_tag")
|
|
175
|
+
|
|
176
|
+
action=$(python -c 'import json,sys; print(json.loads(sys.argv[1])["action"])' "$decision")
|
|
177
|
+
version=$(python -c 'import json,sys; print(json.loads(sys.argv[1])["version"])' "$decision")
|
|
178
|
+
state=$(python -c 'import json,sys; print(json.loads(sys.argv[1])["state"])' "$decision")
|
|
179
|
+
reason=$(python -c 'import json,sys; print(json.loads(sys.argv[1])["reason"])' "$decision")
|
|
180
|
+
{
|
|
181
|
+
echo "action=$action"
|
|
182
|
+
echo "version=$version"
|
|
183
|
+
echo "state=$state"
|
|
184
|
+
echo "reason=$reason"
|
|
185
|
+
echo "source-ref=$source_ref"
|
|
186
|
+
echo "tag-exists=$tag_exists"
|
|
187
|
+
echo "release-exists=$release_exists"
|
|
188
|
+
echo "pypi-exists=$pypi_exists"
|
|
189
|
+
} >> "$GITHUB_OUTPUT"
|
|
190
|
+
echo "Release decision: action=$action version=$version state=$state reason=$reason"
|
|
191
|
+
|
|
192
|
+
release:
|
|
193
|
+
name: Build, release, and publish
|
|
194
|
+
needs: plan
|
|
195
|
+
if: needs.plan.outputs.action == 'release'
|
|
196
|
+
runs-on: ubuntu-latest
|
|
197
|
+
permissions:
|
|
198
|
+
contents: write
|
|
199
|
+
env:
|
|
200
|
+
RELEASE_TAG: ${{ needs.plan.outputs.version }}
|
|
201
|
+
steps:
|
|
202
|
+
- name: Check out exact release source
|
|
203
|
+
uses: actions/checkout@v6
|
|
204
|
+
with:
|
|
205
|
+
ref: ${{ needs.plan.outputs.source-ref }}
|
|
206
|
+
fetch-depth: 0
|
|
207
|
+
|
|
208
|
+
- uses: actions/setup-python@v6
|
|
209
|
+
with:
|
|
210
|
+
python-version: "3.12"
|
|
211
|
+
|
|
212
|
+
- name: Prepare exact release version
|
|
213
|
+
shell: bash
|
|
214
|
+
run: |
|
|
215
|
+
set -euo pipefail
|
|
216
|
+
current_version=$(python scripts/release.py current-version)
|
|
217
|
+
if [[ "$current_version" != "$RELEASE_TAG" ]]; then
|
|
218
|
+
python scripts/release.py set-version "$RELEASE_TAG"
|
|
219
|
+
expected_files=$'CITATION.cff\npyproject.toml\nsrc/auditkit/__init__.py'
|
|
220
|
+
actual_files=$(git diff --name-only | sort)
|
|
221
|
+
if [[ "$actual_files" != "$expected_files" ]]; then
|
|
222
|
+
echo "::error::Version helper changed files outside the authoritative version set."
|
|
223
|
+
exit 1
|
|
224
|
+
fi
|
|
225
|
+
git config user.name github-actions[bot]
|
|
226
|
+
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
|
|
227
|
+
git add CITATION.cff pyproject.toml src/auditkit/__init__.py
|
|
228
|
+
git commit -m "Release $RELEASE_TAG"
|
|
229
|
+
fi
|
|
230
|
+
python scripts/release.py validate-version "$RELEASE_TAG"
|
|
231
|
+
|
|
232
|
+
# Tests are intentionally skipped in the release workflow to avoid delaying
|
|
233
|
+
# GitHub releases and PyPI publication.
|
|
234
|
+
# - name: Install project test dependencies
|
|
235
|
+
# continue-on-error: true
|
|
236
|
+
# run: python -m pip install -e ".[dev]"
|
|
237
|
+
|
|
238
|
+
# - name: Run project test suite (advisory)
|
|
239
|
+
# continue-on-error: true
|
|
240
|
+
# run: python -m pytest
|
|
241
|
+
|
|
242
|
+
- name: Install mandatory packaging tools
|
|
243
|
+
run: python -m pip install --upgrade build twine
|
|
244
|
+
|
|
245
|
+
- name: Build and validate distributions
|
|
246
|
+
run: |
|
|
247
|
+
python -m build
|
|
248
|
+
python -m twine check dist/*
|
|
249
|
+
python scripts/release.py validate-dist "$RELEASE_TAG" --project-name "$PYPI_PROJECT_NAME" dist/*
|
|
250
|
+
|
|
251
|
+
- name: Create or verify annotated tag
|
|
252
|
+
env:
|
|
253
|
+
GH_TOKEN: ${{ github.token }}
|
|
254
|
+
shell: bash
|
|
255
|
+
run: |
|
|
256
|
+
set -euo pipefail
|
|
257
|
+
expected_sha=$(git rev-parse HEAD)
|
|
258
|
+
git fetch --force origin "refs/tags/$RELEASE_TAG:refs/tags/$RELEASE_TAG" 2>/dev/null || true
|
|
259
|
+
if git show-ref --verify --quiet "refs/tags/$RELEASE_TAG"; then
|
|
260
|
+
if [[ "$(git cat-file -t "$RELEASE_TAG")" != "tag" ]]; then
|
|
261
|
+
echo "::error::Existing $RELEASE_TAG is not an annotated tag."
|
|
262
|
+
exit 1
|
|
263
|
+
fi
|
|
264
|
+
if [[ "$(git rev-list -n 1 "$RELEASE_TAG")" != "$expected_sha" ]]; then
|
|
265
|
+
echo "::error::Existing $RELEASE_TAG points at a different commit; it will not be moved."
|
|
266
|
+
exit 1
|
|
267
|
+
fi
|
|
268
|
+
else
|
|
269
|
+
git config user.name github-actions[bot]
|
|
270
|
+
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
|
|
271
|
+
git tag --annotate "$RELEASE_TAG" --message "auditkit $RELEASE_TAG"
|
|
272
|
+
git push origin "refs/tags/$RELEASE_TAG"
|
|
273
|
+
fi
|
|
274
|
+
|
|
275
|
+
- name: Create or verify GitHub release
|
|
276
|
+
env:
|
|
277
|
+
GH_TOKEN: ${{ github.token }}
|
|
278
|
+
shell: bash
|
|
279
|
+
run: |
|
|
280
|
+
set -euo pipefail
|
|
281
|
+
if gh release view "$RELEASE_TAG" \
|
|
282
|
+
--json databaseId,tagName,name,isDraft,isPrerelease > release.json 2>/dev/null; then
|
|
283
|
+
release_state=$(python - "$RELEASE_TAG" <<'PY'
|
|
284
|
+
import json
|
|
285
|
+
import sys
|
|
286
|
+
|
|
287
|
+
release = json.load(open("release.json", encoding="utf-8"))
|
|
288
|
+
expected = sys.argv[1]
|
|
289
|
+
valid = (
|
|
290
|
+
release.get("tagName") == expected
|
|
291
|
+
and release.get("name") == expected
|
|
292
|
+
and isinstance(release.get("isDraft"), bool)
|
|
293
|
+
and release.get("isPrerelease") is False
|
|
294
|
+
and isinstance(release.get("databaseId"), int)
|
|
295
|
+
)
|
|
296
|
+
if not valid:
|
|
297
|
+
raise SystemExit(f"Existing GitHub release conflicts with {expected}: {release}")
|
|
298
|
+
print("draft" if release["isDraft"] else "published")
|
|
299
|
+
PY
|
|
300
|
+
)
|
|
301
|
+
if [[ "$release_state" == "draft" ]]; then
|
|
302
|
+
release_id=$(python -c 'import json; print(json.load(open("release.json"))["databaseId"])')
|
|
303
|
+
gh api --method PATCH "repos/$GITHUB_REPOSITORY/releases/$release_id" \
|
|
304
|
+
--field draft=false --silent
|
|
305
|
+
echo "Published existing draft GitHub release $RELEASE_TAG."
|
|
306
|
+
fi
|
|
307
|
+
else
|
|
308
|
+
gh release create "$RELEASE_TAG" --verify-tag --generate-notes --title "$RELEASE_TAG"
|
|
309
|
+
fi
|
|
310
|
+
|
|
311
|
+
- name: Publish the exact distributions to PyPI
|
|
312
|
+
if: needs.plan.outputs.pypi-exists == 'false'
|
|
313
|
+
env:
|
|
314
|
+
TWINE_USERNAME: __token__
|
|
315
|
+
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
|
|
316
|
+
shell: bash
|
|
317
|
+
run: |
|
|
318
|
+
set -euo pipefail
|
|
319
|
+
: "${TWINE_PASSWORD:?PYPI_API_TOKEN is required to publish the release}"
|
|
320
|
+
python -m twine upload --non-interactive --verbose dist/*
|
|
321
|
+
|
|
322
|
+
# The version-bump commit created above (if any) only exists on this
|
|
323
|
+
# detached checkout so far; fast-forward main with it so the tracked
|
|
324
|
+
# version files don't silently drift behind the release that was just
|
|
325
|
+
# tagged and published. This is push-only and never forced: if main
|
|
326
|
+
# has moved on (a race with a new merge) or branch protection blocks
|
|
327
|
+
# a direct push, git rejects the push and we just warn instead of
|
|
328
|
+
# failing an otherwise-successful release.
|
|
329
|
+
- name: Sync release version bump back to main
|
|
330
|
+
if: needs.plan.outputs.tag-exists == 'false'
|
|
331
|
+
continue-on-error: true
|
|
332
|
+
env:
|
|
333
|
+
GH_TOKEN: ${{ github.token }}
|
|
334
|
+
shell: bash
|
|
335
|
+
run: |
|
|
336
|
+
set -euo pipefail
|
|
337
|
+
if git push origin HEAD:main; then
|
|
338
|
+
echo "Synced the $RELEASE_TAG version bump back to main."
|
|
339
|
+
else
|
|
340
|
+
echo "::warning::Could not fast-forward main with the $RELEASE_TAG version bump (branch protection or a race with a new merge). main's version files may still show the previous version; sync them manually, e.g. via 'python scripts/release.py set-version $RELEASE_TAG'."
|
|
341
|
+
fi
|
|
342
|
+
|
|
343
|
+
- name: Send release notes to Slack
|
|
344
|
+
uses: slackapi/slack-github-action@v1.24.0
|
|
345
|
+
continue-on-error: true
|
|
346
|
+
with:
|
|
347
|
+
channel-id: "lexsi-labs-auditkit-release" #${{ vars.SLACK_CHANNEL }}
|
|
348
|
+
payload: |
|
|
349
|
+
{
|
|
350
|
+
"text": "Auditkit release",
|
|
351
|
+
"blocks": [
|
|
352
|
+
{
|
|
353
|
+
"type": "section",
|
|
354
|
+
"text": {
|
|
355
|
+
"type": "mrkdwn",
|
|
356
|
+
"text": "*Version:* ${{ env.RELEASE_TAG }}"
|
|
357
|
+
}
|
|
358
|
+
},
|
|
359
|
+
{
|
|
360
|
+
"type": "section",
|
|
361
|
+
"text": {
|
|
362
|
+
"type": "mrkdwn",
|
|
363
|
+
"text": "*Release:* https://github.com/${{ github.repository }}/releases/tag/${{ env.RELEASE_TAG }}"
|
|
364
|
+
}
|
|
365
|
+
},
|
|
366
|
+
{
|
|
367
|
+
"type": "section",
|
|
368
|
+
"text": {
|
|
369
|
+
"type": "mrkdwn",
|
|
370
|
+
"text": "*PyPI:* https://pypi.org/project/auditkit/${{ env.RELEASE_TAG }}/"
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
]
|
|
374
|
+
}
|
|
375
|
+
env:
|
|
376
|
+
SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_TOKEN }}
|
auditkit-1.0.0/AGENTS.md
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Agent instructions — AuditKit (release v1.0.0)
|
|
2
|
+
|
|
3
|
+
AuditKit is a standalone Python library that evaluates any model on any dataset
|
|
4
|
+
across any technique. The core runs on the standard library with **zero required
|
|
5
|
+
third-party dependencies**; model backends and heavy metrics are optional extras.
|
|
6
|
+
|
|
7
|
+
## Architecture — the 5-stage spine
|
|
8
|
+
|
|
9
|
+
`Dataset → Adapter → Model → Metrics → RunResult`, orchestrated by `ak.evaluate()`.
|
|
10
|
+
|
|
11
|
+
- **Dataset** — prompts and expected outputs (a YAML file, a Python list, or a loader).
|
|
12
|
+
- **Adapter** — the elicitation technique: benchmark, LLM-as-judge (`GEval`), code
|
|
13
|
+
checks, RAG, hallucination, embedding similarity, toxicity/bias, pairwise/preference,
|
|
14
|
+
red-teaming, security, performance.
|
|
15
|
+
- **Model** — 9 backends resolved by `AutoModel.resolve()`: `openai:`, `anthropic:`,
|
|
16
|
+
`hf:`, `lexsi:`, `vllm:`, `litellm:` (also reaches Ollama), `api:`, `groq:`,
|
|
17
|
+
`openrouter:`. Any `list[str] → list[str]` callable also works; `echo` is the
|
|
18
|
+
dependency-free stub for tests.
|
|
19
|
+
- **Metrics** — every metric subclasses `auditkit.metric.Metric` (10 families).
|
|
20
|
+
- **RunResult** — aggregate scores, per-sample rows, and `perf` (latency/throughput).
|
|
21
|
+
|
|
22
|
+
## Install
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install auditkit # core, zero deps
|
|
26
|
+
pip install "auditkit[openai]" # one backend
|
|
27
|
+
pip install "auditkit[all]" # all backends + heavy metrics
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Quickstart
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
import auditkit as ak
|
|
34
|
+
|
|
35
|
+
result = ak.evaluate(
|
|
36
|
+
model="echo", # or "openai:gpt-4o-mini", "hf:Qwen/Qwen2.5-0.5B", ...
|
|
37
|
+
prompts=["2+2=", "capital of France?"],
|
|
38
|
+
metrics=[ak.Contains("4"), ak.Contains("Paris")],
|
|
39
|
+
)
|
|
40
|
+
print(result.summary())
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## CLI
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
auditkit eval config.yaml # run a YAML-defined evaluation
|
|
47
|
+
auditkit init # scaffold a config
|
|
48
|
+
auditkit list # list available metrics/backends
|
|
49
|
+
auditkit compare ... # compare models
|
|
50
|
+
auditkit redteam ... # red-team probes
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Test
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
python -m pytest tests/ -q --tb=short # pyproject sets pythonpath=src; use python3 on Unix
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
~53 test modules under `tests/`. The CLI subprocess tests need an editable install
|
|
60
|
+
(`pip install -e .`). Some `test_extra_not_installed` checks fail on machines that
|
|
61
|
+
have optional extras (e.g. `transformers`) installed globally — that is expected.
|
|
62
|
+
|
|
63
|
+
## Conventions
|
|
64
|
+
|
|
65
|
+
- `from __future__ import annotations` at the top of every module.
|
|
66
|
+
- **Zero required third-party deps.** Never import an optional extra at module top
|
|
67
|
+
level — import it lazily inside the function that needs it, and raise a clear error
|
|
68
|
+
if the extra is missing.
|
|
69
|
+
- Metrics inherit `auditkit.metric.Metric`; models inherit `auditkit.model.Model`.
|
|
70
|
+
Register new ones through `registry.py` / `router.py`.
|
|
71
|
+
- One test file per module or feature area, in `tests/`.
|
|
72
|
+
- **Version lives in two places, keep them in sync:** `src/auditkit/__init__.py`
|
|
73
|
+
(`__version__`) and `pyproject.toml` (`version`).
|
|
74
|
+
|
|
75
|
+
## Module map (`src/auditkit/`)
|
|
76
|
+
|
|
77
|
+
| Module | Role |
|
|
78
|
+
|--------|------|
|
|
79
|
+
| `api.py` | Public `ak.evaluate()` surface |
|
|
80
|
+
| `runner.py`, `runspec.py` | Execution engine and run configuration |
|
|
81
|
+
| `adapter.py`, `scenario.py` | Elicitation techniques and scenarios |
|
|
82
|
+
| `model/`, `router.py`, `registry.py` | Model backends and resolution |
|
|
83
|
+
| `metric.py`, `metrics/`, `scorers.py`, `scoring.py` | Metrics and scoring |
|
|
84
|
+
| `comparison.py`, `model_compare.py`, `diff.py` | Model comparison |
|
|
85
|
+
| `redteam/` | Red-team probes |
|
|
86
|
+
| `report.py`, `report_format.py` | Result rendering |
|
|
87
|
+
| `cli.py`, `__main__.py` | Command-line interface |
|
|
88
|
+
|
|
89
|
+
## License
|
|
90
|
+
|
|
91
|
+
Released under the **Lexsi Labs Source Available License (LSAL) v1.2** — free for
|
|
92
|
+
academic research and teaching (MIT-like); organizations must acknowledge their use
|
|
93
|
+
or obtain permission (Section 1A); commercial use requires a separate license. See
|
|
94
|
+
[LICENSE.md](LICENSE.md).
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
cff-version: 1.2.0
|
|
2
|
+
title: AuditKit
|
|
3
|
+
abstract: |
|
|
4
|
+
AuditKit is a Python library for evaluating and auditing AI models: a unified
|
|
5
|
+
evaluation spine across techniques and modalities. It provides 10 metric
|
|
6
|
+
families, 9 model backends, LLM-as-judge and encoder-judge scorers, a CLI with
|
|
7
|
+
YAML-configured runs, and an MkDocs documentation site.
|
|
8
|
+
type: software
|
|
9
|
+
message: "If you use this software, please cite it."
|
|
10
|
+
|
|
11
|
+
version: 1.0.0
|
|
12
|
+
|
|
13
|
+
authors:
|
|
14
|
+
- family-names: "Avaiya"
|
|
15
|
+
given-names: "Utsav"
|
|
16
|
+
- family-names: "Arora"
|
|
17
|
+
given-names: "Shreeyans"
|
|
18
|
+
- family-names: "Kadiyala"
|
|
19
|
+
given-names: "Ram Mohan Rao"
|
|
20
|
+
- family-names: "Lyngkhoi"
|
|
21
|
+
given-names: "Zera"
|
|
22
|
+
- family-names: "Sankarapu"
|
|
23
|
+
given-names: "Vinay Kumar"
|
|
24
|
+
- family-names: "Seth"
|
|
25
|
+
given-names: "Pratinav"
|
|
26
|
+
email: "pratinav.seth@lexsi.ai"
|
|
27
|
+
|
|
28
|
+
contact:
|
|
29
|
+
- family-names: "Seth"
|
|
30
|
+
given-names: "Pratinav"
|
|
31
|
+
email: "pratinav.seth@lexsi.ai"
|
|
32
|
+
|
|
33
|
+
repository-code: "https://github.com/Lexsi-Labs/AuditKIT"
|
|
34
|
+
url: "https://github.com/Lexsi-Labs/AuditKIT"
|
|
35
|
+
license: LSAL-1.2
|
|
36
|
+
license-url: "https://github.com/Lexsi-Labs/AuditKIT/blob/main/LICENSE.md"
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Lexsi Labs Source Available License (LSAL), Version 1.2 (AuditKit)
|
|
2
|
+
|
|
3
|
+
## Preamble
|
|
4
|
+
|
|
5
|
+
This Source Available License governs use of the software known as **AuditKit**, together with its documentation, CLI, and example pipelines (collectively, the "Licensed Work"), developed and owned by **Lexsi Labs (Lithasa Technologies Pvt. Ltd.)** ("Licensor").
|
|
6
|
+
|
|
7
|
+
This is **not** an open-source license as defined by the [Open Source Initiative (OSI)](https://opensource.org/). It grants **academic research and teaching** MIT-like permissions: free use, modification, and redistribution with the notice intact. Organizations must acknowledge their use or obtain permission (Section 1A). It also bars commercial exploitation.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 1. Grant of Rights
|
|
12
|
+
|
|
13
|
+
Subject to the terms of this License, permission is hereby granted, free of charge, to any person obtaining a copy of the Licensed Work, to use, copy, modify, merge, publish, and redistribute the Licensed Work and derivative works thereof, **for Noncommercial Purposes only**, provided that the above copyright notice and this License are included in full in all copies or substantial portions of the Licensed Work.
|
|
14
|
+
|
|
15
|
+
For academic research and teaching, this grant is MIT-like: you may use, modify, and redistribute the Licensed Work, provided the copyright notice and this License travel with every copy.
|
|
16
|
+
|
|
17
|
+
**Noncommercial Purposes** means:
|
|
18
|
+
|
|
19
|
+
* personal use for research, experimentation, private study, or hobby projects;
|
|
20
|
+
* academic and scholarly research, teaching, and publication (including use in papers, theses, benchmarks, and reproducibility artifacts).
|
|
21
|
+
|
|
22
|
+
Research and teaching by academics and their groups, including work done at a university or public research body, falls under this Section. Section 1A governs use by an organization as such, including a charitable organization, educational institution, public research organization, or government body acting for its own operations.
|
|
23
|
+
|
|
24
|
+
## 1A. Use by Organizations
|
|
25
|
+
|
|
26
|
+
Before any organization, including a charitable organization, educational institution, public research organization, or government body, uses the Licensed Work for **internal evaluation, red-teaming, benchmarking, auditing, or any use in connection with developing, evaluating, or safeguarding its own models, products, or services**, whether or not it charges a fee or provides the Licensed Work to third parties, it must either:
|
|
27
|
+
|
|
28
|
+
* obtain Licensor's **prior written permission**; or
|
|
29
|
+
* provide Licensor a written **acknowledgement of use**, identifying the organization, the intended use, and an undertaking to attribute the Licensed Work, which Licensor may accept in place of negotiated permission.
|
|
30
|
+
|
|
31
|
+
Both go to **support@lexsi.ai**.
|
|
32
|
+
|
|
33
|
+
Licensor grants permission at its discretion. The written permission sets out the terms, which may include sharing with Licensor the evaluation results the Licensed Work produces, in AuditKit's standard report format, excluding model weights, training data, prompt text, and model generations. Licensor uses shared results for research and for improving the Licensed Work, and handles them under the terms stated in the written permission.
|
|
34
|
+
|
|
35
|
+
Permission under this Section does not authorize any use described in Section 2.
|
|
36
|
+
|
|
37
|
+
## 2. Commercial Restriction
|
|
38
|
+
|
|
39
|
+
Without a separate **commercial license** from Lexsi Labs, you may **not** Sell the Licensed Work. "**Sell**" means practicing any right granted to you under this License to provide to third parties, for a fee or other consideration, a product or service whose value derives, entirely or substantially, from the functionality of the Licensed Work, including:
|
|
40
|
+
|
|
41
|
+
* offering the Licensed Work, or a derivative of it, as a commercial product, paid service, SaaS, hosted, or API offering;
|
|
42
|
+
* embedding the Licensed Work in proprietary or revenue-generating software;
|
|
43
|
+
* paid consulting or support whose substance is the Licensed Work.
|
|
44
|
+
|
|
45
|
+
If you redistribute a modified version, you must mark it as modified and must not present it as the original. You may also not **re-license, rebrand, or redistribute** the Licensed Work under different terms, nor use **Lexsi Labs**, **AuditKit**, or related trademarks, logos, or branding except to identify unmodified, licensed copies.
|
|
46
|
+
|
|
47
|
+
## 3. Patents
|
|
48
|
+
|
|
49
|
+
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. Any patent rights of Licensor relating to the Licensed Work are reserved and may be licensed only under a separate written agreement with Licensor.
|
|
50
|
+
|
|
51
|
+
## 3A. Third-Party Components
|
|
52
|
+
|
|
53
|
+
The Licensed Work evaluates and audits third-party base models and draws on third-party benchmarks and datasets. Each carries its own license, and this License grants no rights under any of them. You must comply with those terms in addition to this License, including any restrictions a base-model or dataset license places on your use of it.
|
|
54
|
+
|
|
55
|
+
## 4. Ownership
|
|
56
|
+
|
|
57
|
+
All rights, title, and interest in and to the Licensed Work remain with **Lithasa Technologies Pvt. Ltd.** Except as expressly stated in Sections 1 and 1A, nothing in this License transfers ownership or any other rights to the Licensee.
|
|
58
|
+
|
|
59
|
+
## 5. Contributions
|
|
60
|
+
|
|
61
|
+
If you submit modifications, pull requests, or patches ("Contributions") to Lexsi Labs, you grant Lexsi Labs a perpetual, worldwide, royalty-free right to use, modify, distribute, and license your Contributions under any terms, including commercial ones, and you represent that you have the right to make such Contributions.
|
|
62
|
+
|
|
63
|
+
## 6. Warranty Disclaimer and Responsibility for Use
|
|
64
|
+
|
|
65
|
+
THE LICENSED WORK IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL THE LICENSOR OR CONTRIBUTORS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE LICENSED WORK OR THE USE OR OTHER DEALINGS IN THE LICENSED WORK.
|
|
66
|
+
|
|
67
|
+
**You alone are responsible for your use of the Licensed Work.** This includes every evaluation, audit, output, or system you produce with it, and your compliance with applicable law. This responsibility applies to academic, personal, organizational, and commercial use alike. Licensor has no duty to monitor your use and bears no liability for misuse of the Licensed Work by you or by any third party who obtained it through you.
|
|
68
|
+
|
|
69
|
+
The Licensed Work is a research and auditing tool. Any measurements or findings it reports hold only under the conditions you configure. They do not certify that any model is safe to deploy; that decision rests with you.
|
|
70
|
+
|
|
71
|
+
If you use the Licensed Work under Section 1A or under a commercial license, you will, to the extent permitted by applicable law, indemnify and hold harmless Licensor and its contributors against any claim, loss, or expense, including legal fees, arising from your use or misuse of the Licensed Work or from any breach of this License by you. This indemnity does not apply to personal or academic use under Section 1; the two preceding paragraphs govern that use.
|
|
72
|
+
|
|
73
|
+
## 7. Termination
|
|
74
|
+
|
|
75
|
+
This License terminates without notice if you breach any of its terms. On termination, you must stop using the Licensed Work and destroy every copy in your possession. Licenses of parties who received the Licensed Work from you remain in force provided they remain in compliance.
|
|
76
|
+
|
|
77
|
+
Sections 3, 3A, 4, 5, 6, and 8 survive termination.
|
|
78
|
+
|
|
79
|
+
## 8. Governing Law and General Terms
|
|
80
|
+
|
|
81
|
+
This License shall be governed by and construed in accordance with the **laws of India**, without regard to its conflict of law principles. If a court holds any provision of this License unenforceable, the remaining provisions stay in effect. Licensor may publish revised versions of this License; a copy of the Licensed Work remains under the version it was received under unless you accept a later version.
|
|
82
|
+
|
|
83
|
+
## 9. Contact
|
|
84
|
+
|
|
85
|
+
For acknowledgements and permission requests under Section 1A, and for commercial use, partnership, or redistribution rights under Section 2, contact:
|
|
86
|
+
**support@lexsi.ai** · **https://lexsi.ai**
|
|
87
|
+
|
|
88
|
+
## 10. Notice
|
|
89
|
+
|
|
90
|
+
**AuditKit** © 2026 **Lithasa Technologies Pvt. Ltd.**
|
|
91
|
+
Licensed under the **Lexsi Labs Source Available License (LSAL) v1.2**.
|
|
92
|
+
**Academic research and teaching are free on MIT-like terms. Use by any organization requires written acknowledgement or permission (Section 1A). Commercial use requires a commercial license (Section 2).**
|