From e6a1f0692f46392569b5225028b20dd587915e96 Mon Sep 17 00:00:00 2001 From: Nik Richers Date: Mon, 4 May 2026 14:30:59 -0700 Subject: [PATCH 1/2] docs: Map and assess evidence (#1299) * docs: Add autogenerate validation reports documentation Document the AI-powered features for validators: - Auto-Link Evidence for single/bulk guideline evidence linking - Risk Assessment Generation for single/bulk assessments - Understanding the structured AI-generated assessment format Closes sc-14812. * fix: Rename to map-and-assess-evidence with accurate UI terminology - Rename file from autogenerate-validation-reports.qmd to map-and-assess-evidence.qmd - Update title to "Map and assess evidence" - Fix UI element names to match actual product (Map Evidence, Assess Evidence) - Describe Evidence Assessment output structure accurately - Add relevance threshold slider documentation * Add screenshots for Map Evidence and Assess Evidence panels - Add map-evidence-panel.png showing evidence type toggles and relevance threshold - Add assess-evidence-panel.png showing compliance assessment option - Display both in column-margin divs alongside their respective sections * fix: Add Approve All / Reject All workflow for Map and Assess Evidence - Update Map Evidence steps to describe approve/reject workflow - Update Assess Evidence steps to describe approve/reject workflow - Clarify that editing is available after approving assessments * Add individual approve/reject, relevance analysis, and reassess options - Add individual Approve/Reject buttons for mapped evidence - Add See Relevance Analysis option with relevance score explanation - Add individual Approve/Reject buttons for evidence assessments - Add Reassess Evidence option to regenerate assessments - Add new "Understand mapped evidence" section explaining relevance scores and analysis * Distinguish report-level vs section-level approve/reject workflows - Report overview: Approve All / Reject All for entire report - Section-level: Individual Approve / Reject per evidence item or assessment - Clarify the two-level review structure for both Map Evidence and Assess Evidence * Consolidate intro into benefits-focused overview section Replace detailed "Understand mapped evidence" and "Understand evidence assessments" sections with a concise "How do evidence mapping and assessment work?" section that explains the benefits for new users. * Format overview section as definition list * Remove What's next section * Remove unused evidence-assessment-example.png * Add What's next section with listing to assess-compliance Links to the manual compliance assessment workflow for users who prefer traditional evidence linking and assessment selection. * Document Remap Evidence button in report overview * Replace 'report overview' with visible UI terminology Changed 'From the report overview' to 'For the entire report' and removed references to non-existent 'Overview page' label. * Simplify navigation: click Validation link directly * Address review comments from Fernanda * Fix link warning --- site/guide/_sidebar.yaml | 1 + .../assess-evidence-panel.png | Bin 0 -> 14871 bytes .../map-and-assess-evidence.qmd | 187 ++++++++++++++++++ .../model-validation/map-evidence-panel.png | Bin 0 -> 19944 bytes 4 files changed, 188 insertions(+) create mode 100644 site/guide/model-validation/assess-evidence-panel.png create mode 100644 site/guide/model-validation/map-and-assess-evidence.qmd create mode 100644 site/guide/model-validation/map-evidence-panel.png diff --git a/site/guide/_sidebar.yaml b/site/guide/_sidebar.yaml index e1a8822d0..f83571cac 100644 --- a/site/guide/_sidebar.yaml +++ b/site/guide/_sidebar.yaml @@ -133,6 +133,7 @@ website: contents: - guide/model-validation/review-model-documentation.qmd - guide/model-validation/assess-compliance.qmd + - guide/model-validation/map-and-assess-evidence.qmd - guide/model-documentation/work-with-content-blocks.qmd - guide/model-documentation/work-with-document-versions.qmd - text: "Check for compliance" diff --git a/site/guide/model-validation/assess-evidence-panel.png b/site/guide/model-validation/assess-evidence-panel.png new file mode 100644 index 0000000000000000000000000000000000000000..a454a4344bbb4ce381f8d05d7ff3b0fc4fe94ff4 GIT binary patch literal 14871 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 Ym?6s6eJ;EA-yaGUWz}SAq|8G87v6ELH2?qr literal 0 HcmV?d00001 diff --git a/site/guide/model-validation/map-and-assess-evidence.qmd b/site/guide/model-validation/map-and-assess-evidence.qmd new file mode 100644 index 000000000..ad342f8aa --- /dev/null +++ b/site/guide/model-validation/map-and-assess-evidence.qmd @@ -0,0 +1,187 @@ +--- +# Copyright © 2023-2026 ValidMind Inc. All rights reserved. +# Refer to the LICENSE file in the root of this repository for details. +# SPDX-License-Identifier: AGPL-3.0 AND ValidMind Commercial +title: "Map and assess evidence" +date: last-modified +listing: + - id: whats-next + type: grid + grid-columns: 2 + max-description-length: 250 + sort: false + fields: [title, description] + contents: + - assess-compliance.qmd +--- + +Use AI-assisted tools to map relevant evidence to validation guidelines and generate compliance assessments based on linked evidence. These features streamline the validation workflow by reducing manual effort while maintaining quality. + +::: {.attn} + +## Prerequisites + +- [x] {{< var link.login >}} +- [x] The model you are validating is registered in the model inventory.[^1] +- [x] A model developer has submitted their model documentation for validation.[^2] +- [x] You are a [{{< fa circle-check >}} Validator]{.bubble} or assigned another role with sufficient permissions.[^3] + +::: + +## How do evidence mapping and assessment work? + +Validation reports require you to link supporting evidence to each guideline and write compliance assessments, a process that can be time-consuming when done manually across dozens of guidelines. + +Map evidence +: Scans all available evidence from developers and validators, then suggests which items are relevant to each guideline. Instead of searching through evidence blocks yourself, you review AI-suggested matches and approve the ones that apply. Each suggestion includes a relevance score and explanation so you can make informed decisions. + +Assess evidence +: Analyzes the linked evidence for a guideline and drafts a structured compliance assessment. The generated assessment includes a compliance conclusion, specific observations about gaps or issues, and a technical review of what the evidence demonstrates. You review and approve the draft, and then make edits if needed — saving time while maintaining control over the final content. + +Both features are designed to accelerate validation without replacing your judgment. You always review and approve suggestions before they become part of the report. + +## Map evidence to guidelines + +:::: {.column-margin} +![Map Evidence panel](map-evidence-panel.png){fig-alt="Map Evidence panel showing evidence type toggles for Developer Evidence and Validator Evidence, and a Relevance Threshold slider set to 0.7." .screenshot} +:::: + +Map Evidence uses AI to suggest relevant evidence for each validation guideline, helping you find and link supporting documentation from both developers and validators. + +1. In the left sidebar, click **{{< fa cubes >}} Inventory**. + +2. Select the model you are validating.[^4] + +3. In the left sidebar, click **Validation** to open the validation report. + +4. Navigate to a section and expand the **Evidence** panel. + +5. Click **{{< fa wand-magic-sparkles >}} Map Evidence**. + +6. Configure the mapping options: + - Toggle **Developer Evidence** to include evidence logged via the {{< var validmind.developer >}}. + - Toggle **Validator Evidence** to include evidence uploaded or created by validators. + - Adjust the **Relevance Threshold** slider — lower values return more results while higher values show only the most relevant matches. + +7. Click **Map Evidence** to run the AI mapping. + + The panel displays how many evidence items are available to review for each guideline in the section. + +### Review and approve mapped evidence + +After running Map Evidence, you can review and approve suggestions at three levels: + +**For the entire report:** + +1. Open the validation report and look at the right sidebar. + +2. The **Map Evidence** panel shows how many items need review across the entire report. + +3. Use **Approve All** to link all suggested evidence across all guidelines, or **Reject All** to dismiss all suggestions. + +4. To re-run mapping with different settings, click **Remap Evidence**. This lets you adjust the relevance threshold or change which evidence types to include, then generate new suggestions. + +**For an entire section:** + +1. Navigate to a specific section in the validation report. + +2. In the section header, click **{{< fa wand-magic-sparkles >}} Map Evidence** to open the mapping panel. + +3. Use **Approve All** to link all suggested evidence for guidelines in that section, or **Reject All** to dismiss all section suggestions. + +4. To re-run mapping with different settings, click **Remap Evidence**. + +**For individual guidelines:** + +1. Navigate to a specific section in the validation report. + +2. Expand the **Evidence** panel for a guideline. + +3. Click **{{< fa wand-magic-sparkles >}} Map Evidence** to open the mapping panel for that guideline. + +4. Review individual evidence suggestions: + + - Each item shows the evidence block name and a relevance score. + - Click **See Relevance Analysis** to view why the evidence was suggested. + - Click **Approve** to link an individual item to the guideline. + - Click **Reject** to dismiss an individual suggestion. + +5. Or use **Approve All** / **Reject All** to handle all suggestions for that guideline at once. + +Approved evidence appears in the Evidence panel for that guideline, organized by evidence type (Developer Evidence or Validator Evidence). + +## Assess evidence for compliance + +:::: {.column-margin} +![Assess Evidence panel](assess-evidence-panel.png){fig-alt="Assess Evidence panel showing option to identify potential risks and compliance gaps based on linked evidence." .screenshot} +:::: + +Assess Evidence analyzes the linked evidence and generates a structured compliance assessment, identifying potential risks and compliance gaps. + +1. Navigate to a section that has linked evidence. + +2. Expand the **Evidence** panel. + +3. Click **{{< fa wand-magic-sparkles >}} Assess Evidence**. + +4. The AI analyzes the linked evidence and generates an **Evidence Assessment** containing: + + - **Guideline Assessment** — A compliance conclusion indicating whether the guideline requirements are fully met, partially met, or not met, with an explanation of the evidence quality. + + - **Validation Observations** — Specific findings about gaps or issues in the evidence, with each observation covering a single concern and suggesting actions for developers. + + - **Evidence Review** — A detailed analysis of what the evidence demonstrates, including references to specific test outputs, documentation, and any limitations. + + The panel displays how many assessments are available to review. + +### Review and approve evidence assessments + +After running Assess Evidence, you can review and approve assessments at three levels: + +**For the entire report:** + +1. Open the validation report and look at the right sidebar. + +2. The **Assess Evidence** panel shows how many assessments need review across the entire report. + +3. Use **Approve All** to accept all generated assessments, or **Reject All** to dismiss all assessments. + +**For an entire section:** + +1. Navigate to a specific section in the validation report. + +2. In the section header, click **{{< fa wand-magic-sparkles >}} Assess Evidence** to open the assessment panel. + +3. Use **Approve All** to accept all generated assessments for that section, or **Reject All** to dismiss them. + +4. To regenerate assessments with updated evidence, click **Re-assess Evidence**. + +**For individual guidelines:** + +1. Navigate to a specific section in the validation report. + +2. Expand the **Evidence Assessment** panel for a guideline. Assessments pending review show a [Review]{.bubble} status. + +3. Review the generated assessment content. + +4. Click **Approve** to accept the assessment, or **Reject** to dismiss it. + +5. After approving, you can edit the assessment content as needed — changes are auto-saved. + +6. To regenerate an assessment, click **{{< fa wand-magic-sparkles >}} Reassess Evidence** to run the AI analysis again with any updated evidence. + +## What's next + +:::{#whats-next} +::: + + + + +[^1]: [Register records in the inventory](/guide/inventory/register-records-in-inventory.qmd) + +[^2]: [Submit for approval](/guide/model-documentation/submit-for-approval.qmd) + +[^3]: [Manage permissions](/guide/configuration/manage-permissions.qmd) + +[^4]: [Working with the inventory](/guide/inventory/working-with-the-inventory.qmd#search-filter-and-sort-records) diff --git a/site/guide/model-validation/map-evidence-panel.png b/site/guide/model-validation/map-evidence-panel.png new file mode 100644 index 0000000000000000000000000000000000000000..6087aec7972f7d62c86c681b60c25ec0151ad3d4 GIT binary patch literal 19944 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 Date: Tue, 5 May 2026 17:07:45 -0700 Subject: [PATCH 2/2] docs: Add Databricks integration documentation (#1301) (#1316) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * docs: Add Databricks Unity Catalog integration documentation Add documentation for the new Databricks integration that enables linking ValidMind inventory records to Databricks Unity Catalog resources including models, datasets, and agents. - Add Databricks to supported connections in configure-connections.qmd - Add Databricks to model inventory integrations in managing-integrations.qmd - Add step-by-step connection and linking examples in integrations-examples.qmd Closes sc-14813 * Add placeholder columns to integrations grid layout * Fix Databricks connection field names to match UI - databricks host → workspace url - client id → sql warehouse id - client secret → personal access token * Fix Databricks link model steps to match UI * docs: Fix Databricks connection field descriptions - client id: Update to describe SQL Warehouse ID - client secret: Update to describe PAT token secret * docs: Add developer workflow for running validations on Databricks data Add a new section explaining how to run validation notebooks against Databricks-hosted data, with a link to the quickstart notebook and a mermaid diagram showing the data flow between platforms. * Split examples up into separate files. * File rename * Remove terminology ambiguity * Edits * Add missing headings for steps * Add configuration screenshot --- site/guide/_sidebar.yaml | 10 +- .../integrations/configure-connections.qmd | 15 + .../integrations/integrations-examples.qmd | 462 +----------------- .../configure-databricks.png | Bin 0 -> 72235 bytes .../create-jira-ticket.qmd | 85 ++++ .../create-servicenow-incident.qmd | 77 +++ ...ns-examples-aws-sagemaker-linked-model.png | Bin .../integrations-examples-aws-sagemaker.png | Bin .../integrations-examples-gitlab.png | Bin ...examples-http-request-open-jira-ticket.png | Bin ...-http-request-open-servicenow-incident.png | Bin ...integrations-examples-webhook-run_step.png | Bin .../synchronize-aws-bedrock.qmd | 99 ++++ .../synchronize-aws-sagemaker.qmd | 82 ++++ .../synchronize-gitlab.qmd | 80 +++ .../synchronize-with-databricks.qmd | 137 ++++++ .../use-webhooks-with-workflows.qmd | 128 +++++ .../integrations/managing-integrations.qmd | 34 +- 18 files changed, 750 insertions(+), 459 deletions(-) create mode 100644 site/guide/integrations/integrations-examples/configure-databricks.png create mode 100644 site/guide/integrations/integrations-examples/create-jira-ticket.qmd create mode 100644 site/guide/integrations/integrations-examples/create-servicenow-incident.qmd rename site/guide/integrations/{ => integrations-examples}/integrations-examples-aws-sagemaker-linked-model.png (100%) rename site/guide/integrations/{ => integrations-examples}/integrations-examples-aws-sagemaker.png (100%) rename site/guide/integrations/{ => integrations-examples}/integrations-examples-gitlab.png (100%) rename site/guide/integrations/{ => integrations-examples}/integrations-examples-http-request-open-jira-ticket.png (100%) rename site/guide/integrations/{ => integrations-examples}/integrations-examples-http-request-open-servicenow-incident.png (100%) rename site/guide/integrations/{ => integrations-examples}/integrations-examples-webhook-run_step.png (100%) create mode 100644 site/guide/integrations/integrations-examples/synchronize-aws-bedrock.qmd create mode 100644 site/guide/integrations/integrations-examples/synchronize-aws-sagemaker.qmd create mode 100644 site/guide/integrations/integrations-examples/synchronize-gitlab.qmd create mode 100644 site/guide/integrations/integrations-examples/synchronize-with-databricks.qmd create mode 100644 site/guide/integrations/integrations-examples/use-webhooks-with-workflows.qmd diff --git a/site/guide/_sidebar.yaml b/site/guide/_sidebar.yaml index f83571cac..6017e6961 100644 --- a/site/guide/_sidebar.yaml +++ b/site/guide/_sidebar.yaml @@ -49,7 +49,15 @@ website: - guide/integrations/link-external-models.qmd - guide/mcp/connect-ai-assistants-via-mcp.qmd - guide/integrations/configure-analytics-exports.qmd - - guide/integrations/integrations-examples.qmd + - file: guide/integrations/integrations-examples.qmd + contents: + - guide/integrations/integrations-examples/create-jira-ticket.qmd + - guide/integrations/integrations-examples/create-servicenow-incident.qmd + - guide/integrations/integrations-examples/synchronize-aws-bedrock.qmd + - guide/integrations/integrations-examples/synchronize-aws-sagemaker.qmd + - guide/integrations/integrations-examples/synchronize-with-databricks.qmd + - guide/integrations/integrations-examples/synchronize-gitlab.qmd + - guide/integrations/integrations-examples/use-webhooks-with-workflows.qmd - text: "---" - section: "Workflows" contents: diff --git a/site/guide/integrations/configure-connections.qmd b/site/guide/integrations/configure-connections.qmd index 944a7fb98..831f96e5a 100644 --- a/site/guide/integrations/configure-connections.qmd +++ b/site/guide/integrations/configure-connections.qmd @@ -121,6 +121,21 @@ Required configuration details: **[personal access token]{.smallcaps}** : Select a secret containing your GitLab Personal Access Token with `api` or `read_api` scope. +### Databricks + +A unified analytics platform for data engineering, data science, and machine learning, including Unity Catalog for centralized metadata management. + +Required configuration details: + +**[databricks host]{.smallcaps}** +: The URL of your Databricks workspace, such as `https://yourcompany.cloud.databricks.com`. + +**[client id]{.smallcaps}** +: The ID of your SQL Warehouse (found in Databricks SQL Warehouses settings). + +**[client secret]{.smallcaps}** +: The secret that stores your Databricks personal access token (PAT). + ### Custom A user-defined connection to a third-party system that implements the {{< var vm.product >}} reference API.[^4] diff --git a/site/guide/integrations/integrations-examples.qmd b/site/guide/integrations/integrations-examples.qmd index 9ee496a77..91c9a5c15 100644 --- a/site/guide/integrations/integrations-examples.qmd +++ b/site/guide/integrations/integrations-examples.qmd @@ -4,461 +4,17 @@ # SPDX-License-Identifier: AGPL-3.0 AND ValidMind Commercial title: "Integrations examples" date: last-modified +listing: + - id: examples-listing + type: grid + grid-columns: 2 + max-description-length: 250 + sort: true + fields: [title, description] + contents: "integrations-examples/*.qmd" --- Adapt these usage examples for your own workflows or connections to interact with external systems. -- [Create a Jira ticket](#create-a-jira-ticket) -- [Create a ServiceNow incident](#create-a-servicenow-incident) -- [Start workflows via webhook](#start-workflows-via-webhook) -- [Add webhook step triggers](#add-webhook-step-triggers) -- [Synchronize models with AWS SageMaker](#synchronize-models-with-aws-sagemaker) -- [Synchronize models with AWS Bedrock](#synchronize-models-with-aws-bedrock) -- [Synchronize models with GitLab](#synchronize-models-with-gitlab) - -::: {.attn} - -## Prerequisites - -- [x] {{< var link.login >}} -- [x] You are a [{{< fa hand >}} Customer Admin]{.bubble} or assigned another role with sufficient permissions to configure workflows.[^1] -- [x] You understand how to configure workflows and add steps to workflows.[^2] -- [x] Secrets are configured for any external systems that require authentication: integration secrets for connections, webhook secrets for HTTP Request step headers.[^3] -- [x] Connections are configured for any external systems you plan to integrate with.[^4] -- [x] You have admin access to the external systems you plan to integrate with. - -::: - -## Workflow examples - -These examples use HTTP requests or webhooks to integrate with external systems: - -- An _HTTP request_ step sends data from {{< var vm.product >}} to another service. A workflow can notify a partner tool when a model reaches a certain state or request an update in an external system. This pattern is useful when {{< var vm.product >}} owns the event and needs to push it outward. - -- A _webhook_ step does the opposite. Another system sends a POST request to start a {{< var vm.product >}} workflow or to continue a workflow that is paused while waiting for a webhook to continue. This lets external tools trigger actions inside {{< var vm.product >}} when an event occurs on their side. - -### Create a Jira ticket - -To create a Jira ticket when model validation requires attention: - -::: {.column-margin} -![Create a Jira issue](integrations-examples-http-request-open-jira-ticket.png){width=80% fig-alt="Screenshot of the HTTP request step configured to create a Jira ticket, showing the required fields described in step 4." .screenshot} -::: - -1. In the left sidebar, click **{{< fa gear >}} Settings**. - -2. Under {{< fa shield >}} Governance, select **Workflows**. - -3. Select the **Model Workflows** tab. - -4. Click on a workflow to modify or click **{{< fa plus >}} Add Model Workflow**[^5] to create a new workflow. - -5. From the **Workflow Steps** modal, drag and drop an **HTTP Request** step[^6] onto the canvas, then connect it to your workflow. - -6. Double-click the step to open the **Configure HTTP Request** modal. - -7. Configure the required fields, replacing the placeholder values with your own: - - - **[url]{.smallcaps}** — `https://yourcompany.atlassian.net/rest/api/3/issue` - - **[method]{.smallcaps}** — POST - - **[headers]{.smallcaps}** — Add: - - `Content-Type`: `application/json` - - `Authorization`: `Bearer {{Jira Personal Access Token}}` - - ::: {.callout-tip title="Use webhook secrets for credentials"} - Instead of entering credentials in plaintext, use a webhook secret: `Bearer {{secret:jira_pat}}`. See [Manage secrets](manage-secrets.qmd#webhook-secrets). - ::: - - - **[body type]{.smallcaps}** — JSON - - **[body]{.smallcaps}** — Use the following JSON payload: - - ```json - { - "fields": { - "project": { - "key": "MODEL" - }, - "summary": "Model validation failed: {{Model Name}}", - "description": "The model [{{Model Name}}|{{Model URL}}] failed validation. Review artifacts in ValidMind.", - "issuetype": { - "name": "Bug" - } - } - } - ``` - -8. Click **Update Step** to save your configuration. - -The HTTP request to create the Jira ticket is sent when the workflow executes the step. - -### Create a ServiceNow incident - -To create a ServiceNow incident when a data drift issue is detected during ongoing monitoring: - -1. In the left sidebar, click **{{< fa gear >}} Settings**. - - -2. Under {{< fa shield >}} Governance, select **Workflows**. - -3. Select the **Model Workflows** tab. - -4. Click on a workflow to modify or click **{{< fa plus >}} Add Model Workflow**[^5] to create a new workflow. - -5. From the **Workflow Steps** modal, drag and drop an **HTTP Request** step[^7] onto the canvas, then connect it to your workflow. - -6. Double-click the step to open the **Configure HTTP Request** modal. - -7. Configure the required fields, replacing the placeholder values with your own: - - - **[url]{.smallcaps}** — `https://yourinstance.service-now.com/api/now/table/incident` - - **[method]{.smallcaps}** — POST - - **[headers]{.smallcaps}** — Add: - - `Content-Type`: `application/json` - - `Authorization`: `Basic {{ServiceNow Credentials}}` - - ::: {.callout-tip title="Use webhook secrets for credentials"} - Instead of entering credentials in plaintext, use a webhook secret: `Basic {{secret:servicenow_creds}}`. See [Manage secrets](manage-secrets.qmd#webhook-secrets). - ::: - - - **[body type]{.smallcaps}** — JSON - - **[body]{.smallcaps}** — Use the following JSON payload: - - ```json - { - "short_description": "Data drift issue detected: {{Model Name}}", - "description": "A potential issue has been identified for model {{Model Name}} (link: [{{Model URL}}]({{Model URL}})). Please review the ongoing monitoring documentation in ValidMind.", - "urgency": "2", - "category": "Model Risk" - } - ``` - -::: {.column-margin} -![Create a ServiceNow incident](integrations-examples-http-request-open-servicenow-incident.png){width=80% fig-alt="Screenshot of the HTTP request step configured to create a ServiceNow incident, showing the required fields described in step 4." .screenshot} -::: - -The HTTP request to create the ServiceNow incident is sent when the workflow executes the step. - -### Start workflows via webhook - -To start a {{< var vm.product >}} workflow from an external system: - -::: {.panel-tabset} - -#### a. Configure workflow in {{< var vm.product >}} - -1. Add a new workflow, selecting the **Via Webhook** workflow start option.[^8] - -2. From the **Workflow Steps** modal, drag and drop a **Webhook** step[^9] onto the canvas, then connect it to your workflow. - -3. Double-click the step to open the **Webhook Step Trigger** modal. - -4. Copy or select the webhook details: - - - **URL** — Click **{{< fa regular copy >}} Copy** for the unique POST webhook URL to use when configuring your external system. - - **[select target model for payload]{.smallcaps}** — Select the model that is associated with the webhook payload from the dropdown. - - **Payload** — Click **{{< fa regular copy >}} Copy** for the JSON payload that external systems must send in their POST request, where the value for `target_cuid` is shown after you select a target: - - ```json - { - "action": "run_workflow", - "target": "", - "entity_name": "InventoryModel" - } - ``` - - - For the required authentication headers, click **{{< fa regular copy >}} Copy** for each of the following key-value pairs and paste them into your external system: - - `x-api-key`: `{{API Key}}` - - `x-api-secret`: `{{API Secret}}` - - **[wait for webhook trigger when reached]{.smallcaps}** — When enabled, the workflow pauses execution when it reaches this step and waits for the external system to send the POST request. - -5. Click **Save**. - -#### b. Start workflow from external system - -Send a POST request to the webhook URL with a JSON payload that includes the `run_workflow` action for the target model CUID: - -```bash -curl -X POST https://api.prod.vm.validmind.ai/vm/api/v1/webhooks/xxxxxxxxxxxxxxxxxxxxxxxxx/xxxx -H 'Content-Type`: `application/json' -H 'x-api-key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' -H 'x-api-secret: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' --data '{ - "action": "run_workflow", - "target": "", - "entity_name": "InventoryModel" -}' -``` +:::{#examples-listing} ::: - -### Add webhook step triggers - -To trigger a waiting {{< var vm.product >}} workflow step to continue from an external system: - -::: {.panel-tabset} - -#### a. Configure workflow in {{< var vm.product >}} - -1. Open the workflow you want to configure, or add a new workflow.[^10] - -2. From the **Workflow Steps** modal, drag and drop a **Webhook** step[^11] onto the canvas, then connect the step to your workflow. - -3. Double-click the step to open the **Webhook Step Trigger** modal. - -4. Copy or select the webhook details: - - - **URL** — Click **{{< fa regular copy >}} Copy** for the unique POST webhook URL to use when configuring your external system. - - **[select target model for payload]{.smallcaps}** — Select the model that is associated with the webhook payload from the dropdown. - - **Payload** — Click **{{< fa regular copy >}} Copy** for the JSON payload that external systems must send in their POST request, where the value for `target_cuid` is shown after you select a target: - - ```json - { - "action": "run_step", - "target": "", - "entity_name": "InventoryModel" - } - ``` - - - For the required authentication headers, click **{{< fa regular copy >}} Copy** for each of the following key-value pairs and paste them into your external system: - - `x-api-key`: `{{API Key}}` - - `x-api-secret`: `{{API Secret}}` - -5. Click **Update Step** to save your configuration. - -When the workflow reaches this step, it pauses and waits for the external system. - -#### b. Trigger workflow to continue from external system - -Send a POST request to the webhook URL with a JSON payload containing the `run_step` action for the model CUID: - -```bash -curl -X POST https://api.prod.vm.validmind.ai/vm/api/v1/webhooks/xxxxxxxxxxxxxxxxxxxxxxxxx/xxxx -H 'Content-Type`: `application/json' -H 'x-api-key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' -H 'x-api-secret: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' --data '{ - "action": "run_step", - "target": "", - "entity_name": "InventoryModel" -}' -``` - -::: - -## Connection examples - -### Synchronize models with AWS SageMaker - -::: {.column-margin} -![Connect with AWS SageMaker](integrations-examples-aws-sagemaker.png){width=80% fig-alt="Screenshot of the AWS Sagemaker connection configured to synchronize models, showing the required fields described in step 5." .screenshot} -::: - -To synchronize models registered in the {{< var vm.product >}} model inventory with AWS SageMaker models, you need to first configure the connection and then link the models: - -#### Configure the connection - -::: {.column-margin} -![A linked AWS SageMaker model](integrations-examples-aws-sagemaker-linked-model.png){width=60% fig-alt="Screenshot of the model linked to AWS SageMaker, showing the required fields described in step 4." .screenshot} -::: - -1. In the left sidebar, click **{{< fa gear >}} Settings**. - -2. Under {{< fa puzzle-piece >}} Integrations, select **Connections**. - -3. Click **{{< fa plus >}} Add Connection**. - -4. In the modal that opens, select **AWS Sagemaker**. - -5. Complete: - - - **[integration name]{.smallcaps}** — How other admins can identify the connection. - - **[description]{.smallcaps}** (optional) — The intended usage or additional details. - - **[aws region]{.smallcaps}** - The primary region where your SageMaker model registry lives, for example `us-west-2`. - - **[aws access key id]{.smallcaps}** — The secret generated by AWS IAM with permissions to read the model registry. - - **[aws secret access key]{.smallcaps}** — The secret generated by AWS IAM with permissions to read the model registry. - - **[initial status]{.smallcaps}** — Set to `Operational` to enable immediately or `Disabled` if you plan to finish setup later. - -6. Click **Save Integration**. - -7. Test the connection: - - a. Hover over the AWS SageMaker connection you just created. - b. When the **{{< fa ellipsis-vertical >}}** menu appears, click on it and select **{{< fa circle-check >}} Test Connection**. - - If the test is successful, the message **{{< fa check-circle >}} Connection successful** displays. - - -#### Link the models - -1. In the left sidebar, click **{{< fa cubes >}} Inventory**. - -2. Select a model by clicking on it or find your model by applying a filter or searching for it.[^12] - -3. Scroll down until you locate the **Amazon Sagemaker** connection box in the right sidebar. - -4. Hover over the Amazon SageMaker box. - -5. When the **{{< fa ellipsis-vertical >}}** menu appears, click on it and select **{{< fa link >}} Link Model**. - -6. In the modal that opens, click the [select model]{.smallcaps} dropdown to pick the AWS SageMaker model to link. - -7. Optional: Click **Test Connection** to ensure the connection is working as expected. - - If the test is successful, the message **{{< fa check-circle >}} Connection Test Successful** displays. - -8. Click **Link Model**. - -### Synchronize models with AWS Bedrock - -The AWS Bedrock integration lets you link {{< var vm.product >}} models to foundation models and generative AI agents in Amazon Bedrock, supporting governance across your AI/ML ecosystem. - -AWS Bedrock exposes two primary integration surfaces: - -- **Foundation model layer** — Access to AWS-hosted and custom foundation models through the Bedrock model catalog (Discover and Tune views). - -- **Application layer** — Bedrock primitives such as agents, flows, and knowledge bases that represent built generative AI applications and workflows. - -#### Configure the connection - -1. In the left sidebar, click **{{< fa gear >}} Settings**. - -2. Under {{< fa puzzle-piece >}} Integrations, select **Connections**. - -3. Click **{{< fa plus >}} Add Connection**. - -4. In the modal that opens, select **AWS Bedrock**. - -5. Complete: - - - **[integration name]{.smallcaps}** — How other admins can identify the connection. - - **[description]{.smallcaps}** (optional) — The intended usage or additional details. - - **[aws region]{.smallcaps}** — The primary region where your Bedrock resources are deployed, for example `us-east-1`. - - **[aws access key id]{.smallcaps}** — The secret generated by AWS IAM with permissions to access Bedrock. - - **[aws secret access key]{.smallcaps}** — The secret generated by AWS IAM with permissions to access Bedrock. - - **[initial status]{.smallcaps}** — Set to `Operational` to enable immediately or `Disabled` if you plan to finish setup later. - -6. Click **Save Integration**. - -7. Test the connection: - - a. Hover over the AWS Bedrock connection you just created. - b. When the **{{< fa ellipsis-vertical >}}** menu appears, click on it and select **{{< fa circle-check >}} Test Connection**. - - If the test is successful, the message **{{< fa check-circle >}} Connection successful** displays. - -#### Link models from Bedrock - -Once the connection is configured, you can link {{< var vm.product >}} models to your Bedrock resources: - -::: {.callout title="Model dependencies"} -Bedrock agents, flows, and runtimes typically call foundation models (LLMs) under the hood. When you link these application-layer resources to {{< var vm.product >}}, consider also registering their underlying foundation models and creating dependency relationships between them. - -This builds a complete dependency graph showing how your AI applications relate to underlying models. Benefits include: - -- **Impact analysis** — See which applications are affected if a foundation model is deprecated or has compliance issues. -- **Full audit trails** — Documentation and risk assessments capture the entire model stack, not just the top-level application. -- **Governance visibility** — Track model versions and changes across your AI ecosystem. -::: - -1. In the left sidebar, click **{{< fa cubes >}} Inventory**. - -2. Select a model by clicking on it or find your model by applying a filter or searching for it.[^13] - -3. Scroll down until you locate the **Amazon Bedrock** connection box in the right sidebar. - -4. Hover over the Amazon Bedrock box. - -5. When the **{{< fa ellipsis-vertical >}}** menu appears, click on it and select **{{< fa link >}} Link Model**. - -6. In the modal that opens, use the tabs to filter by resource type: - - - **All** — View all available Bedrock resources. - - **Foundation Models** — AWS-hosted and custom foundation models from the Bedrock catalog. - - **Agents** — Generative AI agents you've built in Bedrock. - - **Flows** — Prompt flows and orchestration workflows. - - **AgentCore Runtimes** — Agent runtime environments. - -7. Click **[select model]{.smallcaps}** to choose the specific Bedrock resource to link. - -8. Optional: Click **Test Connection** to ensure the connection is working as expected. - - If the test is successful, the message **{{< fa check-circle >}} Connection Test Successful** displays. - -9. Click **Link Model**. - -### Synchronize models with GitLab - -Synchronize GitLab model registry with ValidMind model inventory for comprehensive model tracking. - -#### Configure the connection - -::: {.column-margin} -![Configure GitLab connection](integrations-examples-gitlab.png){width=80% fig-alt="Screenshot of the Configure GitLab dialog showing fields for integration name, description, project ID, GitLab instance URL, personal access token, and initial status." .screenshot} -::: - -1. In the left sidebar, click **{{< fa gear >}} Settings**. - -2. Under {{< fa puzzle-piece >}} Integrations, select **Connections**. - -3. Click **{{< fa plus >}} Add Connection**. - -4. In the modal that opens, select **GitLab**. - -5. Complete: - - - **[integration name]{.smallcaps}** — How other admins can identify the connection. - - **[description]{.smallcaps}** (optional) — The intended usage or additional details. - - **[project id]{.smallcaps}** — The GitLab project ID or path containing ML models (required). - - **[gitlab instance url]{.smallcaps}** (optional) — Leave empty to use GitLab.com, or enter your self-hosted GitLab URL. - - **[personal access token]{.smallcaps}** — Select a secret containing your GitLab Personal Access Token with `api` or `read_api` scope. - - **[initial status]{.smallcaps}** — Set to `Operational` to enable immediately or `Disabled` if you plan to finish setup later. - -6. Click **Save Integration**. - -7. Test the connection: - - a. Hover over the GitLab connection you just created. - b. When the **{{< fa ellipsis-vertical >}}** menu appears, click on it and select **{{< fa circle-check >}} Test Connection**. - - If the test is successful, the message **{{< fa check-circle >}} Connection successful** displays. - -#### Link the models - -1. In the left sidebar, click **{{< fa cubes >}} Inventory**. - -2. Select a model by clicking on it or find your model by applying a filter or searching for it.[^14] - -3. Scroll down until you locate the **GitLab** connection box in the right sidebar. - -4. Hover over the GitLab box. - -5. When the **{{< fa ellipsis-vertical >}}** menu appears, click on it and select **{{< fa link >}} Link Model**. - -6. In the modal that opens, click the [select model]{.smallcaps} dropdown to pick the GitLab model to link. - -7. Optional: Click **Test Connection** to ensure the connection is working as expected. - - If the test is successful, the message **{{< fa check-circle >}} Connection Test Successful** displays. - -8. Click **Link Model**. - - - -[^1]: [Manage permissions](/guide/configuration/manage-permissions.qmd) - -[^2]: [Introduction to workflows](/guide/workflows/introduction-to-workflows.qmd) - -[^3]: [Manage secrets](manage-secrets.qmd) - -[^4]: [Configure connections](configure-connections.qmd) - -[^5]: [Add new workflows](/guide/workflows/configure-workflows.qmd#add-new-workflows) - -[^6]: [Workflow step types](/guide/workflows/workflow-step-types.qmd#http-request) - -[^7]: [Workflow step types](/guide/workflows/workflow-step-types.qmd#http-request) - -[^8]: [Add new workflows](/guide/workflows/configure-workflows.qmd#add-new-workflows) - -[^9]: [Workflow step types](/guide/workflows/workflow-step-types.qmd#webhook) - -[^10]: [Add new workflows](/guide/workflows/configure-workflows.qmd#add-new-workflows) - -[^11]: [Workflow step types](/guide/workflows/workflow-step-types.qmd#webhook) - -[^12]: [Working with the inventory](/guide/inventory/working-with-the-inventory.qmd#search-filter-and-sort-records) - -[^13]: [Working with the inventory](/guide/inventory/working-with-the-inventory.qmd#search-filter-and-sort-records) - -[^14]: [Working with the inventory](/guide/inventory/working-with-the-inventory.qmd#search-filter-and-sort-records) \ No newline at end of file diff --git a/site/guide/integrations/integrations-examples/configure-databricks.png b/site/guide/integrations/integrations-examples/configure-databricks.png new file mode 100644 index 0000000000000000000000000000000000000000..d524781af9ba8727d44ff260bbd2c846fd5eec8a GIT binary patch literal 72235 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⪼5HL8qbkDIO|Q=1%d ze!W>`D%TSvv$YPDXCor3w*Imy9h(hsU9R?@M~mV`l}^VSl&Ef3vLe!gC|hK7KQ(8o z4kexCT>X`D^2`qYEk{RZCcj%5gV1NnNv~NygDqcAFAgAdb_;wE>wAK@H@cgouKcpA zSdfSKP^Z(B03)St4Inn(OH3w8_-^=%OP1=kkj69UL<8P|ptiO)d~RoD;Q#fLG+La) zfc0sQC?t>(fLpvPzdsdgBoo&=`pd^?x6-K6ZkwS>5QxjFyciKY6r8IvL2^ht#|sR) zqT#b1GICz>1~QeTR+M%pt|hib(p}n2&yBf3H<3cv^t$y5wtF=k7PDUkzX?6NU%7L^ zA>D%^GV+)bsg`MzkSX(hn0yql%l)m}`l`e3^$h4%$4i^preIA~&1XtjsTJ(aW@;lG z5`!b<*-4`mCqnhpCkx2Vw?^WDTwo{}jmq?u6H<>S*E8kRd*D7vyeNLz{9r3uY`T`z zmir*wuL$HP4B-H_k~mwV0qIQ9Aj2*|u~)3l91zE5Dm769Xi~nCk|Lv&w^MlmjM+_- zo?Wm$mC*JyK6g5RYU^67;{lz2<8`=LCl58MVtQrI%Bq_!&Tgil$MaPbyg)Mphm;P9 zNPz82#`oRv@fsN{yZR|CQAJ?p8yaLLT`$zh*4b15JFgHIz$`+(>-1_UT5tGg`u>-f zN0;-ZzYnP?<29MToGTl}*m@@&U4XWnp~H(7RA2H5uICPRl3R%QPm2rZU`19psa9=q z_pZdE7?42Gm20ZqbbT=99B>oOuf-9B!wYQYyYxc#_*s*@I9n3!}f1x>Aa>q2}X6YLw+!3jFGCCti}lD z@i=&j0}3OkNf>I(lP%_)w{Fw2IG5)m(TsWmF;7NQRS5WOv)P|A!mQ@&;>UBO{iajg z^Z@X#9C>f67vrnR5%7q%)1P{w=L5!wm&7Z0xP~4;^VD*2nW9k@YUh6R;G}e4Ax-cE zxDt{l3)oD@n~|fvlh%AEX+`mq3d_B2usK(;q<(Nk=@VH1L1?+4dx;Wyr{YiW*`}7W z^<$GC^#$Qp-~qM=pdpK@EzwH${$?SOPGHVk{_btXMm+&Lk#Q5x-E~bqzNwz-*u4`0 zUhp4a-%4wrrC9Q9xP+emYpl_gzI>xsWrLivwzdo(QaLg|{;b7Jj$TCrLZ<%8kxN&p@?aDUuFHC3b*uUDhK*yxW@QC=EGrQ>JZP+iYww?#MZ zu_A<_5WhKFVIVH_QwZNw(aO~Dt(%w|bSAk{?#Ec{MuM62r+b8g<@_i>_B)2&CJ~H2 zS6*2fAQ?7=lx^Z?3@XG_tX3`2q_3*+f60W%AQ*OgwU>CJi3(Vhz)%#J>HbyO*^7NW9~O@fmRNaVf-^m zGTONd(@&}dqL>(O0PodgQULzeuA=qM{a11@c9QbFy%fjYX*r^*eRC@;#yyX#M7jxY zJM`4w$Z|H#SCaHAh(jlx#UCKI=VTRNnvz`ie|H!UK{QaPTxy|MS$sY0ArX#CAs9iJ zwQDJrGp8n3gS457wCeKDI{)Pd&>?L7W4=x(LPT0uVap{TNX_aJ2t*2uu|cE6?pcu5 zvE@5zJHuTUh3vV#mo0uGdqh~CS+$Ua^;zk-_8)!yRLD`DM0EBfBZM3LmonkyTVRM@ zZmJGPSVFniHfAAkQgoses8`oR2%OOm(B#Yf8Vvc%<)`3kjri9~&FFyIpAm|cQTVS9 zKK;f0+6hB`q6kxeN#Ub90uGVhpXDj!RJd&L;lFm@Uk)^|9+Gq)%S7V*3YC%ZdL8Rq zNJPMsJbAD?1n7Z_ncUX!nitu|3h6JzBuYR#KtJ4U)dP&y?xbUGe_~L+x%K^gCet3( za&68M$4|nCeN|3G3MD{3K&17GJWH&h(LaE9mPB?b4FSK&xYi`&ps(QnB%3V)*2bM~gAz8=<>)L$GGb0t0JF|V@%kWpZLpI4i|DaJis=y60d+&gZe77k9>zgB;0r3&X;S^t6GV2oHyx|Z zZ8tx%Q2yCxFjY`5T@YVR;1S3$OQnsUs{^oxxAx=Y_ckDA!%^Y}z?2t?C#c(c_=kJ8 zwR{O*z*f}#b`z^WwIt~WgGxVstI4r0Adqk5bAM15DAi!?JRMBnR$?(8d=Kbde<;tA-xXzyb&4JCcSXv;MF;YMN_-@hh#msllQNFWKmTsB_3=>y}rMi4hXPu$P06BXc z;A80!biCFeoRp!0sG}n6_D+tJ@|I%(IifZXKoSJD@kD6UO6mCBZ$1D(`IS8dZs&sp z{0XAj4QeIBwBV5LFgzJR0-odU^Hy9)|Aq8uo{(o!!cFp`Mh1=UfnAO9>qu_-Q zx7G=((P*LZHNckW)xG*)4yh}>0nyS!^Ehcb5enlZ0re|@hC^R{)v5&1bqql3xxhrU z0RTY40-ccu^*4IJ3B|k+O({pC8~t1*xkzWw9TpQy z!(&|n&@5%N_@6VcSY2u@NUqNP#m&ScaLDxBE@M-8U8ddLn$>f`4O+zAzx0IDzuTLM z$7cSL(6&OT>xEJLx%IVa$V2FbjWgP|NvqlmAt+c-x+|q#LL~Uvd)J{4m0|;M@v@dh z*;Z?0VK#UxW)p+2%&LvD6>%kLLTxXzq(HBF<@d{Cys0~0V$TG>M2ckGo4&y{1I>l3*y<5JlV>C_*2QItHZ-6^n+%H!=#4>!ypuK6Lz^`%O;1d6u{t0 z+3|_V1FS%|rSW03D6c^rsL#oPyn!w3eXLA;WRxMT+8^S2t|YB9WimjWHFQ)#!?N{! z8ql0)`Df}0sHo>HJnFui_N8!Fp~$F8M_t5@vHR76YE?-6(Igph_=>|6z6r?#b zRv`k-?Xl`zZ3gK6(>bQ9-%;UzihL1}UKIN$Mc2qeK_jf?xzv3_<#+!6lB@8;`C5le z5}8{Aj~u=9Yc^#TT%uc2Yb+q~wM$!PguxaiZ?xYfb*J%c-JSikRw(qr1zAc-89RIY z6pK++cDh8%@L9OqT(Sor;y@Uv(Z(Lj6|Q|4Q5(odP9;vjvZJ3seKq$OPLn~zQ^lPqG|hIr4D0}$zPZN)9N+RLnU23szX zlG@%~n3~7udh?gh*snaeTpuO6ffO;qeLOXOcCCy}RY>?6rd%iUsirU=I84&bT-IYfCQ<1P{fNbA(n1#GqaAkEkTRk`F_gtecE;@HTr_0E?`4;3p&IFIKe z#(MB2Q9_LqSV@XdCIs8|&wv>ODdOC6v9`pCjghbkUgVTBjn1#*pwwBrhDOD3EZswT zwZm^H%W}fB)9~)NZGa|BpE%4MNG81M^*3!_otfc5oJ{|>K0 zDFGEkV?A%ycU5Jo9sFMl$;y(1$OSz-v_QP8|B@z#KXv5&vT4l_TX1AA^qg{?wEn>e zs2|&I%i0X{l<1*J;om3tKjz4{3R{Xg%Y_IlgRQMvVnCJGG!oF>zZWmdkEoR^BmGrL zp!u^!ai2}mtU4oDpaY9q1<=9cLH$AIeoq{c6HzXf4LOE2sVxLD95SSZ~m4&*d1U4onX=YKvriCQCW(=4Rd%iRCwZJdCL<@Sj2Nisw z0@nUp1**twFKwT?Acxv-3&v@he$J6*Dn$Zn+TjN6SHW<3l|}<=CCs#9@KLCI6$5wQ zA_Fw{&yuH8ek!ECJ{?D>_4daZH=qE)puL4M}?^;~C&CZBkTx0m*Fielx{(yc>9}R|Kj{FfdWx zqkE`cw8!z|9f41O_Pl^iW;J*OSDFZL@XZ4HKYGzeswPgTuL=raz#u^eCi0-ILkeBp zBWS{>s2dRb?=6+T5HL?6kbmOopS#8?M_wJL5O`TAZ~|#XM&Mt|ER)564);*wGCuvQ z?`vjxDPIxz8D(EB5v(wQ(wKAK-LCr8r=Rq{NE%r#n#;x70VUc##dCB!Ey>Du5BH69 z`+4TS-)n^rR>q*ybOm#qe@(zeI$_N4qpj|+_Ss^wLJg2NsJW-|X`OBM;Ve;Zwr3dF zK6K(p#qjtIrrhThtG7ti9?g>Fjp#;h^hHaCVvp(74{a84^sb?V+kCm z6M{Bor4j|qqb%;s14O5{iSncq2bVVX>^=Gh=R%C`huu&)zu`-zy!V>Bo{7`3y&u+* zN+OSXRPVu>Froj!R-hOdA%g?p9s(JdaPE;&NQ?+JTBjfB}b5p+_7Dq*Y38Ya;ziGJzReb+B>ADR^m%`3AbBt zFaI6#F1c=ipTH%$6Lx4iXJBR^hjxZsC+Wx5VOpfu=8m=7K3gS{eq(m zup6uQkUg{03urlILU#mmC8o^-{RrLsWfB#|$fE`99@25Qhy@@{*ZJ?YA1AIr0{^-2 zp5`y?jqyAgdZJdnPrpS7UVELTxQn>ABjvy2>zkVptZ3ra~ zB$B^Fz@}*B{MKS!6%tn*1=hkN^UJkC?UcGFQ75YR`gTcGP!D| zFcx&+8Maijln7d*0AwaL$C|ayK6E-2!%u`WfjEe#mV(SXP@RXXKX131kK0aK?drg; zzG;?KV4te2HxdE|(=0rPT4^|^d2fI7k4k!FnPg@9ImQ&lj?Z8EI$LlCnh zl4A%j>3Tr*8&kLppz$+0ySS}Vww0LE@*acOEsY+nM^C=|b&%nz1*>704MDpj=m z@vg~cdi5u#xuX1+U49~#Gc41ST?ujYqj@`_;gpuIo!cy793?t!Vwn;Vl=fz-@fI2^ z2~(~x^m@z5K=!MxY2k2YSG%^l$KjHTq?obBT&`OWHlZmS*t)59TiinhCM0pak(Et=f64Z9BZdqDa&9Mi*c6~Das$4@3&fy`QOpAQT|t%nEP znq99{yM+Oba_9vLdzPEoj-sVU(m$|Dc5uS!n zlBj>b)E_&PZOHx2cj9IsTVuSzP3bm62Jco$jh^Jqi2%TX+51sl2al8zfF5ViBahef z_BbjD3UK}qq@04e@yL`!6!!jHMJw0(RZHOu(zVgm^(|~sAz`q|l#mU^%OtZN4S0Xob(tg>minbuBp*@$maU9Pz%`ricvn5W zKU5=Rvxo37N3P0$Pe_mRUSgLUV<48zV%@ZG4t#UX!f|R$6i#Cm+$noHKxIQG4F3b@ zV76vCv`KHoDpVxo-dhr>GbJ`X;(A79wtbY5t3%|@%|vltwQSMi2uzeP;bL!kI*@UD z-+)e4c}N8>yvG31NCjndwW*awON=pP-WS)tF=NJGzuXskI4J9ykQ64|PTfCW9FSAW z30@ruk|!Knx00j~W3!q_nsmEAx2Aud)AA!vF~J4_z34gD(s8qA;ky(9Zg*)-wnuGe z2TQWH2abUhyrl*~n|}P=@ruMJw)o__v@r8vhWCal8Qg$M+y?zqX*fI9lpe`Y{AWPZ zJhJcp9^$ep(8cRJ8;mNG|E#rZSZ%59CA-|0G`+E2gJ)fW9Q~(1Tjv1;fVhzk==m@W z67FO|lLj!+d9!_rdWRWkyt+)6{&h_GLY(>8IML_kpZ?*B9?6R82H9lVP9fddcEwtn z48it7-Eq<+-NT4S;gdYk)y|j!cj2%CpkEQO?4O5)W;RopY@c_yn5FK!S9J&?s2&ex zD|yu91n&_br`0(ln5%b6wmB;I4r_$xI;jyXrHrzt;5FYu==Q2f(TYFZxsgVvzxY#{ z|0yd$MMYF6(s^1+Nvs?k9#P&q#l9y-;kTE$ztPww7uOLo9F_ehX3;Y;IW(K14-5<` zd!TRzp?-5IE?G^lEy9>Xg(F-7#*#rluaMX@q)vv1F^9cHdQJnz=mpyaRnroZAO?DQ zOMj01wZj(s_&%jvs=02{-Db`uy&v2|S!bxQzQ7eXcF6Q%k>g(hW{JtV^_|>#-O=Ky3Zshsn_tlyms4h&x3bI zoZBh9VjBjRX+Id1w9RJn4TDLl2WNVEe9=E-ixM$3zZJOta+@^+p8-YUoj1|D*q3>F z(_0rfG%61w58idNIT>Yk!}SnnBB?twkBmXjOpBeRb0)Yl`ozg6f{czl`h36VvOAkw zurVCV-))ZY3u{I@2T-2kZY@kUO=X($H)O}SFnM~?e`@}jh>g{oF4HZaMty>;?hX4$ zt5@rL8rd#_HF1ov^!p3VSGov_BPy8vo2C1D!gLSzK@i{Gbm^DTpNJ3L*9ZLMj@2JQ zs`|{a?9dnK2}f9TJf8c!cEhAf2-i&R>o!A=1wUsn+iFn7;0qnCyb9K5Pbb7D*Wlfu zn~s7&pa=g#ChDwfw?!V6A$}hgYGpcM1)fH#Pyf4~Jkf_l)po5nm4%@MW0K`KRYrL> z35PXY*v6f6#!JV(Vo#!j|EzD7F!}k+45t!x7JJ4P_yy(E_I%OUawomXnX4pCZH`iv*f7meP+5>8E9pcsCiuG2~uy z>8gRsWQ=}#=(nlE9W=BFD37v9SkPTBY@Gii@dhl~s4VWDA2JqSS9d2i+Tpij*Dpo= zd$ip_Qu&YUC+9N89ZARnCW#ct(YMZct&)Zk?;`^Ig?}kr#RX$yQ<}xuyOm@)+cEUR z$<;o~QswLAV?lP5hr#g{A*~o#olMW_{eIt5-FA|q;UGhmhYf*xD{@rhu~_Q%qpI7> zoSf%WKDPrpjc9<_6S*5bS*+}LE1fMsplUV}KE<6b`s~Xfyw_i_(t-9p5F8{ZUSN`8 znq?AdLR)&xU3v<*B|`OuKVk?Y<~=cwfU1%EeYIo9+CHirf2NATew4m$z0zS_2zNK( z!a{Q&7`&{f3Plb#ntMEYoTkT3DsOw2?9h8pQ|fVZr8Lo&o3sx38KP=FsG!)M=%@C@ z{pN(b6%JCuF|OZ9n9*}FD+%}2 z=K0p}XVjedGHol>$PPFWn5^I-ZLSg91)3L??QfI&>2(l5u1kEg=Py7d^(Nof-Tyvb?lZqa~1qi zI0mo6`!RM3!XKGU_D$YbaDi^3MdVV$UY-pC}!Tj=XcaWqkL~i2a$$z?L5kZQ-pwo;V)mTPUHz>YbYwLe6eyeuu3z+ijO# zJgmSw$+alPeW+KT!M+t6d&f<{dwsxJ)bcqxJc!elmiQ#n4vjjPlw7%Nj!$m9EmxSP zvFq9qGu?#<9DN46L5W(q+JCvp(QGRJ{e;Od=L{%qDeH!xhsOMpGxr{fMBd5PXhxyv z5*7Ws%6V9Bf~Z@H&vIn!wqcv))b>u57hGq?-7@Y4JhxWd<>U8Ai>YVKUlU+a!O-MU zNVufrrfgmoslVm_v)Sb3OR_Sl*mNaFrpg19;8#tu2%rr_PS($&gB)pyM595BaT8*; z^|3Hd$3fqcI#b3$lI6$I9}UZvn+pa8jYkdFa{mG+8HP8Uh^zf=H;# z_ur5xBm&4B$m){4^s3}-)c%h!A;Nl9dw{jcG1QvrQDw|pE+&L|wIe+l4%R$KrRW`9 zNl4!K6iqxU8gnSYpMl+*igAqSb7pF>g+M3ybcPZfL6(@+&tBKy+r(^e8KzY15xE`SgMB>83Lv4v{;cyxs*AF9U{jeMbRhuiEi=AMxl9y(zN>kws^jel6q z7<8RmV?j<7u^maSNK0C5IJn-htDv#6KFid6qVbb5?^`=OHJnbEyJ$s0W|AKJ)A1k> zm7G9#Co&;eC^U(&+K~&_> zo8r^yCSjidaffuqg?#oF#qR7v1H;g0NcasGV%!R_(BUzXUeEc!8+9F;tRX(z*o{o3 z-rK%JO#G`UR9El<#eYBCR^1Fo{#a?3rQBTkBBKmOqmv&|gm)UX0vLDtT-~xj3+g$XQ*8!Ivcin%rxZDjo zofE&gmL3z1Y9pf4ePabL0MNh;7P|QfZnYk+1$rJ4!dJr2a4sC7KYvmYp+Ff|Rf_-K z&E9E+Lh_})?1Z;d7-}Wl74M(!Zu@Vt6-<28%#o)wL=nV}n?Ba;{UU-a*-mYKXJ53% z$!m0C=4VsRa_mA{)l28?8Y(y_QEXcgV$ZJ;{%_7C%58D^eBq~Df&%a?zXxq395k&O z4DD&g1%?zLT>pc@<>T_olXe{(&2cz4tylfv1}6`6<3N?L#GEh#f@DzyY0dMvq?n86 zSB7XSJO9%=Tsb8>Q4WgeK@xNkebuRwM*@o{PZ8wj;#U066ZAiXUI}2o7C&m${q@UU zkU%D5)K4xAod2vm{s-$#1~kILd#wduzbxbpV1gwTQi@-5=Oo)v00gguVSV~5C$J>( z2LKaH{{Ext>z*k2N+3W!CS!SltN-`Ld*n~x7*WxwX#Z+QT8jeYV-%eK#7+DMIV`CF z93yOSOzc0W^54x+E>eJe9EfoJs^j+tmi#@?#DnbW>;J3&ijM+d&_(_4|7t0s{s2(M z-fMWPkGcv1JKVBKd>Ybm?@2B%wAH_U%}2oIQsAjJrvkKu?Dt>pw)l)0@>JXgmGjbx?>G=Lkb8rBGwe?nDiTV zBLf+=>8H@p&;u|8CKZ`o*`h&fwfkl&nmT0?0t7^*j_d?7Kpx)^iFOPCE0d0&(X9zS zi+Odof1z0UvAy0sl+5Ds3!GKsV=PM!AV2ufItI&cv3q8O>U>?ASZ%PDMk3GwAqme!bRZyETZjaP4%yHIOTpY;?fbCMhcFJ4aL+V}J2j`El5Q z6$a+QZg93DH~oDGPb=<84WM+8fl||Lu)Qp79s`K2q+9|f!|7*T@p?4z-=pa?SazQ; zXT;T4637_zT<7%S=yXWMLeQhosO0YUGgozcfrau6IREe7u*c;nWZBoyLbXvKgb9!0M_NEINE%@BFqP4r7+(mHF9|?E@0|Ej7Qnj#R;ZJU-y&s{;OdtH; z5tvbKaS1Xpl_1t_jUW zF%OL+d|%7Nupx(QCqhI0po}Mz_pGMg0lo0fU z6LBU3;9!=epGz&y8UZ&_uZC6|$`heAh!P;LvllZ}C{N|H{#?4pa4fLjpHK#~P|=ak zpj}UVe{~q+7lJ8;nu<<#P!RrcFW$6QC15+9lY}28qCbki$r&OpIHJxG{g*AC3RlM083~W+;vB5LOn70yR<}rMEO217`Izx z1_n$*ySUNd{*Q-#+YcI*aTuf@c8-oS$2o@2UJ$htTVJ{GN`I?8-pc@a-In(i%m)EP z7GE}Q!wD>VkPD}aM1MbX(0I|E=yRa|8z3>|=<3)S(;Nm_antX2T#2QGTynrmG`xSDuc}psfywB`KiTLt$dpVjC^z6fgaWJK=*S z;&Mi{Bfn`f3Wr6L2cf@#;r6bB$Pfk8>@nw9!+1zTJQ(aY%z;RNoan>yRYBcvnV7|j zGRak8O8mhyV&bsu;{c-mk)-5kG6@H%QYXTbS#^I`^bK8g%+!G}JWjc2SD^ZKDpjG~ zeeS{nfC{EBa92}aN(NP(3OCG8{^m2Ku`4TDx!8Oxy(M5;1IUEa@-5g{_NShDJz-T2 z$s=zs_ZLcuxMsDQYAsbZ8emJIUaQ#FL{_{yN+XlOj>W$FV0|g`SNm1@H9;|CYsgXz zuocL;LsK>_;f z?`P&#FhNOe`WepeNzZ9doaACkd-C7I)N?u=-9Ft{Du|Tze_et_=l}$8`-yWJ;kI2HT) zHHXRVF;|R41Pg?_Mz9aBVj0M?1$=G%m zyfylR4R#k9<)l*G-xmZ^cdd;7K}covssf2aGv>f1RUe~2cBbpic(Ub#Pi)uHlwD)n zWn4pTEyN!{1^K`KyzY@t07=|3)iw2b`tO80mwm-b0PD^fbF>3Bo-Jh%o`q0rw|`c~ zRNU-)?8KG={rLkjV=S!-DxFFQGL`G`!?+A3Gr{Kh=0H)CZ><6|@ZKt3T_wT9@xYM&eKke$%;NdP|DKCECT zWHW6IThJmZH_Wm(CzRA8p!{NYqEx>uP#?=2*Rc~Q-moj)P^tZnqvJ#)DbhM_E;(D& z$YxDl1aEwxn(Xgm`++yDQIuJAxC491{ao(!{9GyGlRGe2W6WE6Qs2E3iRQMo1j5l( z%Y_O1@pKwz&$yVLP@NBn@yAR&S}4_>5Q?-iJXXG5vf9NB=IXlkaOb0iAm}F=R%`qe z0&CK>eqBD`qglfv!j7$w{ImM_cP0J?mQNcT>Bsr0byN5JUo~nPIZy%1k56r=zn(9d zUl7aKdiV~nZ|nd2+gC0Wn@}3RDEijJ>K1I@)Hp|+_Rg{Y*Tn@cv=}FKen;`DT{^w7-8H7Oa^TF^)lur7xDHVdK&kYb5Xn zHWCyRVU0o9b0pfkG%&MaW*w;fFJOO3k5|Q+wkR<Ca~Po~gQtM! z$H1a44cDK;3rXtkRBW=~Eiv6S?s0!Dc|aX7LP$bbLPVV+E|Pz`dieEECphG>jS&A% zR@r&C<9(yq+$G_Pr|MIE$wjY0>)WqhvxbI1LUsKiqS zrgNXdXZY$XFwe4l*^snrGy$S4*Z~O0QgwmhV8Usuif)^`4!{PWJUR-uSM+WD{P?Kb zvXKl1aim2A*Zi6q>? z3KgIdRPuj5@d3HGB)jWxSMN?30d9xd^=a{`{@5H~X)vw!dKMGPq*wuorvn^a>s9ZA zxhe@D1%knTZ!#(}64`V*(+`N;J!~zh{yHW7F@+DuoI5b0!Q&Cb9OvFgN7qH}g_PU2 zFSziM83IUsA5A>89rT-B?3?NBL*D@j@h@>Kd04uUqoWFTcR)t8VRx|x%eM#6OQ}Am zmI<=?omUY2gWGOPk`=>bMWtB1qMogf<<+S^nMJb>+J-<^%$6hp#yJ+Dy~$Gg+q11$ z`R8lF#0>d|&qb;w(E#X#dXMf+|u9gr4VG z4FY7-_%v7ydx@3s368uSD;^~9WpBIc9bUhe4>XjnCjb-f3n22KV>g?OOuD;v zo+-6GT@x$#)Y5oUAe0ZR7dHl@et+hkL@Mh5)>g>1*rlFBqp@}hr?yfq(oQyRGR?A;l6^gVe6-1Uy8<(`#!za+z#GJy^x_0 zdWlArIDo9Da+<8NJ(y+YF8QpUGgSo~e6*Vkjpzijy$S4-jiMbb6KoqkI{93sF}p4}?L)77N=2;Q3^K(% zNvYf_?#M+>4Dt0Wrv0Hk z7^V^u#y6nm_;c-ZZ)eX=g+We=Gg^7{RAhz-6zt6L*N;%esg15*Dgg~2Hyu`~t}mHH zMA8XeN(e^Ye4Q1M5__#%1N#U#IOI|gc_SPa>Z;?>AJb;k_ZLr1$GEF!;&tE70=9CA zCCFtLc2BPs#`7GlG-_QNT(54o73Equ#@>D zCb5O%BM-1-%Uhk%Y3>)QRm92^-l8vm{o>3jx1?JlGwp0DAP%IgVshh!Bk0Bh4H!vz z3>-jb%GrP~$sr+$j$qF=`lueeuk&vA&ZZM){jz;e%Tlv04v2G25a2EpymK%9>1SQl z9fmuH_~E;ophW@-zodBHs}7oH5lp@GclGtte^qnS@#=#1qn+>_wF$sK(?KSLF-(LgSZ zTfe78fTvX;v4DT%ceyIQDN^^sZpb|*oCC1!8>8f)jYQ(={v{^eVo#`311kUs#neE? zHNp}YMF%891zZVEv|OhVqr;y%aQ!zs6R2f+!rJ?iNoe_UTdnN1#dbBJs#rz&(wR-R3f^i-wOcXJQ zl5~-=TnuFnyL0U5UJr-lCmTSh2*|dSLgKakD1semOZMEImD|0ZJpQk5_X33=ZB+Kq zr*2dba`OHi0Z9(F<5gc~b7@6pgGDs&9p98pF1JR4C4BUt1yT1`ZIwm?J_<1kH41%t zD%+{y+P)kmJ#!*=xKAHYwj7PtSj+hO!INCsCG~W4{hzvoih%|wek9#gW;aIT;op*9 z$IkUI_HN0{kdxCr>}C#)y;^d%D@ndNcOQH!Bg%laJd)AHc2h0eiK*zf&NY>{rj9(brS^U)sNpU9M2#EuX|OIF-LG!bJh$aJ+O?)~9gP34#%Tc5dl24*t&dF7fW;(LUmF z8S{E>zf7uTm!`yp51^Tf_X|-=T6}W0r1`-}?PRwds5`j1Y+z7nJ0uPyv^4Y0G$%&3@S(2`_}>E|D*mvzza*LuE)wmcCs~84ziO%lW6_c? zzr&*i#-wmH0;DW!3t8jBK%F+5WbG!0_0Mbs+dTXit73K-{WrX>8}-UFE?5g1tR{gK zh}s6B|I4V41i^4^-nMU?++8Lsw#vdvMR$rUfogp8D-n2Ij=V$1`&Ly_d(mkkCDN>x z`QYC1Z4#cIi>@>G6~_cKq%KH}XQz2fZPo{Q^d9m$=DY|dGqhoEA0yf}YT>Z-^z=-Z zZg8~tu^6HHkObwBK>#rBGQO^@Jc&@4$A$WT7!$tTn2MiIsuIcrulucqNH>>y^J;; z4$b+V0^>HA7oUh z_Ft#-l&H4#ESU4~X#L7HBpE21UJJN4@*G|M(Qx`kD!JY%?SqYtRPgHo+M#<@io{9t zi7Yo``8pDEC16*g5_0R7aubjOCr3+zvdx0o>8-!S<(x&9BSnR#Gc{PVP8zE~sX>F3 z*RV;#pRdw@=VVR-d{&1^~_Ux}6Js;Jb*P%4cs>??V- z)4NScZWSs2%I3&Di((mFb`Rh6toqqSaouYDpzCtwKb0Fk=C!@zD%AIFdB)}ZMQiai z%38`lCB_vsXlWN7AWip!G{-poo*@R1IMF89 zuta{}vpA?DgDR7259K=K!FT-CB;2!%|Ef;4 zwK+0c?f`20_8NaxCrfd`W3(#ReeTi{7+6`L>mV}HVz*fcUI1D}6TiN{cG;W2xw<~p zdO#0#^omTjiQAHongSPb*`PiTma1BC4#(B(j7(2d)W1rvg>?oM0(5aUea98 zwIpRZVkG(|p}LP%b9ggtbxVPX!`%8_i@duxaTd!J$^ur)^qn(;{sT}gt)Xuxrr==K zrI<0#+fd5#vD=xOOE!s4jDDz5p6@Hg(>jCxB;%9eI^INm&~-Ea&0}{i77~zn7{&B&PN!Ri82YI~Em;a{ zH&VB_5CCIlNd^t2QZ*sq0CQBSyD+z*uj~^kuF&MrgvUPSavTi7?sT(jr-_CO^AC?9 z$jM*{;gQ#*rKLs5J=&p#(Pl_D+2bFBA0y*JR%%25v2r#}xFi2%E9rYx0bXfQ5(X>=+|wY>Bv#WdkV1&t|J|2TP#AS7^4J-&LF?c z`FB{9$%+RZoU)~owv1t8ZTB?slQ*Y#LAJSUp1@GF7s-}4JhAT;g?R4uf?TnJi|X>C z*gZuBBj`*6xaEr~&&GIE1MF9a-xm|4fB#-YuHB1{xsSJxd3nrB#fmNS#t->-(sHIN zDR|!EyWX>aQRibZx_!A8q-l^i|{qvCqXPm=Q0d6Y($H2vniK})Sy4?v*m zj4S?(CFy>&)M8G4sf5FY5^5>OVDOtZcUT&nT#!Gb+i6p5f4mFc%#qRMrNgA`t|A;y zaPwQ|tDdY}(=7?fD8} zPGGaqhC9 zD8MPT&1MWV#4~>T1_X~bhh0d(;4Zwx8c7^rh3jkl@kHnFZ3#OIxhzMvcCFQNmabcY zB#1C`-RtAW{A1&ov7ILAbqn=sh+;l35E3`Q5XDsNIBW-9pMf$a9(0Hf%bLPUccPDnsH{F6+YsJGFiG{4@;7G(ZO1@M3-7_z`w& zGVv-u47UR5HA=O-QqhDX2qEUZ&5Y(@wVi0&ORA&S9YlWib^|{oor`1++xhJalle$8 zWnI6|MR#!F3&~8MMDxS+mohhv^bU8Le;@S8-vVt|$z0f6p~4^q$pA4@@)d|fM?|tM z@Xen46|)kMNgkl_ri&@Z&(&;yKNek`d#6E71E|0IIiNh)`na5g<=q@|%=SdPm{d&S zD*4{NQJHIJ>ect%|MHdf5GDv|BVgvOz-&ZF$SvGP!pf3^0pQ1CdNv4L5Xwx$dg7CA zy+lqU(N4~i!%(2#KtIn=w511a#}(8a`D}eY_(jJH5};nyNex$AU2;8QJh#x4MHRMF zUsR-ujYa2Z=yf3xk&2p|Bq{TCOuI9-kUSXDeVgG2k1v#ldEaPu_`2S|$fkPEum9S0 zG`zP9=dMxkGhaQ4%wD^&WO{OsOM4a*Qr_5|J;XH#xVa|+B*inAlHPan9Y@u24X;(Pe_}r?AV|r zl|}>fDhmqor39N*Y@;Bt$u4g(qBM-<2^-8}Pk)N^M?b0>v#EB;d?1>_e0TOt z_d`A*CKnfbZ7=BHx2b8)4Vr}YNber69XAB_O@_PtnnCRRX@$5bFc;E5FpY2=Sso3OLnX1RSH5)}ZYN9f5|H<4AXzs;i=l94?yQoeV8nbeqQ z4uzUdLjL>XOgMgqKAKj2E?xCz&LuLz3%-O*sRgf`Np*ey0M+R`KUd6E7a@X>tGiup z-^t~Ox?lCWAMJTFY0)HAz(vun@}I4B?}i2I4>@gAl9)@)qYg_dgdTpBP}>l$)alol zd$nb_Go1J8YC!UdV3D+{P7H$|ww+(1n?IbRfek&%&6+gNEde4XxEz79Zi z44aqBo4=3OqnIU>OvkU;0s0`i3=TP>90H--2DJ9oAM1rc!*3*^a2OM~&hwDH!FD|W z8J~q(T-E)(W?>A_{UhNye(mN3@dp1cTkjQ<2D@Q_o3bt}{Tuk7q$p+RpXG580_`JA zJ|v{1LeeR0y0vf~oGS0$y%Pf(8GC|4ZBikE2^udEquSe{7(4pdi{@)K*sc z)Suno%jN6vS6RBKzNS@uCxy%W8pxVGN_YPL{d?wmt7QIBP-uD8|Ld@xIdAPL=qVVT z_8J=D9S<7D`5pj^K_W>WD}<=sRsbbuC(DgIS*WClDlDsdcDZa@I5I!4uEt_bbJun) z&a*QvqExCzwmBG!>FnGm$mM*P!nY7JZ3l3c;r8nEj{S)j`h|gijg@|!2_**9!;J{S z(F6Vc#Y&QDB&ECi3B6u9vu+n@HiIe*`Xl%O_>2m`crpDx@h^1uEFCOq_J-h+Jx6*K z0}QAY3r{=hb;W&T(iR_?v~2N2IbgmtDL?MJt>T_K599gOr{`bLuvE5j zH~}t0jl$0~&bMHbh1P(8fPu=*A*r2lfSlX7^*^rCf}gwN1hcGbR72 zTL7iyLsr8ZI{4@CuT(70Yk~51zeS!{wD6SmjL8Ylw>Pv_uo6qnF3)fDEA<;Qr=Cf@ zB4l^3e>K5{Hq*}UE4iaM^!lS7$EWf^rG`qwob9F~@t$v3hQN&SJ@(^RMBK{F%}uPb z3w?_(oKJY26$J8?u{!NGnKe!xN4uap>00^$kxn*0fmMOXcTfn6X=!3PDixWHXI8IK zI_#n`)Lu#)sTq-ZsxKcWvdR#wD^da@o?||!{&J$sa(#<7rI;;>F0Y(4Q6M#M!Ygud z&};AADHcT<3DlDl(LPegtG8OP19K*dE_%k5-msjQa6)ua#$a9CrwUc&7glOz1?%55 z(_+IYt@`L{+&e+%8inFUsomIs=a|PwN;Q}1h}CT^mlX#8#p1pveQb%av-V!dvpK_K zccd z-Q}qmgg=gLe3)dO)FQnp{J%tp!Ebl>MMHbSwYia5$fvdRvM2GJYx8OEbC=tBq}0e6tnp>Ps{}{Wj%vd8^Mjz zvFd5#iRcel4RW4Gl%WPda}KRr-ygMJrYRK33Qm=(Z!5AYsYIHwb4o?GtqBY8+1TH;TVbu@hjxf zYE=p~Iv&xS-d{^V!$AM=;|3IAA0?+dk}(0$2R|nfkd_`Qkk2C(3_yNlV#1!o!ASsJ z2p|`ifveMPpi)k4#9M1i4fyUY57I{;%e(y(iIpA|@t&ggwV=9g)+=<|}x6EuYvpk#|0<#yg(Z)Ebn}9V!9ED~Aj~_E@gL&JZ}R z!kW+4f`x-N22sAUCSxZl;Fqq<#!qk*|(^lQ-28y@E=6J^RWTZJ}P5)VHM zX7V!~bsv(g+dcxCSFtf@=#BS~dO&J=IZrwk2JU754!!;c0E`F=-Ex`5gy3_}1;y97 zo<(#8qDp{3^{=Q^KEHU0{he0&n9k#aLVfwcY>T?nu69w}#~kZ)9`fQ3xlU0OG6b+_K;|*5c(9a3f!Zk6R9Ct>E-)m&|d%chq zqPPHBK*B1$8WH{56pK^X?R!B~HW0A$Qsin^z<{6axA@vr$96#aTQd7UXa6o+#PB)3&yY|zo{A{+uh zP-9M9mO9@hQ|S1&iu!R_J)4j7+06Q!Fj$}Lv=w@?2tcpFd&XqBBI~Mpxwj(Fl;+sI zJ=jK>`{fvl7W|EJRaf$}E~@$c=`vd2`;QdIqQWI+aJ#VRNH-KY+O&S9D7(J9YwDCY z_PGQwg+ai<#_0Ej4X_L|dOMS`Jjzl!>`e?P!7e4@Fd7e@US7lk=QW;0I#0`ro`zCI zGysf&>h#UOynVVE;Sq>RbTWAq0)Mxs8_pP~`{;mW`eguMYNc_u+U3;ix<&PJw#o58 z`Ktg8oDh;RP*vKnwkSS(D;Z36;ih-dLS_2XRGBe27|PpdzWH%E~(yWsmXQRvT}Y_9F^ zn{$rLv4J4pV?L@YC7GKjS`8D<7N=njt>E)BxH(X1m!?Q2vkX@wt1fL@o+O_U`ehhgPYOJq^W zGFwcDmhSGUI6A6o4cQ;xjb{AH>feJE^1$1O~EG9GMERalM7` zsSNGTy=inkFMI?Ya~#2!BFn8n8^v(~k;TvwL{AVtBzy1ES1T3iH@b@S_`zCJ*N6G| z`)s^V&cYQjQZ$FVI1ojs7uuxPA{=U>v}9&ys~AWOPjxWnJwE=oO5XOL>$+a;;*xdC z#+HH;-P3qAn9HszPZgZgUO>}ay0iH-I_@hCBrNgRa$tTuzR;< z0`;dSmj_ZvJ^~vR&l+L=dA`Wt#gjMr1@`~!ms2na8}(lOlVJMq-FD?Y*-AD6;9mXw z{gcVe)8!`cSf0ceTs5$eJ;a@7#y{R4uL3^Vr*ttB$~J&)=qS4SGsj z>~_xB5yIiy9uTNk?Vvq*c;p&vJO==p(qaBTTk~fMxBWWHv5j+lV-KR3xHh3N;6~Y% zeXR$4ESrF)K#in0nyr(IS)#v8t=$VDrO`ok371|eEVb?TvhTvF3OYb}M$@3|^-DOK zvrW?Gb@#2Mx+xxKN9xU1vQ6$}@tDq6MBANpesakb^%hygs{Jdll3{)Z;+peh779yi zf+*OFTKGO>3sRY?)EYE5ffauC9ZT?kRRVqaTw#&8Ik8D~9MJQGgU5)25-6eM!iX!N zGE1&^$dMmrBjbr8cloY>p2v|iO2LhwFKR+w{1;24AqB-wP~9!EGMZQ=?KlT)mn{YP z@M$rbPHY0&%mb7^pS3$3Dtc&rBV9nNfdg z=GBj84$jfEjSY9NB2KY8LB^yY+B^rsN zB2$HiNzub}SkHB5HVkNnNIJfcV6KvPgpmIEpQ0hKQwOuOUM0)atN`Qep2#S+Ux-Dj zcw#_;^_BP!|rnU(<0Tp`kl)Ub5~iD7bmC*c8R0D4sa8jlaw2>SHnE+>SNe z*MtIi<#MOf1(am6PYl|}(n$)rWopJ+IvnZQ31zX$&jW_czWu0=nriIc@xt*m#96LR zn5dV5tR?5C$1Gr2;JUXT!T9|5Q0KFB(cR_-y^rw`a1@u|_q3B`hK0=zca679&fa)z zjvU0vqN9x(Yggs2w^~EJk4RGSyc-{f7pH*JZgMZxtA47$k+kUNZ|epltG08#w=%bA zh7Rhr1nTc+kW|{7I%OH9zgLtj#CmU{Xnb>Pd1c1#zLnCvSPbY`lGT8>U;MEiuJ^E| zCL4X_?58;{Id;FA9OW5{8RLC78t#_|LlpNnCtuWrQYMz!7sBkJ^rz8$o>M3y9dKN` z9SP&EJe{#EC_K%dHD}4sBW>W)Zb~9Oydcdk`&^n8GAxMY7MM62|WJAWEFC`ERaG z?lU-pUocWQGPM?)!sO_unlZQxAeySQhUl^#A8p$0t&zF3$a34OB_}DKjZ3u%-b`@D z$|flm=*($aaS7i@C6W>l{1Uj_mMoL4eMEcQu@9!lbDL?I6G zDwW2XeL@mbO=Wf4y}8)3o_Y87k}yWv(JUyvtWJSifsaPJDdUD!Ld(*6zaz`%hO9>0 z&QztedP6i_X?u|ZxrlR*?0phrvTK<5&?|hwAu}v8YHAHYh;Z{)&3;%ws?H5znovka zFr0LHBv>SD;OL>41q~4}09vYzTJ4u(cYS2W0S+hY+Q9}p#ce-k_a`;a)>hEB1aw5E zSF;Qv5z*a}TkTTaujY~c)51Hu2$1Xk+2m=I&~IPj{emRXnX0#BT590@%8q-keHI&5 zQ|i@OFS+tYIxUV@;X86Nx3<+{1J(MQhpf{Qm#rCXj!2K~ zJniQN(D0T=3}?o(E@yr#+%H>%WnwnfwBz`^5^MEJ-06%mOTZ#EwnBt#f=uUD)4$+R zgl6~@_&^Gj2{Nrm_uoL|#}VeZ0h14#VREYe@Z?(wJ8xPj3JVKnOg`6ErzprOmPv|T zZCtU~ZOKKr%0mNEVb-FrrO<5*(AYyi#KdY@CcQn9N5K+=X=)|{?fWykwAtO|259*w z?9<(r(DYKlWSpHBjYyPWe3F{9t}`LEHldtW42AW9GSMzddNmT;g;$iLx7#u`oUKxN z;M#HsbcHCVw@qkSEg_-@#St%R#c_R*BvP_TwF>aVuJ8_o?5MkH=ddZB*z*Wo7HMXv_jHzI^{ix-=;TU{D_H-=+m8Ln=I zC@?))QNt`_d3-|I_Y%K+HY?T3%s@o3xjG(s&LG$VWA1bm{lbGMdj3N>q`J*?(@su- z0z#tTklN~?YPOf{ne56z1T}TARHWZPV>u~NA<2zeHC?Q%?Vo(RP*voLgE-{Z7T?3s zxXc9mQY%(4Zv@fLFMUhvw$(khTFx4i3vE93PJQ?-jx3$g{cH1NGw*7 zXQpzqdwe@@nu$ty@O3)Jo%ZV6+;gH!koWND-O>)&J>{%m1N*D6#OHr{B)kPOCSG@C z;RsEgpN{BO+>S3#qjRx_c0#!nl@1n2R2BV+T|W40abb5>piLXA>bIzrj~7bn+R(3w zL=EtUUj6(l@do5}(Z0(p=q3n}#Pn5m;nt>gcP;)1Y)w9nr=F>n!mN_P)j{nrW;eG__4d+|*<$P@klQ z4dMiwD^7e><-{V`=(!)4EqUm+yo%53)e*yI`WUdJqjAUYp7hiY!gS~aNP=-oxK5`nd z1|(ct$4c~%JjjXn&*4wRQt7)Mk9D8QBf1oP817Mb>Te#o5f#Ql*KBT-UnQUx9@Uw4q~X zNPcAc_Q$FG2&c7z=n;Kj%sCQFV6uDoyGH0&&98ae&XWR;4C2d}UhP_^>MxGi<;ob_ z34MMUeJRVqE@B0L(bf9d8ln3o`DQ$m`}^bo(vr#BMG-@7Gs;+L6vt0_$9DXJC0nJ7 zq?Tq1^it#6(IZmlR!V}bR^!J+Dc@Ot_s;r^%;+l}X@>FV_*cd9;JuSd^4vC-Gm7Jrvx$T* zO$H79X=nR41MJ+zZhhb(fXksM@Vta(i-R`O7um&b--+s&onxhbG{ivQ2 z`}J#tGU1>AcYbQVFF({;q;XB4AKGbXal>UvP%N*dx)y}@I-g}Rja)5mCl&6%Gx;Fw z!i6EfD@xg_BC^f`9i|AAsu@P^+)EZVktU z$JqMcsghvnXbe^%{}sfUL4&?&773wa8u_E8OeN*t2K3(Q|4QkcR;EMe_1a8wrGVaK z_jrKYk|X!i+?K{+W?w`!?u)@YQtxs{(q-E`*`)tEBAVN~mn~}4yMeQ+0{@nyNM`Za zDpYHPnZC$am&QnY+1F;)0aA__*zdkvKj9lVQ{)7uM@>1l3ifYooYpy4TUo?~2e;wa zssGwB(?Y|(VIK25`Wh{q{oRT*L0@%kwup6R2?=`DCpHW6`Nj&AfSi1lXYp&}ekXtn z2ObYZ6Tw?`)vkMrhEKiPGn2VI2IubT<}%m-uyHiSmC|YXzkc_PF0t1(21(ia4Kl)w`noN?&Cj9_0c+-u*Uw8l zAzPq-su1N@gVAPvIs`iouf-szx=3M*{s5=xFYzWBRPXeyJ4=Cqv@~>)u^=0WeEqklKSQna zM&dqw6$PdEC7QWX-=$OvXdyo`uc_-`Ol>RTo{$ zB|M*ZN{lb7rc_^(b@I3TTNY}8#70g#_i`(!!cIUNTGXu>VP!MAY@&#)Y@%#aK_vAx zp$RyW;j)lVPAdfucM6*IvmxzDMPo??ox~0;X1`nM5xvA z=6Dz14f;PBiGt5O1Gv~LOc8Jxgwl0`nE%Al|Gj0WaX?FNx^p?ku<879NRMByH{4?< ze>=SDvp>7_F+<9y0jN-Q`(q3}NtXgr0d&AE9Zt9(@n5(1HGn`Np@~rm_;V$F{EZcF z02kq+6HxkFg$sC%_6ERMY%{u__A~QAqe`wkOxfWNcd!{mK>}} +- [x] You are a [{{< fa hand >}} Customer Admin]{.bubble} or assigned another role with sufficient permissions to configure workflows.[^1] +- [x] You understand how to configure workflows and add steps to workflows.[^2] +- [x] A webhook secret is configured for your Jira Personal Access Token.[^3] +- [x] You have admin access to Jira. + +::: + +## Configure the workflow step + +::: {.column-margin} +![Create a Jira issue](integrations-examples-http-request-open-jira-ticket.png){width=80% fig-alt="Screenshot of the HTTP request step configured to create a Jira ticket, showing the required fields described in step 4." .screenshot} +::: + +1. In the left sidebar, click **{{< fa gear >}} Settings**. + +2. Under {{< fa shield >}} Governance, select **Workflows**. + +3. Select the **Model Workflows** tab. + +4. Click on a workflow to modify or click **{{< fa plus >}} Add Model Workflow**[^4] to create a new workflow. + +5. From the **Workflow Steps** modal, drag and drop an **HTTP Request** step[^5] onto the canvas, then connect it to your workflow. + +6. Double-click the step to open the **Configure HTTP Request** modal. + +7. Configure the required fields, replacing the placeholder values with your own: + + - **[url]{.smallcaps}** — `https://yourcompany.atlassian.net/rest/api/3/issue` + - **[method]{.smallcaps}** — POST + - **[headers]{.smallcaps}** — Add: + - `Content-Type`: `application/json` + - `Authorization`: `Bearer {{Jira Personal Access Token}}` + + ::: {.callout-tip title="Use webhook secrets for credentials"} + Instead of entering credentials in plaintext, use a webhook secret: `Bearer {{secret:jira_pat}}`. See [Manage secrets](../manage-secrets.qmd#webhook-secrets). + ::: + + - **[body type]{.smallcaps}** — JSON + - **[body]{.smallcaps}** — Use the following JSON payload: + + ```json + { + "fields": { + "project": { + "key": "MODEL" + }, + "summary": "Model validation failed: {{Model Name}}", + "description": "The model [{{Model Name}}|{{Model URL}}] failed validation. Review artifacts in ValidMind.", + "issuetype": { + "name": "Bug" + } + } + } + ``` + +8. Click **Update Step** to save your configuration. + +The HTTP request to create the Jira ticket is sent when the workflow executes the step. + + + +[^1]: [Manage permissions](../../configuration/manage-permissions.qmd) + +[^2]: [Introduction to workflows](../../workflows/introduction-to-workflows.qmd) + +[^3]: [Manage secrets](../manage-secrets.qmd) + +[^4]: [Add new workflows](../../workflows/configure-workflows.qmd#add-new-workflows) + +[^5]: [Workflow step types](../../workflows/workflow-step-types.qmd#http-request) diff --git a/site/guide/integrations/integrations-examples/create-servicenow-incident.qmd b/site/guide/integrations/integrations-examples/create-servicenow-incident.qmd new file mode 100644 index 000000000..7ecde2ead --- /dev/null +++ b/site/guide/integrations/integrations-examples/create-servicenow-incident.qmd @@ -0,0 +1,77 @@ +--- +# Copyright © 2023-2026 ValidMind Inc. All rights reserved. +# Refer to the LICENSE file in the root of this repository for details. +# SPDX-License-Identifier: AGPL-3.0 AND ValidMind Commercial +title: "Create a ServiceNow incident" +date: last-modified +--- + +Create a ServiceNow incident when a data drift issue is detected during ongoing monitoring using an HTTP request workflow step. + +::: {.attn} + +## Prerequisites + +- [x] {{< var link.login >}} +- [x] You are a [{{< fa hand >}} Customer Admin]{.bubble} or assigned another role with sufficient permissions to configure workflows.[^1] +- [x] You understand how to configure workflows and add steps to workflows.[^2] +- [x] A webhook secret is configured for your ServiceNow credentials.[^3] +- [x] You have admin access to ServiceNow. + +::: + +## Configure the workflow step + +1. In the left sidebar, click **{{< fa gear >}} Settings**. + +2. Under {{< fa shield >}} Governance, select **Workflows**. + +3. Select the **Model Workflows** tab. + +4. Click on a workflow to modify or click **{{< fa plus >}} Add Model Workflow**[^4] to create a new workflow. + +5. From the **Workflow Steps** modal, drag and drop an **HTTP Request** step[^5] onto the canvas, then connect it to your workflow. + +6. Double-click the step to open the **Configure HTTP Request** modal. + +7. Configure the required fields, replacing the placeholder values with your own: + + - **[url]{.smallcaps}** — `https://yourinstance.service-now.com/api/now/table/incident` + - **[method]{.smallcaps}** — POST + - **[headers]{.smallcaps}** — Add: + - `Content-Type`: `application/json` + - `Authorization`: `Basic {{ServiceNow Credentials}}` + + ::: {.callout-tip title="Use webhook secrets for credentials"} + Instead of entering credentials in plaintext, use a webhook secret: `Basic {{secret:servicenow_creds}}`. See [Manage secrets](../manage-secrets.qmd#webhook-secrets). + ::: + + - **[body type]{.smallcaps}** — JSON + - **[body]{.smallcaps}** — Use the following JSON payload: + + ```json + { + "short_description": "Data drift issue detected: {{Model Name}}", + "description": "A potential issue has been identified for model {{Model Name}} (link: [{{Model URL}}]({{Model URL}})). Please review the ongoing monitoring documentation in ValidMind.", + "urgency": "2", + "category": "Model Risk" + } + ``` + +::: {.column-margin} +![Create a ServiceNow incident](integrations-examples-http-request-open-servicenow-incident.png){width=80% fig-alt="Screenshot of the HTTP request step configured to create a ServiceNow incident, showing the required fields described in step 4." .screenshot} +::: + +The HTTP request to create the ServiceNow incident is sent when the workflow executes the step. + + + +[^1]: [Manage permissions](../../configuration/manage-permissions.qmd) + +[^2]: [Introduction to workflows](../../workflows/introduction-to-workflows.qmd) + +[^3]: [Manage secrets](../manage-secrets.qmd) + +[^4]: [Add new workflows](../../workflows/configure-workflows.qmd#add-new-workflows) + +[^5]: [Workflow step types](../../workflows/workflow-step-types.qmd#http-request) diff --git a/site/guide/integrations/integrations-examples-aws-sagemaker-linked-model.png b/site/guide/integrations/integrations-examples/integrations-examples-aws-sagemaker-linked-model.png similarity index 100% rename from site/guide/integrations/integrations-examples-aws-sagemaker-linked-model.png rename to site/guide/integrations/integrations-examples/integrations-examples-aws-sagemaker-linked-model.png diff --git a/site/guide/integrations/integrations-examples-aws-sagemaker.png b/site/guide/integrations/integrations-examples/integrations-examples-aws-sagemaker.png similarity index 100% rename from site/guide/integrations/integrations-examples-aws-sagemaker.png rename to site/guide/integrations/integrations-examples/integrations-examples-aws-sagemaker.png diff --git a/site/guide/integrations/integrations-examples-gitlab.png b/site/guide/integrations/integrations-examples/integrations-examples-gitlab.png similarity index 100% rename from site/guide/integrations/integrations-examples-gitlab.png rename to site/guide/integrations/integrations-examples/integrations-examples-gitlab.png diff --git a/site/guide/integrations/integrations-examples-http-request-open-jira-ticket.png b/site/guide/integrations/integrations-examples/integrations-examples-http-request-open-jira-ticket.png similarity index 100% rename from site/guide/integrations/integrations-examples-http-request-open-jira-ticket.png rename to site/guide/integrations/integrations-examples/integrations-examples-http-request-open-jira-ticket.png diff --git a/site/guide/integrations/integrations-examples-http-request-open-servicenow-incident.png b/site/guide/integrations/integrations-examples/integrations-examples-http-request-open-servicenow-incident.png similarity index 100% rename from site/guide/integrations/integrations-examples-http-request-open-servicenow-incident.png rename to site/guide/integrations/integrations-examples/integrations-examples-http-request-open-servicenow-incident.png diff --git a/site/guide/integrations/integrations-examples-webhook-run_step.png b/site/guide/integrations/integrations-examples/integrations-examples-webhook-run_step.png similarity index 100% rename from site/guide/integrations/integrations-examples-webhook-run_step.png rename to site/guide/integrations/integrations-examples/integrations-examples-webhook-run_step.png diff --git a/site/guide/integrations/integrations-examples/synchronize-aws-bedrock.qmd b/site/guide/integrations/integrations-examples/synchronize-aws-bedrock.qmd new file mode 100644 index 000000000..ef136a1d6 --- /dev/null +++ b/site/guide/integrations/integrations-examples/synchronize-aws-bedrock.qmd @@ -0,0 +1,99 @@ +--- +# Copyright © 2023-2026 ValidMind Inc. All rights reserved. +# Refer to the LICENSE file in the root of this repository for details. +# SPDX-License-Identifier: AGPL-3.0 AND ValidMind Commercial +title: "Synchronize models with AWS Bedrock" +date: last-modified +--- + +Link {{< var vm.product >}} models to foundation models and generative AI agents in Amazon Bedrock, supporting governance across your AI/ML ecosystem. + +::: {.attn} + +## Prerequisites + +- [x] {{< var link.login >}} +- [x] You are a [{{< fa hand >}} Customer Admin]{.bubble} or assigned another role with sufficient permissions to configure connections.[^1] +- [x] You have AWS IAM credentials with permissions to access Bedrock. + +::: + +AWS Bedrock exposes two primary integration surfaces: + +- **Foundation model layer** — Access to AWS-hosted and custom foundation models through the Bedrock model catalog (Discover and Tune views). + +- **Application layer** — Bedrock primitives such as agents, flows, and knowledge bases that represent built generative AI applications and workflows. + +## Configure the connection + +1. In the left sidebar, click **{{< fa gear >}} Settings**. + +2. Under {{< fa puzzle-piece >}} Integrations, select **Connections**. + +3. Click **{{< fa plus >}} Add Connection**. + +4. In the modal that opens, select **AWS Bedrock**. + +5. Complete: + + - **[integration name]{.smallcaps}** — How other admins can identify the connection. + - **[description]{.smallcaps}** (optional) — The intended usage or additional details. + - **[aws region]{.smallcaps}** — The primary region where your Bedrock resources are deployed, for example `us-east-1`. + - **[aws access key id]{.smallcaps}** — The secret generated by AWS IAM with permissions to access Bedrock. + - **[aws secret access key]{.smallcaps}** — The secret generated by AWS IAM with permissions to access Bedrock. + - **[initial status]{.smallcaps}** — Set to `Operational` to enable immediately or `Disabled` if you plan to finish setup later. + +6. Click **Save Integration**. + +7. Test the connection: + + a. Hover over the AWS Bedrock connection you just created. + b. When the **{{< fa ellipsis-vertical >}}** menu appears, click on it and select **{{< fa circle-check >}} Test Connection**. + + If the test is successful, the message **{{< fa check-circle >}} Connection successful** displays. + +## Link models from Bedrock + +Once the connection is configured, you can link {{< var vm.product >}} models to your Bedrock resources: + +::: {.callout title="Model dependencies"} +Bedrock agents, flows, and runtimes typically call foundation models (LLMs) under the hood. When you link these application-layer resources to {{< var vm.product >}}, consider also registering their underlying foundation models and creating dependency relationships between them. + +This builds a complete dependency graph showing how your AI applications relate to underlying models. Benefits include: + +- **Impact analysis** — See which applications are affected if a foundation model is deprecated or has compliance issues. +- **Full audit trails** — Documentation and risk assessments capture the entire model stack, not just the top-level application. +- **Governance visibility** — Track model versions and changes across your AI ecosystem. +::: + +1. In the left sidebar, click **{{< fa cubes >}} Inventory**. + +2. Select a model by clicking on it or find your model by applying a filter or searching for it.[^2] + +3. Scroll down until you locate the **Amazon Bedrock** connection box in the right sidebar. + +4. Hover over the Amazon Bedrock box. + +5. When the **{{< fa ellipsis-vertical >}}** menu appears, click on it and select **{{< fa link >}} Link Model**. + +6. In the modal that opens, use the tabs to filter by resource type: + + - **All** — View all available Bedrock resources. + - **Foundation Models** — AWS-hosted and custom foundation models from the Bedrock catalog. + - **Agents** — Generative AI agents you've built in Bedrock. + - **Flows** — Prompt flows and orchestration workflows. + - **AgentCore Runtimes** — Agent runtime environments. + +7. Click **[select model]{.smallcaps}** to choose the specific Bedrock resource to link. + +8. Optional: Click **Test Connection** to ensure the connection is working as expected. + + If the test is successful, the message **{{< fa check-circle >}} Connection Test Successful** displays. + +9. Click **Link Model**. + + + +[^1]: [Manage permissions](../../configuration/manage-permissions.qmd) + +[^2]: [Working with the inventory](../../inventory/working-with-the-inventory.qmd#search-filter-and-sort-records) diff --git a/site/guide/integrations/integrations-examples/synchronize-aws-sagemaker.qmd b/site/guide/integrations/integrations-examples/synchronize-aws-sagemaker.qmd new file mode 100644 index 000000000..cc87f119f --- /dev/null +++ b/site/guide/integrations/integrations-examples/synchronize-aws-sagemaker.qmd @@ -0,0 +1,82 @@ +--- +# Copyright © 2023-2026 ValidMind Inc. All rights reserved. +# Refer to the LICENSE file in the root of this repository for details. +# SPDX-License-Identifier: AGPL-3.0 AND ValidMind Commercial +title: "Synchronize models with AWS SageMaker" +date: last-modified +--- + +Synchronize models registered in the {{< var vm.product >}} model inventory with AWS SageMaker models. + +::: {.attn} + +## Prerequisites + +- [x] {{< var link.login >}} +- [x] You are a [{{< fa hand >}} Customer Admin]{.bubble} or assigned another role with sufficient permissions to configure connections.[^1] +- [x] You have AWS IAM credentials with permissions to read the SageMaker model registry. + +::: + +## Configure the connection + +::: {.column-margin} +![Connect with AWS SageMaker](integrations-examples-aws-sagemaker.png){width=80% fig-alt="Screenshot of the AWS Sagemaker connection configured to synchronize models, showing the required fields described in step 5." .screenshot} +::: + +::: {.column-margin} +![A linked AWS SageMaker model](integrations-examples-aws-sagemaker-linked-model.png){width=60% fig-alt="Screenshot of the model linked to AWS SageMaker, showing the required fields described in step 4." .screenshot} +::: + +1. In the left sidebar, click **{{< fa gear >}} Settings**. + +2. Under {{< fa puzzle-piece >}} Integrations, select **Connections**. + +3. Click **{{< fa plus >}} Add Connection**. + +4. In the modal that opens, select **AWS Sagemaker**. + +5. Complete: + + - **[integration name]{.smallcaps}** — How other admins can identify the connection. + - **[description]{.smallcaps}** (optional) — The intended usage or additional details. + - **[aws region]{.smallcaps}** - The primary region where your SageMaker model registry lives, for example `us-west-2`. + - **[aws access key id]{.smallcaps}** — The secret generated by AWS IAM with permissions to read the model registry. + - **[aws secret access key]{.smallcaps}** — The secret generated by AWS IAM with permissions to read the model registry. + - **[initial status]{.smallcaps}** — Set to `Operational` to enable immediately or `Disabled` if you plan to finish setup later. + +6. Click **Save Integration**. + +7. Test the connection: + + a. Hover over the AWS SageMaker connection you just created. + b. When the **{{< fa ellipsis-vertical >}}** menu appears, click on it and select **{{< fa circle-check >}} Test Connection**. + + If the test is successful, the message **{{< fa check-circle >}} Connection successful** displays. + + +## Link the models + +1. In the left sidebar, click **{{< fa cubes >}} Inventory**. + +2. Select a model by clicking on it or find your model by applying a filter or searching for it.[^2] + +3. Scroll down until you locate the **Amazon Sagemaker** connection box in the right sidebar. + +4. Hover over the Amazon SageMaker box. + +5. When the **{{< fa ellipsis-vertical >}}** menu appears, click on it and select **{{< fa link >}} Link Model**. + +6. In the modal that opens, click the [select model]{.smallcaps} dropdown to pick the AWS SageMaker model to link. + +7. Optional: Click **Test Connection** to ensure the connection is working as expected. + + If the test is successful, the message **{{< fa check-circle >}} Connection Test Successful** displays. + +8. Click **Link Model**. + + + +[^1]: [Manage permissions](../../configuration/manage-permissions.qmd) + +[^2]: [Working with the inventory](../../inventory/working-with-the-inventory.qmd#search-filter-and-sort-records) diff --git a/site/guide/integrations/integrations-examples/synchronize-gitlab.qmd b/site/guide/integrations/integrations-examples/synchronize-gitlab.qmd new file mode 100644 index 000000000..c8a9095ee --- /dev/null +++ b/site/guide/integrations/integrations-examples/synchronize-gitlab.qmd @@ -0,0 +1,80 @@ +--- +# Copyright © 2023-2026 ValidMind Inc. All rights reserved. +# Refer to the LICENSE file in the root of this repository for details. +# SPDX-License-Identifier: AGPL-3.0 AND ValidMind Commercial +title: "Synchronize models with GitLab" +date: last-modified +--- + +Synchronize GitLab model registry with ValidMind model inventory for comprehensive model tracking. + +::: {.attn} + +## Prerequisites + +- [x] {{< var link.login >}} +- [x] You are a [{{< fa hand >}} Customer Admin]{.bubble} or assigned another role with sufficient permissions to configure connections.[^1] +- [x] A secret is configured for your GitLab Personal Access Token with `api` or `read_api` scope.[^2] +- [x] You have access to the GitLab project containing ML models. + +::: + +## Configure the connection + +::: {.column-margin} +![Configure GitLab connection](integrations-examples-gitlab.png){width=80% fig-alt="Screenshot of the Configure GitLab dialog showing fields for integration name, description, project ID, GitLab instance URL, personal access token, and initial status." .screenshot} +::: + +1. In the left sidebar, click **{{< fa gear >}} Settings**. + +2. Under {{< fa puzzle-piece >}} Integrations, select **Connections**. + +3. Click **{{< fa plus >}} Add Connection**. + +4. In the modal that opens, select **GitLab**. + +5. Complete: + + - **[integration name]{.smallcaps}** — How other admins can identify the connection. + - **[description]{.smallcaps}** (optional) — The intended usage or additional details. + - **[project id]{.smallcaps}** — The GitLab project ID or path containing ML models (required). + - **[gitlab instance url]{.smallcaps}** (optional) — Leave empty to use GitLab.com, or enter your self-hosted GitLab URL. + - **[personal access token]{.smallcaps}** — Select a secret containing your GitLab Personal Access Token with `api` or `read_api` scope. + - **[initial status]{.smallcaps}** — Set to `Operational` to enable immediately or `Disabled` if you plan to finish setup later. + +6. Click **Save Integration**. + +7. Test the connection: + + a. Hover over the GitLab connection you just created. + b. When the **{{< fa ellipsis-vertical >}}** menu appears, click on it and select **{{< fa circle-check >}} Test Connection**. + + If the test is successful, the message **{{< fa check-circle >}} Connection successful** displays. + +## Link the models + +1. In the left sidebar, click **{{< fa cubes >}} Inventory**. + +2. Select a model by clicking on it or find your model by applying a filter or searching for it.[^3] + +3. Scroll down until you locate the **GitLab** connection box in the right sidebar. + +4. Hover over the GitLab box. + +5. When the **{{< fa ellipsis-vertical >}}** menu appears, click on it and select **{{< fa link >}} Link Model**. + +6. In the modal that opens, click the [select model]{.smallcaps} dropdown to pick the GitLab model to link. + +7. Optional: Click **Test Connection** to ensure the connection is working as expected. + + If the test is successful, the message **{{< fa check-circle >}} Connection Test Successful** displays. + +8. Click **Link Model**. + + + +[^1]: [Manage permissions](../../configuration/manage-permissions.qmd) + +[^2]: [Manage secrets](../manage-secrets.qmd) + +[^3]: [Working with the inventory](../../inventory/working-with-the-inventory.qmd#search-filter-and-sort-records) diff --git a/site/guide/integrations/integrations-examples/synchronize-with-databricks.qmd b/site/guide/integrations/integrations-examples/synchronize-with-databricks.qmd new file mode 100644 index 000000000..ac765fc9c --- /dev/null +++ b/site/guide/integrations/integrations-examples/synchronize-with-databricks.qmd @@ -0,0 +1,137 @@ +--- +# Copyright © 2023-2026 ValidMind Inc. All rights reserved. +# Refer to the LICENSE file in the root of this repository for details. +# SPDX-License-Identifier: AGPL-3.0 AND ValidMind Commercial +title: "Synchronize with Databricks" +date: last-modified +listing: + - id: whats-next + type: grid + grid-columns: 2 + max-description-length: 250 + sort: false + fields: [title, description] + contents: + - path: https://docs.validmind.ai/notebooks/databricks/validmind_databricks_quickstart.html + title: "Databricks quickstart" + description: "Install the {{< var validmind.developer >}}, load data from a Unity Catalog table via Spark, train a simple classification model, and run ValidMind tests to send results to the {{< var validmind.platform >}}." +--- + +Link {{< var vm.product >}} inventory records to models, datasets, and agents in Databricks Unity Catalog for governance across your ML ecosystem and bidirectional metadata synchronization. You can also run validation notebooks directly against Databricks-hosted data. + +::: {.attn} + +## Prerequisites + +- [x] {{< var link.login >}} +- [x] You are a [{{< fa hand >}} Customer Admin]{.bubble} or assigned another role with sufficient permissions to configure connections.[^1] +- [x] A secret is configured for your Databricks Personal Access Token.[^2] +- [x] You have admin access to your Databricks workspace. + +::: + + +## How does the integration with Databricks work? + +Databricks Unity Catalog provides a unified governance solution for all data and AI assets across your Databricks workspaces. The integration exposes three Unity Catalog resource types: + +- **Models** — Registered ML models in Unity Catalog's model registry. +- **Datasets** — Tables and datasets managed by Unity Catalog. +- **Agents** — AI agents and applications built on Databricks. + +After linking your inventory record to Databricks, you can run validation tests directly against data hosted in Unity Catalog. + +```{mermaid} +%%| fig-cap: "Data flow between Databricks and ValidMind" +flowchart LR + subgraph databricks [Databricks] + UC[Unity Catalog] + Data[Tables/Datasets] + end + + subgraph notebook [Validation Notebook] + SDK[ValidMind SDK] + end + + subgraph validmind [ValidMind Platform] + Report[Validation Report] + Inventory[Inventory Record] + end + + UC --> Data + Data --> SDK + SDK --> Report + Report --> Inventory + Inventory -.->|linked| UC +``` + + +## Configure the connection + +::: {.column-margin .pt6} +![Configure the Databricks connection](configure-databricks.png){width=80% fig-alt="Screenshot of the Configure Databricks connection dialog showing the required fields described in step 5." .screenshot} +::: + +1. In the left sidebar, click **{{< fa gear >}} Settings**. + +2. Under {{< fa puzzle-piece >}} Integrations, select **Connections**. + +3. Click **{{< fa plus >}} Add Connection**. + +4. In the modal that opens, select **Databricks**. + +5. Complete: + + - **[integration name]{.smallcaps}** — How other admins can identify the connection. + - **[description]{.smallcaps}** (optional) — The intended usage or additional details. + - **[workspace url]{.smallcaps}** — Your Databricks workspace URL, found in the browser address bar, such as `https://adb-1234567890.azuredatabricks.net`. + - **[sql warehouse id]{.smallcaps}** — The ID of your SQL Warehouse, found in SQL Warehouses settings. + - **[personal access token]{.smallcaps}** — Select a secret containing your Databricks Personal Access Token. + - **[initial status]{.smallcaps}** — Set to `Operational` to enable immediately or `Disabled` if you plan to finish setup later. + +6. Click **Save Integration**. + +7. Test the connection: + + a. Hover over the Databricks connection you just created. + b. When the **{{< fa ellipsis-vertical >}}** menu appears, click on it and select **{{< fa circle-check >}} Test Connection**. + + If the test is successful, the message **{{< fa check-circle >}} Connection successful** displays. + +## Link records to Databricks + +Once the connection is configured, you can link {{< var vm.product >}} inventory records to your Databricks Unity Catalog resources: + +1. In the left sidebar, click **{{< fa cubes >}} Inventory**. + +2. Select a record by clicking on it or find your record by applying a filter or searching for it.[^3] + +3. Scroll down until you locate the **Databricks** connection box in the right sidebar. + +4. Hover over the Databricks box. + +5. When the **{{< fa ellipsis-vertical >}}** menu appears, click on it and select **{{< fa link >}} Link Model**. + +6. In the modal that opens: + + - **[select model]{.smallcaps}** — Choose the Databricks model to link from the dropdown. + - **[sync frequency]{.smallcaps}** — Set how often ValidMind automatically syncs data from the external system. + +7. Click **Link Model** to complete the link. + +8. Click **Link Model**. + +After linking, metadata from the Unity Catalog resource syncs to {{< var vm.product >}}. You can use linked fields in custom calculated fields to surface Databricks metadata directly in your inventory views. + +## What's next + +:::{#whats-next} +::: + + + +[^1]: [Manage permissions](../../configuration/manage-permissions.qmd) + +[^2]: [Manage secrets](../manage-secrets.qmd) + +[^3]: [Working with the inventory](../../inventory/working-with-the-inventory.qmd#search-filter-and-sort-records) diff --git a/site/guide/integrations/integrations-examples/use-webhooks-with-workflows.qmd b/site/guide/integrations/integrations-examples/use-webhooks-with-workflows.qmd new file mode 100644 index 000000000..22b7dd9a0 --- /dev/null +++ b/site/guide/integrations/integrations-examples/use-webhooks-with-workflows.qmd @@ -0,0 +1,128 @@ +--- +# Copyright © 2023-2026 ValidMind Inc. All rights reserved. +# Refer to the LICENSE file in the root of this repository for details. +# SPDX-License-Identifier: AGPL-3.0 AND ValidMind Commercial +title: "Use webhooks with workflows" +date: last-modified +--- + +Use webhooks to let external systems start {{< var vm.product >}} workflows or trigger paused workflows to continue. + +::: {.attn} + +## Prerequisites + +- [x] {{< var link.login >}} +- [x] You are a [{{< fa hand >}} Customer Admin]{.bubble} or assigned another role with sufficient permissions to configure workflows.[^1] +- [x] You understand how to configure workflows and add steps to workflows.[^2] +- [x] You have admin access to the external system that will send webhook requests. + +::: + +## Start a workflow via webhook + +Start a {{< var vm.product >}} workflow from an external system by sending a POST request to trigger a new workflow. + +::: {.panel-tabset} + +### a. Configure workflow in {{< var vm.product >}} + +1. Add a new workflow, selecting the **Via Webhook** workflow start option.[^3] + +2. From the **Workflow Steps** modal, drag and drop a **Webhook** step[^4] onto the canvas, then connect it to your workflow. + +3. Double-click the step to open the **Webhook Step Trigger** modal. + +4. Copy or select the webhook details: + + - **URL** — Click **{{< fa regular copy >}} Copy** for the unique POST webhook URL to use when configuring your external system. + - **[select target model for payload]{.smallcaps}** — Select the model that is associated with the webhook payload from the dropdown. + - **Payload** — Click **{{< fa regular copy >}} Copy** for the JSON payload that external systems must send in their POST request, where the value for `target_cuid` is shown after you select a target: + + ```json + { + "action": "run_workflow", + "target": "", + "entity_name": "InventoryModel" + } + ``` + + - For the required authentication headers, click **{{< fa regular copy >}} Copy** for each of the following key-value pairs and paste them into your external system: + - `x-api-key`: `{{API Key}}` + - `x-api-secret`: `{{API Secret}}` + - **[wait for webhook trigger when reached]{.smallcaps}** — When enabled, the workflow pauses execution when it reaches this step and waits for the external system to send the POST request. + +5. Click **Save**. + +### b. Start workflow from external system + +Send a POST request to the webhook URL with a JSON payload that includes the `run_workflow` action for the target model CUID: + +```bash +curl -X POST https://api.prod.vm.validmind.ai/vm/api/v1/webhooks/xxxxxxxxxxxxxxxxxxxxxxxxx/xxxx -H 'Content-Type`: `application/json' -H 'x-api-key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' -H 'x-api-secret: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' --data '{ + "action": "run_workflow", + "target": "", + "entity_name": "InventoryModel" +}' +``` +::: + +## Trigger a paused workflow to continue + +Trigger a waiting {{< var vm.product >}} workflow step to continue from an external system. Use this pattern when a workflow pauses at a webhook step and waits for external input before proceeding. + +::: {.panel-tabset} + +### a. Configure workflow in {{< var vm.product >}} + +1. Open the workflow you want to configure, or add a new workflow.[^3] + +2. From the **Workflow Steps** modal, drag and drop a **Webhook** step[^4] onto the canvas, then connect the step to your workflow. + +3. Double-click the step to open the **Webhook Step Trigger** modal. + +4. Copy or select the webhook details: + + - **URL** — Click **{{< fa regular copy >}} Copy** for the unique POST webhook URL to use when configuring your external system. + - **[select target model for payload]{.smallcaps}** — Select the model that is associated with the webhook payload from the dropdown. + - **Payload** — Click **{{< fa regular copy >}} Copy** for the JSON payload that external systems must send in their POST request, where the value for `target_cuid` is shown after you select a target: + + ```json + { + "action": "run_step", + "target": "", + "entity_name": "InventoryModel" + } + ``` + + - For the required authentication headers, click **{{< fa regular copy >}} Copy** for each of the following key-value pairs and paste them into your external system: + - `x-api-key`: `{{API Key}}` + - `x-api-secret`: `{{API Secret}}` + +5. Click **Update Step** to save your configuration. + +When the workflow reaches this step, it pauses and waits for the external system. + +### b. Trigger workflow to continue from external system + +Send a POST request to the webhook URL with a JSON payload containing the `run_step` action for the model CUID: + +```bash +curl -X POST https://api.prod.vm.validmind.ai/vm/api/v1/webhooks/xxxxxxxxxxxxxxxxxxxxxxxxx/xxxx -H 'Content-Type`: `application/json' -H 'x-api-key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' -H 'x-api-secret: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' --data '{ + "action": "run_step", + "target": "", + "entity_name": "InventoryModel" +}' +``` + +::: + + + +[^1]: [Manage permissions](../../configuration/manage-permissions.qmd) + +[^2]: [Introduction to workflows](../../workflows/introduction-to-workflows.qmd) + +[^3]: [Add new workflows](../../workflows/configure-workflows.qmd#add-new-workflows) + +[^4]: [Workflow step types](../../workflows/workflow-step-types.qmd#webhook) diff --git a/site/guide/integrations/managing-integrations.qmd b/site/guide/integrations/managing-integrations.qmd index c4fc74182..2f15044cb 100644 --- a/site/guide/integrations/managing-integrations.qmd +++ b/site/guide/integrations/managing-integrations.qmd @@ -78,24 +78,48 @@ Link to models in external registries and development platforms and keep invento :::: {.flex .flex-wrap .justify-around} -::: {.w-25-ns} +::: {.w-20-ns} - AWS SageMaker ::: -::: {.w-25-ns} +::: {.w-20-ns} - AWS Bedrock ::: -::: {.w-25-ns} +::: {.w-20-ns} +- Databricks +::: + +::: {.w-20-ns} - MLflow ::: -::: {.w-25-ns} +::: {.w-20-ns} +  +::: + +:::: + +:::: {.flex .flex-wrap .justify-around} + +::: {.w-20-ns} - GitLab ::: ::: {.w-20-ns} -- Custom integrations +- Custom +::: + +::: {.w-20-ns} +  +::: + +::: {.w-20-ns} +  +::: + +::: {.w-20-ns} +  ::: ::::