policynim 0.1.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.
- policynim-0.1.0/.dockerignore +14 -0
- policynim-0.1.0/.env.development.example +27 -0
- policynim-0.1.0/.env.example +36 -0
- policynim-0.1.0/.env.production.example +35 -0
- policynim-0.1.0/.github/workflows/ci.yml +54 -0
- policynim-0.1.0/.github/workflows/hosted-smoke.yml +42 -0
- policynim-0.1.0/.github/workflows/release.yml +291 -0
- policynim-0.1.0/.gitignore +19 -0
- policynim-0.1.0/.pre-commit-config.yaml +19 -0
- policynim-0.1.0/.python-version +2 -0
- policynim-0.1.0/.threadloop/config.json +4 -0
- policynim-0.1.0/Dockerfile +43 -0
- policynim-0.1.0/Dockerfile.railway +45 -0
- policynim-0.1.0/LICENSE +21 -0
- policynim-0.1.0/PKG-INFO +284 -0
- policynim-0.1.0/README.md +217 -0
- policynim-0.1.0/docs/ai-engineer-miami-context-plane.md +33 -0
- policynim-0.1.0/docs/architecture-diagram.md +282 -0
- policynim-0.1.0/docs/architecture.md +439 -0
- policynim-0.1.0/docs/assets/readme/policynim-beta-dark-landing-preview.png +0 -0
- policynim-0.1.0/docs/contributor-guide.md +225 -0
- policynim-0.1.0/docs/demo-script.md +265 -0
- policynim-0.1.0/docs/extreme-programming-with-agents.md +109 -0
- policynim-0.1.0/docs/hosted-beta-operations.md +304 -0
- policynim-0.1.0/docs/index.md +45 -0
- policynim-0.1.0/docs/limitations.md +138 -0
- policynim-0.1.0/docs/public-source-grounding.md +118 -0
- policynim-0.1.0/docs/release.md +84 -0
- policynim-0.1.0/docs/workflows.md +587 -0
- policynim-0.1.0/evals/default_cases.json +61 -0
- policynim-0.1.0/examples/claude-code/README.md +104 -0
- policynim-0.1.0/examples/codex/README.md +121 -0
- policynim-0.1.0/packaging/pyinstaller.spec +62 -0
- policynim-0.1.0/packmind.json +4 -0
- policynim-0.1.0/policies/TEMPLATE.md +52 -0
- policynim-0.1.0/policies/architecture/api-versioning-guidance.md +46 -0
- policynim-0.1.0/policies/architecture/background-job-design-rules.md +47 -0
- policynim-0.1.0/policies/backend/backend-logging-standard.md +48 -0
- policynim-0.1.0/policies/backend/config-validation-and-fail-closed.md +43 -0
- policynim-0.1.0/policies/backend/request-correlation-and-tracing-standard.md +45 -0
- policynim-0.1.0/policies/security/auth-sensitive-code-review-standard.md +47 -0
- policynim-0.1.0/policies/security/secrets-redaction-and-handling.md +46 -0
- policynim-0.1.0/policies/security/session-lifetime-and-token-boundaries.md +41 -0
- policynim-0.1.0/pyproject.toml +98 -0
- policynim-0.1.0/pyrightconfig.json +25 -0
- policynim-0.1.0/railway.toml +10 -0
- policynim-0.1.0/scripts/install.ps1 +156 -0
- policynim-0.1.0/scripts/install.sh +216 -0
- policynim-0.1.0/src/policynim/__init__.py +1 -0
- policynim-0.1.0/src/policynim/assets/beta/beta-page.js +58 -0
- policynim-0.1.0/src/policynim/assets/beta/beta-theme-init.js +16 -0
- policynim-0.1.0/src/policynim/assets/beta/beta.css +687 -0
- policynim-0.1.0/src/policynim/assets/beta/policynim_darkmode.jpg +0 -0
- policynim-0.1.0/src/policynim/assets/beta/policynim_lightmode.png +0 -0
- policynim-0.1.0/src/policynim/config_discovery.py +309 -0
- policynim-0.1.0/src/policynim/contracts.py +157 -0
- policynim-0.1.0/src/policynim/errors.py +43 -0
- policynim-0.1.0/src/policynim/ingest/__init__.py +24 -0
- policynim-0.1.0/src/policynim/ingest/chunking.py +307 -0
- policynim-0.1.0/src/policynim/ingest/loader.py +113 -0
- policynim-0.1.0/src/policynim/ingest/parser.py +940 -0
- policynim-0.1.0/src/policynim/interfaces/__init__.py +1 -0
- policynim-0.1.0/src/policynim/interfaces/cli.py +1009 -0
- policynim-0.1.0/src/policynim/interfaces/mcp.py +1034 -0
- policynim-0.1.0/src/policynim/providers/__init__.py +25 -0
- policynim-0.1.0/src/policynim/providers/nvidia.py +1135 -0
- policynim-0.1.0/src/policynim/providers/nvidia_eval.py +141 -0
- policynim-0.1.0/src/policynim/providers/nvidia_guardrails.py +383 -0
- policynim-0.1.0/src/policynim/runtime_paths.py +163 -0
- policynim-0.1.0/src/policynim/services/__init__.py +71 -0
- policynim-0.1.0/src/policynim/services/beta_auth.py +351 -0
- policynim-0.1.0/src/policynim/services/compiler.py +264 -0
- policynim-0.1.0/src/policynim/services/conformance.py +323 -0
- policynim-0.1.0/src/policynim/services/dump.py +31 -0
- policynim-0.1.0/src/policynim/services/eval.py +1763 -0
- policynim-0.1.0/src/policynim/services/evidence_trace.py +353 -0
- policynim-0.1.0/src/policynim/services/health.py +202 -0
- policynim-0.1.0/src/policynim/services/ingest.py +217 -0
- policynim-0.1.0/src/policynim/services/preflight.py +406 -0
- policynim-0.1.0/src/policynim/services/regeneration.py +653 -0
- policynim-0.1.0/src/policynim/services/router.py +362 -0
- policynim-0.1.0/src/policynim/services/runtime_decision.py +428 -0
- policynim-0.1.0/src/policynim/services/runtime_evidence_report.py +156 -0
- policynim-0.1.0/src/policynim/services/runtime_execution.py +575 -0
- policynim-0.1.0/src/policynim/services/search.py +110 -0
- policynim-0.1.0/src/policynim/settings.py +383 -0
- policynim-0.1.0/src/policynim/storage/__init__.py +7 -0
- policynim-0.1.0/src/policynim/storage/auth_store.py +628 -0
- policynim-0.1.0/src/policynim/storage/lancedb.py +188 -0
- policynim-0.1.0/src/policynim/storage/runtime_evidence.py +211 -0
- policynim-0.1.0/src/policynim/templates/beta/dashboard.html.j2 +130 -0
- policynim-0.1.0/src/policynim/templates/beta/landing.html.j2 +85 -0
- policynim-0.1.0/src/policynim/templates/beta/page.html.j2 +17 -0
- policynim-0.1.0/src/policynim/templates/beta/partials/command_card.html.j2 +19 -0
- policynim-0.1.0/src/policynim/templates/beta/partials/logo.html.j2 +18 -0
- policynim-0.1.0/src/policynim/templates/beta/partials/new_key_panel.html.j2 +24 -0
- policynim-0.1.0/src/policynim/templates/beta/partials/notice.html.j2 +4 -0
- policynim-0.1.0/src/policynim/templates/beta/partials/theme_toggle.html.j2 +10 -0
- policynim-0.1.0/src/policynim/templates/nvidia_guardrails/preflight_output/config.yml +31 -0
- policynim-0.1.0/src/policynim/templates/nvidia_guardrails/preflight_output/rails.co +2 -0
- policynim-0.1.0/src/policynim/types.py +1114 -0
- policynim-0.1.0/tests/README.md +88 -0
- policynim-0.1.0/tests/test_auth_store.py +232 -0
- policynim-0.1.0/tests/test_beta_auth.py +149 -0
- policynim-0.1.0/tests/test_beta_portal.py +340 -0
- policynim-0.1.0/tests/test_ci_workflows.py +113 -0
- policynim-0.1.0/tests/test_cli.py +2665 -0
- policynim-0.1.0/tests/test_compiler_service.py +303 -0
- policynim-0.1.0/tests/test_docker_build_live.py +149 -0
- policynim-0.1.0/tests/test_dockerfile_contract.py +58 -0
- policynim-0.1.0/tests/test_docs_hosted_onboarding.py +140 -0
- policynim-0.1.0/tests/test_docs_runtime_workflows.py +171 -0
- policynim-0.1.0/tests/test_eval_service.py +515 -0
- policynim-0.1.0/tests/test_health_service.py +387 -0
- policynim-0.1.0/tests/test_hosted_mcp_live.py +130 -0
- policynim-0.1.0/tests/test_ingest.py +431 -0
- policynim-0.1.0/tests/test_ingest_service.py +280 -0
- policynim-0.1.0/tests/test_installer_contract.py +234 -0
- policynim-0.1.0/tests/test_lancedb.py +68 -0
- policynim-0.1.0/tests/test_mcp.py +1030 -0
- policynim-0.1.0/tests/test_nemo_agent_toolkit_policy_conformance.py +112 -0
- policynim-0.1.0/tests/test_nemo_evaluator_policy_conformance.py +110 -0
- policynim-0.1.0/tests/test_nemo_guardrails_preflight_generator.py +388 -0
- policynim-0.1.0/tests/test_nvidia_embedder.py +114 -0
- policynim-0.1.0/tests/test_nvidia_generator.py +240 -0
- policynim-0.1.0/tests/test_nvidia_live.py +96 -0
- policynim-0.1.0/tests/test_nvidia_policy_compiler.py +324 -0
- policynim-0.1.0/tests/test_nvidia_policy_conformance.py +280 -0
- policynim-0.1.0/tests/test_nvidia_reranker.py +274 -0
- policynim-0.1.0/tests/test_package_release.py +45 -0
- policynim-0.1.0/tests/test_policy_conformance_service.py +272 -0
- policynim-0.1.0/tests/test_policy_evidence_trace_service.py +285 -0
- policynim-0.1.0/tests/test_policy_regeneration_service.py +542 -0
- policynim-0.1.0/tests/test_preflight_service.py +756 -0
- policynim-0.1.0/tests/test_router_service.py +294 -0
- policynim-0.1.0/tests/test_runtime_decision_service.py +595 -0
- policynim-0.1.0/tests/test_runtime_evidence_report_service.py +449 -0
- policynim-0.1.0/tests/test_runtime_evidence_store.py +272 -0
- policynim-0.1.0/tests/test_runtime_execution_service.py +560 -0
- policynim-0.1.0/tests/test_runtime_paths.py +281 -0
- policynim-0.1.0/tests/test_search_service.py +264 -0
- policynim-0.1.0/tests/test_service_factories.py +308 -0
- policynim-0.1.0/tests/test_settings_and_types.py +917 -0
- policynim-0.1.0/uv.lock +4459 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Local development defaults.
|
|
2
|
+
# Copy this file to .env for local CLI, eval, and stdio MCP work.
|
|
3
|
+
NVIDIA_API_KEY=
|
|
4
|
+
POLICYNIM_ENV=development
|
|
5
|
+
POLICYNIM_LANCEDB_URI=data/lancedb
|
|
6
|
+
POLICYNIM_LANCEDB_TABLE=policy_chunks
|
|
7
|
+
POLICYNIM_RUNTIME_RULES_ARTIFACT_PATH=data/runtime/runtime_rules.json
|
|
8
|
+
POLICYNIM_RUNTIME_EVIDENCE_DB_PATH=data/runtime/runtime_evidence.sqlite3
|
|
9
|
+
POLICYNIM_RUNTIME_SHELL_TIMEOUT_SECONDS=300
|
|
10
|
+
POLICYNIM_EVAL_WORKSPACE_DIR=data/evals/workspace
|
|
11
|
+
POLICYNIM_DEFAULT_TOP_K=5
|
|
12
|
+
POLICYNIM_EMBED_BATCH_SIZE=32
|
|
13
|
+
POLICYNIM_NVIDIA_CHAT_MODEL=nvidia/llama-3.3-nemotron-super-49b-v1.5
|
|
14
|
+
POLICYNIM_NVIDIA_EMBED_MODEL=nvidia/llama-nemotron-embed-1b-v2
|
|
15
|
+
POLICYNIM_NVIDIA_RERANK_MODEL=nvidia/llama-nemotron-rerank-1b-v2
|
|
16
|
+
POLICYNIM_NVIDIA_BASE_URL=https://integrate.api.nvidia.com/v1
|
|
17
|
+
POLICYNIM_NVIDIA_RETRIEVAL_BASE_URL=https://ai.api.nvidia.com/v1/retrieval
|
|
18
|
+
POLICYNIM_NVIDIA_TIMEOUT_SECONDS=30
|
|
19
|
+
POLICYNIM_NVIDIA_MAX_RETRIES=2
|
|
20
|
+
POLICYNIM_MCP_HOST=127.0.0.1
|
|
21
|
+
POLICYNIM_MCP_PORT=6000
|
|
22
|
+
POLICYNIM_MCP_REQUIRE_AUTH=false
|
|
23
|
+
POLICYNIM_EVAL_UI_PORT=8001
|
|
24
|
+
|
|
25
|
+
# Optional hosted-only settings:
|
|
26
|
+
# POLICYNIM_MCP_BEARER_TOKENS=token-a,token-b
|
|
27
|
+
# POLICYNIM_MCP_PUBLIC_BASE_URL=https://your-host
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Backward-compatible local-development example.
|
|
2
|
+
# Prefer copying .env.development.example for local work and
|
|
3
|
+
# .env.production.example when preparing hosted Railway variables.
|
|
4
|
+
NVIDIA_API_KEY=
|
|
5
|
+
POLICYNIM_ENV=development
|
|
6
|
+
POLICYNIM_LANCEDB_URI=data/lancedb
|
|
7
|
+
POLICYNIM_LANCEDB_TABLE=policy_chunks
|
|
8
|
+
POLICYNIM_RUNTIME_RULES_ARTIFACT_PATH=data/runtime/runtime_rules.json
|
|
9
|
+
POLICYNIM_RUNTIME_EVIDENCE_DB_PATH=data/runtime/runtime_evidence.sqlite3
|
|
10
|
+
POLICYNIM_RUNTIME_SHELL_TIMEOUT_SECONDS=300
|
|
11
|
+
POLICYNIM_EVAL_WORKSPACE_DIR=data/evals/workspace
|
|
12
|
+
POLICYNIM_DEFAULT_TOP_K=5
|
|
13
|
+
POLICYNIM_EMBED_BATCH_SIZE=32
|
|
14
|
+
POLICYNIM_NVIDIA_CHAT_MODEL=nvidia/llama-3.3-nemotron-super-49b-v1.5
|
|
15
|
+
POLICYNIM_NVIDIA_EMBED_MODEL=nvidia/llama-nemotron-embed-1b-v2
|
|
16
|
+
POLICYNIM_NVIDIA_RERANK_MODEL=nvidia/llama-nemotron-rerank-1b-v2
|
|
17
|
+
POLICYNIM_NVIDIA_BASE_URL=https://integrate.api.nvidia.com/v1
|
|
18
|
+
POLICYNIM_NVIDIA_RETRIEVAL_BASE_URL=https://ai.api.nvidia.com/v1/retrieval
|
|
19
|
+
POLICYNIM_NVIDIA_TIMEOUT_SECONDS=30
|
|
20
|
+
POLICYNIM_NVIDIA_MAX_RETRIES=2
|
|
21
|
+
POLICYNIM_MCP_HOST=127.0.0.1
|
|
22
|
+
POLICYNIM_MCP_PORT=6000
|
|
23
|
+
POLICYNIM_MCP_REQUIRE_AUTH=false
|
|
24
|
+
POLICYNIM_EVAL_UI_PORT=8001
|
|
25
|
+
|
|
26
|
+
# Optional hosted-only settings:
|
|
27
|
+
# POLICYNIM_MCP_BEARER_TOKENS=token-a,token-b
|
|
28
|
+
# POLICYNIM_MCP_PUBLIC_BASE_URL=https://your-host
|
|
29
|
+
# POLICYNIM_BETA_SIGNUP_ENABLED=true
|
|
30
|
+
# POLICYNIM_BETA_AUTH_DB_PATH=data/runtime/auth.sqlite3
|
|
31
|
+
# POLICYNIM_BETA_SESSION_SECRET=replace-with-a-random-secret
|
|
32
|
+
# POLICYNIM_BETA_GITHUB_CLIENT_ID=github-oauth-client-id
|
|
33
|
+
# POLICYNIM_BETA_GITHUB_CLIENT_SECRET=github-oauth-client-secret
|
|
34
|
+
# POLICYNIM_BETA_DAILY_REQUEST_QUOTA=500
|
|
35
|
+
# POLICYNIM_BETA_AUTH_RATE_LIMIT_MAX_ATTEMPTS=20
|
|
36
|
+
# POLICYNIM_BETA_AUTH_RATE_LIMIT_WINDOW_SECONDS=900
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# Hosted production defaults for Docker and Railway.
|
|
2
|
+
# Railway injects PORT. Leave POLICYNIM_MCP_PORT unset unless you need an override.
|
|
3
|
+
# Required at Docker build time for baked ingest and at runtime for live hosted retrieval.
|
|
4
|
+
NVIDIA_API_KEY=
|
|
5
|
+
POLICYNIM_ENV=production
|
|
6
|
+
POLICYNIM_LANCEDB_URI=/app/data/lancedb-baked
|
|
7
|
+
POLICYNIM_LANCEDB_TABLE=policy_chunks
|
|
8
|
+
# Keep the compiled rules artifact with the baked/runtime data layout.
|
|
9
|
+
POLICYNIM_RUNTIME_RULES_ARTIFACT_PATH=/app/data/runtime/runtime_rules.json
|
|
10
|
+
# Keep mutable runtime evidence on the writable state volume.
|
|
11
|
+
POLICYNIM_RUNTIME_EVIDENCE_DB_PATH=/app/state/runtime_evidence.sqlite3
|
|
12
|
+
POLICYNIM_RUNTIME_SHELL_TIMEOUT_SECONDS=300
|
|
13
|
+
POLICYNIM_DEFAULT_TOP_K=5
|
|
14
|
+
POLICYNIM_EMBED_BATCH_SIZE=32
|
|
15
|
+
POLICYNIM_NVIDIA_CHAT_MODEL=nvidia/llama-3.3-nemotron-super-49b-v1.5
|
|
16
|
+
POLICYNIM_NVIDIA_EMBED_MODEL=nvidia/llama-nemotron-embed-1b-v2
|
|
17
|
+
POLICYNIM_NVIDIA_RERANK_MODEL=nvidia/llama-nemotron-rerank-1b-v2
|
|
18
|
+
POLICYNIM_NVIDIA_BASE_URL=https://integrate.api.nvidia.com/v1
|
|
19
|
+
POLICYNIM_NVIDIA_RETRIEVAL_BASE_URL=https://ai.api.nvidia.com/v1/retrieval
|
|
20
|
+
POLICYNIM_NVIDIA_TIMEOUT_SECONDS=30
|
|
21
|
+
POLICYNIM_NVIDIA_MAX_RETRIES=2
|
|
22
|
+
POLICYNIM_MCP_HOST=0.0.0.0
|
|
23
|
+
POLICYNIM_MCP_REQUIRE_AUTH=false
|
|
24
|
+
POLICYNIM_BETA_SIGNUP_ENABLED=false
|
|
25
|
+
POLICYNIM_BETA_AUTH_DB_PATH=/app/state/auth.sqlite3
|
|
26
|
+
POLICYNIM_BETA_DAILY_REQUEST_QUOTA=500
|
|
27
|
+
POLICYNIM_BETA_AUTH_RATE_LIMIT_MAX_ATTEMPTS=20
|
|
28
|
+
POLICYNIM_BETA_AUTH_RATE_LIMIT_WINDOW_SECONDS=900
|
|
29
|
+
|
|
30
|
+
# Optional hosted auth after you generate a public domain:
|
|
31
|
+
# POLICYNIM_MCP_BEARER_TOKENS=token-a,token-b
|
|
32
|
+
# POLICYNIM_MCP_PUBLIC_BASE_URL=https://your-host
|
|
33
|
+
# POLICYNIM_BETA_SESSION_SECRET=replace-with-a-random-secret
|
|
34
|
+
# POLICYNIM_BETA_GITHUB_CLIENT_ID=github-oauth-client-id
|
|
35
|
+
# POLICYNIM_BETA_GITHUB_CLIENT_SECRET=github-oauth-client-secret
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
push:
|
|
6
|
+
branches:
|
|
7
|
+
- main
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: read
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
lint:
|
|
14
|
+
runs-on: ubuntu-24.04
|
|
15
|
+
steps:
|
|
16
|
+
- name: Check out repository
|
|
17
|
+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
18
|
+
|
|
19
|
+
- name: Install uv
|
|
20
|
+
uses: astral-sh/setup-uv@d0d8abe699bfb85fec6de9f7adb5ae17292296ff # v6
|
|
21
|
+
|
|
22
|
+
- name: Set up Python 3.11
|
|
23
|
+
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
|
|
24
|
+
with:
|
|
25
|
+
python-version: "3.11"
|
|
26
|
+
|
|
27
|
+
- name: Sync dependencies
|
|
28
|
+
run: uv sync --group test --group dev
|
|
29
|
+
|
|
30
|
+
- name: Run Ruff
|
|
31
|
+
run: uv run ruff check
|
|
32
|
+
|
|
33
|
+
- name: Run Pyright
|
|
34
|
+
run: uv run pyright
|
|
35
|
+
|
|
36
|
+
test:
|
|
37
|
+
runs-on: ubuntu-24.04
|
|
38
|
+
steps:
|
|
39
|
+
- name: Check out repository
|
|
40
|
+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
41
|
+
|
|
42
|
+
- name: Install uv
|
|
43
|
+
uses: astral-sh/setup-uv@d0d8abe699bfb85fec6de9f7adb5ae17292296ff # v6
|
|
44
|
+
|
|
45
|
+
- name: Set up Python 3.11
|
|
46
|
+
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
|
|
47
|
+
with:
|
|
48
|
+
python-version: "3.11"
|
|
49
|
+
|
|
50
|
+
- name: Sync dependencies
|
|
51
|
+
run: uv sync --group test --group dev
|
|
52
|
+
|
|
53
|
+
- name: Run offline pytest
|
|
54
|
+
run: uv run pytest -q -m "not live and not docker_live"
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
name: Hosted Beta Smoke
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
|
|
6
|
+
permissions:
|
|
7
|
+
contents: read
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
hosted-smoke:
|
|
11
|
+
runs-on: ubuntu-24.04
|
|
12
|
+
env:
|
|
13
|
+
POLICYNIM_BETA_MCP_URL: ${{ secrets.POLICYNIM_BETA_MCP_URL }}
|
|
14
|
+
POLICYNIM_BETA_MCP_TOKEN: ${{ secrets.POLICYNIM_BETA_MCP_TOKEN }}
|
|
15
|
+
steps:
|
|
16
|
+
- name: Check out repository
|
|
17
|
+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
18
|
+
|
|
19
|
+
- name: Install uv
|
|
20
|
+
uses: astral-sh/setup-uv@d0d8abe699bfb85fec6de9f7adb5ae17292296ff # v6
|
|
21
|
+
|
|
22
|
+
- name: Set up Python 3.11
|
|
23
|
+
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
|
|
24
|
+
with:
|
|
25
|
+
python-version: "3.11"
|
|
26
|
+
|
|
27
|
+
- name: Validate hosted smoke secrets
|
|
28
|
+
run: |
|
|
29
|
+
test -n "$POLICYNIM_BETA_MCP_URL" || {
|
|
30
|
+
echo "POLICYNIM_BETA_MCP_URL secret is required for hosted smoke tests."
|
|
31
|
+
exit 1
|
|
32
|
+
}
|
|
33
|
+
test -n "$POLICYNIM_BETA_MCP_TOKEN" || {
|
|
34
|
+
echo "POLICYNIM_BETA_MCP_TOKEN secret is required for hosted smoke tests."
|
|
35
|
+
exit 1
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
- name: Sync dependencies
|
|
39
|
+
run: uv sync --group test --group dev
|
|
40
|
+
|
|
41
|
+
- name: Run hosted live smoke
|
|
42
|
+
run: uv run --group test pytest -q -m live tests/test_hosted_mcp_live.py
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
inputs:
|
|
6
|
+
version:
|
|
7
|
+
description: "Release version or tag, for example 0.1.0 or v0.1.0."
|
|
8
|
+
required: false
|
|
9
|
+
type: string
|
|
10
|
+
publish_pypi:
|
|
11
|
+
description: "Publish the built Python distribution to PyPI using trusted publishing."
|
|
12
|
+
required: false
|
|
13
|
+
default: false
|
|
14
|
+
type: boolean
|
|
15
|
+
push:
|
|
16
|
+
tags:
|
|
17
|
+
- "v*.*.*"
|
|
18
|
+
|
|
19
|
+
permissions:
|
|
20
|
+
contents: read
|
|
21
|
+
|
|
22
|
+
env:
|
|
23
|
+
PYTHON_VERSION: "3.11"
|
|
24
|
+
|
|
25
|
+
jobs:
|
|
26
|
+
verify:
|
|
27
|
+
runs-on: ubuntu-24.04
|
|
28
|
+
steps:
|
|
29
|
+
- name: Check out repository
|
|
30
|
+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
31
|
+
|
|
32
|
+
- name: Install uv
|
|
33
|
+
uses: astral-sh/setup-uv@d0d8abe699bfb85fec6de9f7adb5ae17292296ff # v6
|
|
34
|
+
|
|
35
|
+
- name: Set up Python
|
|
36
|
+
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
|
|
37
|
+
with:
|
|
38
|
+
python-version: ${{ env.PYTHON_VERSION }}
|
|
39
|
+
|
|
40
|
+
- name: Sync dependencies
|
|
41
|
+
run: uv sync --group test --group dev
|
|
42
|
+
|
|
43
|
+
- name: Check lockfile
|
|
44
|
+
run: uv lock --check
|
|
45
|
+
|
|
46
|
+
- name: Run Ruff
|
|
47
|
+
run: uv run ruff check .
|
|
48
|
+
|
|
49
|
+
- name: Run Pyright
|
|
50
|
+
run: uv run pyright
|
|
51
|
+
|
|
52
|
+
- name: Run offline pytest
|
|
53
|
+
run: uv run pytest -q -m "not live and not docker_live"
|
|
54
|
+
|
|
55
|
+
- name: Build Python distribution
|
|
56
|
+
run: uv build --out-dir dist
|
|
57
|
+
|
|
58
|
+
- name: Upload Python distribution
|
|
59
|
+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
|
60
|
+
with:
|
|
61
|
+
name: python-dist
|
|
62
|
+
path: dist/*
|
|
63
|
+
if-no-files-found: error
|
|
64
|
+
|
|
65
|
+
wheel-smoke:
|
|
66
|
+
runs-on: ubuntu-24.04
|
|
67
|
+
needs: verify
|
|
68
|
+
steps:
|
|
69
|
+
- name: Download Python distribution
|
|
70
|
+
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
|
|
71
|
+
with:
|
|
72
|
+
name: python-dist
|
|
73
|
+
path: dist
|
|
74
|
+
|
|
75
|
+
- name: Set up Python
|
|
76
|
+
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
|
|
77
|
+
with:
|
|
78
|
+
python-version: ${{ env.PYTHON_VERSION }}
|
|
79
|
+
|
|
80
|
+
- name: Smoke install built wheel
|
|
81
|
+
run: |
|
|
82
|
+
python -m venv /tmp/policynim-wheel-smoke
|
|
83
|
+
/tmp/policynim-wheel-smoke/bin/python -m pip install dist/*.whl
|
|
84
|
+
/tmp/policynim-wheel-smoke/bin/policynim --help
|
|
85
|
+
/tmp/policynim-wheel-smoke/bin/policynim --version
|
|
86
|
+
|
|
87
|
+
standalone-build:
|
|
88
|
+
needs: verify
|
|
89
|
+
strategy:
|
|
90
|
+
fail-fast: false
|
|
91
|
+
matrix:
|
|
92
|
+
include:
|
|
93
|
+
- os: ubuntu-24.04
|
|
94
|
+
platform: linux-amd64
|
|
95
|
+
archive: tar
|
|
96
|
+
- os: macos-13
|
|
97
|
+
platform: darwin-amd64
|
|
98
|
+
archive: tar
|
|
99
|
+
- os: macos-14
|
|
100
|
+
platform: darwin-arm64
|
|
101
|
+
archive: tar
|
|
102
|
+
- os: windows-2022
|
|
103
|
+
platform: windows-amd64
|
|
104
|
+
archive: zip
|
|
105
|
+
runs-on: ${{ matrix.os }}
|
|
106
|
+
steps:
|
|
107
|
+
- name: Check out repository
|
|
108
|
+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
109
|
+
|
|
110
|
+
- name: Install uv
|
|
111
|
+
uses: astral-sh/setup-uv@d0d8abe699bfb85fec6de9f7adb5ae17292296ff # v6
|
|
112
|
+
|
|
113
|
+
- name: Set up Python
|
|
114
|
+
uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5
|
|
115
|
+
with:
|
|
116
|
+
python-version: ${{ env.PYTHON_VERSION }}
|
|
117
|
+
|
|
118
|
+
- name: Resolve release tag
|
|
119
|
+
env:
|
|
120
|
+
REQUESTED_VERSION: ${{ inputs.version }}
|
|
121
|
+
shell: bash
|
|
122
|
+
run: |
|
|
123
|
+
python - <<'PY' >> "$GITHUB_ENV"
|
|
124
|
+
import os
|
|
125
|
+
import tomllib
|
|
126
|
+
from pathlib import Path
|
|
127
|
+
|
|
128
|
+
project = tomllib.loads(Path("pyproject.toml").read_text(encoding="utf-8"))
|
|
129
|
+
project_version = project["project"]["version"]
|
|
130
|
+
if os.environ.get("GITHUB_REF_TYPE") == "tag":
|
|
131
|
+
tag = os.environ["GITHUB_REF_NAME"]
|
|
132
|
+
requested_version = tag.removeprefix("v")
|
|
133
|
+
else:
|
|
134
|
+
requested = os.environ.get("REQUESTED_VERSION", "").strip()
|
|
135
|
+
if requested:
|
|
136
|
+
requested_version = requested.removeprefix("v")
|
|
137
|
+
tag = f"v{requested_version}"
|
|
138
|
+
else:
|
|
139
|
+
requested_version = project_version
|
|
140
|
+
tag = f"v{project_version}"
|
|
141
|
+
if requested_version != project_version:
|
|
142
|
+
raise SystemExit(
|
|
143
|
+
"Release version mismatch: "
|
|
144
|
+
f"requested {requested_version}, pyproject.toml has {project_version}."
|
|
145
|
+
)
|
|
146
|
+
print(f"RELEASE_TAG={tag}")
|
|
147
|
+
PY
|
|
148
|
+
|
|
149
|
+
- name: Sync release dependencies
|
|
150
|
+
run: uv sync --group release
|
|
151
|
+
|
|
152
|
+
- name: Build standalone bundle
|
|
153
|
+
run: uv run --group release pyinstaller --clean --noconfirm packaging/pyinstaller.spec
|
|
154
|
+
|
|
155
|
+
- name: Smoke standalone bundle
|
|
156
|
+
shell: bash
|
|
157
|
+
run: |
|
|
158
|
+
if [ "${{ matrix.platform }}" = "windows-amd64" ]; then
|
|
159
|
+
dist/policynim/policynim.exe --help
|
|
160
|
+
dist/policynim/policynim.exe --version
|
|
161
|
+
else
|
|
162
|
+
dist/policynim/policynim --help
|
|
163
|
+
dist/policynim/policynim --version
|
|
164
|
+
fi
|
|
165
|
+
|
|
166
|
+
- name: Archive Unix standalone bundle
|
|
167
|
+
if: matrix.archive == 'tar'
|
|
168
|
+
shell: bash
|
|
169
|
+
run: |
|
|
170
|
+
mkdir -p artifacts
|
|
171
|
+
case "${{ matrix.platform }}" in
|
|
172
|
+
linux-amd64) ASSET_NAME="policynim-${RELEASE_TAG}-linux-amd64.tar.gz" ;;
|
|
173
|
+
darwin-amd64) ASSET_NAME="policynim-${RELEASE_TAG}-darwin-amd64.tar.gz" ;;
|
|
174
|
+
darwin-arm64) ASSET_NAME="policynim-${RELEASE_TAG}-darwin-arm64.tar.gz" ;;
|
|
175
|
+
*) echo "Unsupported release platform: ${{ matrix.platform }}" >&2; exit 1 ;;
|
|
176
|
+
esac
|
|
177
|
+
tar -C dist -czf "artifacts/${ASSET_NAME}" policynim
|
|
178
|
+
|
|
179
|
+
- name: Archive Windows standalone bundle
|
|
180
|
+
if: matrix.archive == 'zip'
|
|
181
|
+
shell: pwsh
|
|
182
|
+
run: |
|
|
183
|
+
New-Item -ItemType Directory -Force -Path artifacts | Out-Null
|
|
184
|
+
$RELEASE_TAG = $env:RELEASE_TAG
|
|
185
|
+
$AssetName = "policynim-${RELEASE_TAG}-windows-amd64.zip"
|
|
186
|
+
Compress-Archive -Path "dist/policynim/*" -DestinationPath "artifacts/$AssetName" -Force
|
|
187
|
+
|
|
188
|
+
- name: Upload standalone bundle
|
|
189
|
+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
|
|
190
|
+
with:
|
|
191
|
+
name: standalone-${{ matrix.platform }}
|
|
192
|
+
path: artifacts/*
|
|
193
|
+
if-no-files-found: error
|
|
194
|
+
|
|
195
|
+
publish-github-release:
|
|
196
|
+
runs-on: ubuntu-24.04
|
|
197
|
+
needs:
|
|
198
|
+
- verify
|
|
199
|
+
- wheel-smoke
|
|
200
|
+
- standalone-build
|
|
201
|
+
permissions:
|
|
202
|
+
contents: write
|
|
203
|
+
steps:
|
|
204
|
+
- name: Check out repository
|
|
205
|
+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
206
|
+
|
|
207
|
+
- name: Download release artifacts
|
|
208
|
+
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
|
|
209
|
+
with:
|
|
210
|
+
path: release-downloads
|
|
211
|
+
|
|
212
|
+
- name: Resolve release tag
|
|
213
|
+
env:
|
|
214
|
+
REQUESTED_VERSION: ${{ inputs.version }}
|
|
215
|
+
run: |
|
|
216
|
+
python - <<'PY' >> "$GITHUB_ENV"
|
|
217
|
+
import os
|
|
218
|
+
import tomllib
|
|
219
|
+
from pathlib import Path
|
|
220
|
+
|
|
221
|
+
project = tomllib.loads(Path("pyproject.toml").read_text(encoding="utf-8"))
|
|
222
|
+
project_version = project["project"]["version"]
|
|
223
|
+
if os.environ.get("GITHUB_REF_TYPE") == "tag":
|
|
224
|
+
tag = os.environ["GITHUB_REF_NAME"]
|
|
225
|
+
requested_version = tag.removeprefix("v")
|
|
226
|
+
else:
|
|
227
|
+
requested = os.environ.get("REQUESTED_VERSION", "").strip()
|
|
228
|
+
if requested:
|
|
229
|
+
requested_version = requested.removeprefix("v")
|
|
230
|
+
tag = f"v{requested_version}"
|
|
231
|
+
else:
|
|
232
|
+
requested_version = project_version
|
|
233
|
+
tag = f"v{project_version}"
|
|
234
|
+
if requested_version != project_version:
|
|
235
|
+
raise SystemExit(
|
|
236
|
+
"Release version mismatch: "
|
|
237
|
+
f"requested {requested_version}, pyproject.toml has {project_version}."
|
|
238
|
+
)
|
|
239
|
+
print(f"RELEASE_TAG={tag}")
|
|
240
|
+
PY
|
|
241
|
+
|
|
242
|
+
- name: Prepare release assets
|
|
243
|
+
run: |
|
|
244
|
+
mkdir -p release-assets
|
|
245
|
+
find release-downloads -type f -exec cp {} release-assets/ \;
|
|
246
|
+
cp scripts/install.sh release-assets/install.sh
|
|
247
|
+
cp scripts/install.ps1 release-assets/install.ps1
|
|
248
|
+
(
|
|
249
|
+
cd release-assets
|
|
250
|
+
sha256sum * > SHA256SUMS
|
|
251
|
+
)
|
|
252
|
+
cat > release-notes.md <<'EOF'
|
|
253
|
+
PolicyNIM release artifacts:
|
|
254
|
+
|
|
255
|
+
- Python wheel and source distribution for `pipx install policynim`
|
|
256
|
+
- Standalone CLI bundles for Linux, macOS, and Windows
|
|
257
|
+
- Unix and PowerShell installer scripts
|
|
258
|
+
- SHA256SUMS for release asset verification
|
|
259
|
+
EOF
|
|
260
|
+
|
|
261
|
+
- name: Create draft GitHub release
|
|
262
|
+
env:
|
|
263
|
+
GH_TOKEN: ${{ github.token }}
|
|
264
|
+
run: |
|
|
265
|
+
gh release create "$RELEASE_TAG" \
|
|
266
|
+
--draft \
|
|
267
|
+
--target "$GITHUB_SHA" \
|
|
268
|
+
--title "$RELEASE_TAG" \
|
|
269
|
+
--notes-file release-notes.md \
|
|
270
|
+
release-assets/*
|
|
271
|
+
|
|
272
|
+
publish-pypi:
|
|
273
|
+
runs-on: ubuntu-24.04
|
|
274
|
+
needs:
|
|
275
|
+
- verify
|
|
276
|
+
- wheel-smoke
|
|
277
|
+
if: startsWith(github.ref, 'refs/tags/v') || (github.event_name == 'workflow_dispatch' && inputs.publish_pypi)
|
|
278
|
+
environment: pypi
|
|
279
|
+
permissions:
|
|
280
|
+
id-token: write
|
|
281
|
+
contents: read
|
|
282
|
+
steps:
|
|
283
|
+
- name: Download Python distribution
|
|
284
|
+
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
|
|
285
|
+
with:
|
|
286
|
+
name: python-dist
|
|
287
|
+
path: dist
|
|
288
|
+
|
|
289
|
+
- name: Publish to PyPI
|
|
290
|
+
# This Docker-based action publishes GHCR images under release tags, not commit SHA tags.
|
|
291
|
+
uses: pypa/gh-action-pypi-publish@v1.14.0 # 6733eb7d741f0b11ec6a39b58540dab7590f9b7d
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
.DS_Store
|
|
2
|
+
.plan/
|
|
3
|
+
.env
|
|
4
|
+
.env.*
|
|
5
|
+
!.env.example
|
|
6
|
+
!.env.development.example
|
|
7
|
+
!.env.production.example
|
|
8
|
+
.mypy_cache/
|
|
9
|
+
.pytest_cache/
|
|
10
|
+
.ruff_cache/
|
|
11
|
+
.venv/
|
|
12
|
+
.vscode/
|
|
13
|
+
.voice/
|
|
14
|
+
__pycache__/
|
|
15
|
+
build/
|
|
16
|
+
data/
|
|
17
|
+
dist/
|
|
18
|
+
*.pyc
|
|
19
|
+
.threadloop/state/
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: local
|
|
3
|
+
hooks:
|
|
4
|
+
- id: ruff-check
|
|
5
|
+
name: ruff check
|
|
6
|
+
entry: uv run --group dev ruff check --fix
|
|
7
|
+
language: system
|
|
8
|
+
types: [python]
|
|
9
|
+
- id: ruff-format
|
|
10
|
+
name: ruff format
|
|
11
|
+
entry: uv run --group dev ruff format
|
|
12
|
+
language: system
|
|
13
|
+
types: [python]
|
|
14
|
+
- id: pyright
|
|
15
|
+
name: pyright
|
|
16
|
+
entry: uv run --group dev pyright
|
|
17
|
+
language: system
|
|
18
|
+
pass_filenames: false
|
|
19
|
+
types: [python]
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# syntax=docker/dockerfile:1.7
|
|
2
|
+
ARG PYTHON_BASE_IMAGE=python:3.11.15-slim-trixie@sha256:9358444059ed78e2975ada2c189f1c1a3144a5dab6f35bff8c981afb38946634
|
|
3
|
+
|
|
4
|
+
FROM ${PYTHON_BASE_IMAGE} AS builder
|
|
5
|
+
|
|
6
|
+
ENV PYTHONDONTWRITEBYTECODE=1 \
|
|
7
|
+
PYTHONUNBUFFERED=1 \
|
|
8
|
+
POLICYNIM_LANCEDB_URI=/app/data/lancedb-baked
|
|
9
|
+
|
|
10
|
+
WORKDIR /app
|
|
11
|
+
|
|
12
|
+
RUN pip install --no-cache-dir uv==0.7.12
|
|
13
|
+
|
|
14
|
+
COPY pyproject.toml uv.lock README.md LICENSE ./
|
|
15
|
+
COPY src ./src
|
|
16
|
+
COPY policies ./policies
|
|
17
|
+
COPY evals ./evals
|
|
18
|
+
|
|
19
|
+
RUN uv sync --frozen
|
|
20
|
+
RUN --mount=type=secret,id=nvidia_api_key,required=true \
|
|
21
|
+
sh -c 'NVIDIA_API_KEY="$(cat /run/secrets/nvidia_api_key)" uv run policynim ingest'
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
FROM ${PYTHON_BASE_IMAGE} AS runtime
|
|
25
|
+
|
|
26
|
+
ENV PYTHONDONTWRITEBYTECODE=1 \
|
|
27
|
+
PYTHONUNBUFFERED=1 \
|
|
28
|
+
POLICYNIM_LANCEDB_URI=/app/data/lancedb-baked \
|
|
29
|
+
POLICYNIM_MCP_HOST=0.0.0.0 \
|
|
30
|
+
PATH=/app/.venv/bin:$PATH
|
|
31
|
+
|
|
32
|
+
WORKDIR /app
|
|
33
|
+
|
|
34
|
+
COPY --from=builder /app/.venv /app/.venv
|
|
35
|
+
COPY --from=builder /app/src /app/src
|
|
36
|
+
COPY --from=builder /app/policies /app/policies
|
|
37
|
+
COPY --from=builder /app/evals /app/evals
|
|
38
|
+
COPY --from=builder /app/pyproject.toml /app/pyproject.toml
|
|
39
|
+
COPY --from=builder /app/README.md /app/README.md
|
|
40
|
+
COPY --from=builder /app/LICENSE /app/LICENSE
|
|
41
|
+
COPY --from=builder /app/data/lancedb-baked /app/data/lancedb-baked
|
|
42
|
+
|
|
43
|
+
CMD ["policynim", "mcp", "--transport", "streamable-http"]
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
ARG PYTHON_BASE_IMAGE=python:3.11.15-slim-trixie@sha256:9358444059ed78e2975ada2c189f1c1a3144a5dab6f35bff8c981afb38946634
|
|
2
|
+
|
|
3
|
+
FROM ${PYTHON_BASE_IMAGE} AS builder
|
|
4
|
+
|
|
5
|
+
ENV PYTHONDONTWRITEBYTECODE=1 \
|
|
6
|
+
PYTHONUNBUFFERED=1 \
|
|
7
|
+
POLICYNIM_LANCEDB_URI=/app/data/lancedb-baked
|
|
8
|
+
|
|
9
|
+
WORKDIR /app
|
|
10
|
+
|
|
11
|
+
RUN pip install --no-cache-dir uv==0.7.12
|
|
12
|
+
|
|
13
|
+
COPY pyproject.toml uv.lock README.md LICENSE ./
|
|
14
|
+
COPY src ./src
|
|
15
|
+
COPY policies ./policies
|
|
16
|
+
COPY evals ./evals
|
|
17
|
+
|
|
18
|
+
# Railway's Dockerfile builder rejects non-cache mounts, so its deploy-specific
|
|
19
|
+
# Dockerfile still has to source the bake-time key from a build arg.
|
|
20
|
+
ARG NVIDIA_API_KEY
|
|
21
|
+
|
|
22
|
+
RUN uv sync --frozen
|
|
23
|
+
RUN NVIDIA_API_KEY="${NVIDIA_API_KEY}" uv run policynim ingest
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
FROM ${PYTHON_BASE_IMAGE} AS runtime
|
|
27
|
+
|
|
28
|
+
ENV PYTHONDONTWRITEBYTECODE=1 \
|
|
29
|
+
PYTHONUNBUFFERED=1 \
|
|
30
|
+
POLICYNIM_LANCEDB_URI=/app/data/lancedb-baked \
|
|
31
|
+
POLICYNIM_MCP_HOST=0.0.0.0 \
|
|
32
|
+
PATH=/app/.venv/bin:$PATH
|
|
33
|
+
|
|
34
|
+
WORKDIR /app
|
|
35
|
+
|
|
36
|
+
COPY --from=builder /app/.venv /app/.venv
|
|
37
|
+
COPY --from=builder /app/src /app/src
|
|
38
|
+
COPY --from=builder /app/policies /app/policies
|
|
39
|
+
COPY --from=builder /app/evals /app/evals
|
|
40
|
+
COPY --from=builder /app/pyproject.toml /app/pyproject.toml
|
|
41
|
+
COPY --from=builder /app/README.md /app/README.md
|
|
42
|
+
COPY --from=builder /app/LICENSE /app/LICENSE
|
|
43
|
+
COPY --from=builder /app/data/lancedb-baked /app/data/lancedb-baked
|
|
44
|
+
|
|
45
|
+
CMD ["policynim", "mcp", "--transport", "streamable-http"]
|
policynim-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Nnenna Ndukwe
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|