From 576f3e8096b8e4880923f096830b3e6f27ec2ddc Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 4 Aug 2026 02:09:11 +0000
Subject: [PATCH 01/16] chore(internal): codegen related update
---
scripts/upload-artifacts | 1 +
1 file changed, 1 insertion(+)
diff --git a/scripts/upload-artifacts b/scripts/upload-artifacts
index 10f3c705..5c1fbefc 100755
--- a/scripts/upload-artifacts
+++ b/scripts/upload-artifacts
@@ -91,6 +91,7 @@ generate_instructions() {
Maven Repo
+
Stainless SDK Maven Repository
From aa54ceb20bdd0634c88e29c55b8c189b014b21b4 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 14 Aug 2026 05:01:35 +0000
Subject: [PATCH 02/16] fix(docs): link the javadoc badge so the version stays
current after release
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index d8bbe81e..7ecfe780 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
[](https://central.sonatype.com/artifact/com.openlayer.api/openlayer-java/0.10.0)
-[](https://javadoc.io/doc/com.openlayer.api/openlayer-java/0.10.0)
+[](https://javadoc.io/doc/com.openlayer.api/openlayer-java/0.10.0)
From 2733a53794639dddf53420c065bf91f09297d9c2 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 18 Aug 2026 04:13:02 +0000
Subject: [PATCH 03/16] chore(internal): codegen related update
---
openlayer-java-core/build.gradle.kts | 1 +
1 file changed, 1 insertion(+)
diff --git a/openlayer-java-core/build.gradle.kts b/openlayer-java-core/build.gradle.kts
index 396e8396..7655ccfd 100644
--- a/openlayer-java-core/build.gradle.kts
+++ b/openlayer-java-core/build.gradle.kts
@@ -38,4 +38,5 @@ dependencies {
testImplementation("org.mockito:mockito-core:5.14.2")
testImplementation("org.mockito:mockito-junit-jupiter:5.14.2")
testImplementation("org.mockito.kotlin:mockito-kotlin:4.1.0")
+ testImplementation("org.slf4j:slf4j-nop:1.7.36")
}
From 3460d6cfa3b95eabb956c5af0feaa7102287b59c Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 20 Aug 2026 04:24:14 +0000
Subject: [PATCH 04/16] chore(internal): allow the mock server port to be set
with STAINLESS_MOCK_PORT
---
scripts/mock | 13 ++++++++++---
scripts/test | 12 +++++++++---
2 files changed, 19 insertions(+), 6 deletions(-)
diff --git a/scripts/mock b/scripts/mock
index feebe5ed..984e1c00 100755
--- a/scripts/mock
+++ b/scripts/mock
@@ -4,6 +4,11 @@ set -e
cd "$(dirname "$0")/.."
+if [ "$1" == "--install" ]; then
+ npm exec --package=@stdy/cli@0.22.1 -- steady --version
+ exit 0
+fi
+
if [[ -n "$1" && "$1" != '--'* ]]; then
URL="$1"
shift
@@ -20,16 +25,18 @@ fi
echo "==> Starting mock server with URL ${URL}"
# Run steady mock on the given spec
+MOCK_PORT="${STAINLESS_MOCK_PORT:-4010}"
+
if [ "$1" == "--daemon" ]; then
# Pre-install the package so the download doesn't eat into the startup timeout
npm exec --package=@stdy/cli@0.22.1 -- steady --version
- npm exec --package=@stdy/cli@0.22.1 -- steady --host 127.0.0.1 -p 4010 --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL" &> .stdy.log &
+ npm exec --package=@stdy/cli@0.22.1 -- steady --host 127.0.0.1 -p "$MOCK_PORT" --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL" &> .stdy.log &
# Wait for server to come online via health endpoint (max 30s)
echo -n "Waiting for server"
attempts=0
- while ! curl --silent --fail "http://127.0.0.1:4010/_x-steady/health" >/dev/null 2>&1; do
+ while ! curl --silent --fail "http://127.0.0.1:$MOCK_PORT/_x-steady/health" >/dev/null 2>&1; do
if ! kill -0 $! 2>/dev/null; then
echo
cat .stdy.log
@@ -48,5 +55,5 @@ if [ "$1" == "--daemon" ]; then
echo
else
- npm exec --package=@stdy/cli@0.22.1 -- steady --host 127.0.0.1 -p 4010 --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL"
+ npm exec --package=@stdy/cli@0.22.1 -- steady --host 127.0.0.1 -p "$MOCK_PORT" --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL"
fi
diff --git a/scripts/test b/scripts/test
index 7d7f08e3..29eb2fa9 100755
--- a/scripts/test
+++ b/scripts/test
@@ -9,8 +9,10 @@ GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color
+MOCK_PORT="${STAINLESS_MOCK_PORT:-4010}"
+
function steady_is_running() {
- curl --silent "http://127.0.0.1:4010/_x-steady/health" >/dev/null 2>&1
+ curl --silent "http://127.0.0.1:$MOCK_PORT/_x-steady/health" >/dev/null 2>&1
}
kill_server_on_port() {
@@ -27,7 +29,7 @@ function is_overriding_api_base_url() {
if ! is_overriding_api_base_url && ! steady_is_running ; then
# When we exit this script, make sure to kill the background mock server process
- trap 'kill_server_on_port 4010' EXIT
+ trap 'kill_server_on_port "$MOCK_PORT"' EXIT
# Start the dev server
./scripts/mock --daemon
@@ -43,7 +45,7 @@ elif ! steady_is_running ; then
echo -e "To run the server, pass in the path or url of your OpenAPI"
echo -e "spec to the steady command:"
echo
- echo -e " \$ ${YELLOW}npm exec --package=@stdy/cli@0.22.1 -- steady path/to/your.openapi.yml --host 127.0.0.1 -p 4010 --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets${NC}"
+ echo -e " \$ ${YELLOW}npm exec --package=@stdy/cli@0.22.1 -- steady path/to/your.openapi.yml --host 127.0.0.1 -p $MOCK_PORT --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets${NC}"
echo
exit 1
@@ -52,5 +54,9 @@ else
echo
fi
+if [ -n "${STAINLESS_MOCK_PORT:-}" ] && ! is_overriding_api_base_url ; then
+ export TEST_API_BASE_URL="http://127.0.0.1:$MOCK_PORT"
+fi
+
echo "==> Running tests"
./gradlew test "$@"
From 013d4a6692e44912d1a0b5e1000545aa241ec2ac Mon Sep 17 00:00:00 2001
From: Jon Harrell <4829245+jharrell@users.noreply.github.com>
Date: Tue, 25 Aug 2026 09:06:47 -0500
Subject: [PATCH 05/16] feat: initial stlc build
Stainless-Generated-From: 129181c0add10a6b9836d1a03dc2824d83abbdd7
---
.github/workflows/release-please.yml | 20 ++++++++++++++++++
.stats.yml | 2 --
README.md | 2 +-
examples/.keep | 4 ----
openlayer-java-core/build.gradle.kts | 1 +
openlayer-java-example/build.gradle.kts | 3 ++-
release-please-config.json | 4 ++--
scripts/mock | 28 ++++++++++++++++---------
scripts/test | 12 ++++++++---
scripts/upload-artifacts | 1 +
10 files changed, 54 insertions(+), 23 deletions(-)
create mode 100644 .github/workflows/release-please.yml
delete mode 100644 examples/.keep
diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml
new file mode 100644
index 00000000..e9c93560
--- /dev/null
+++ b/.github/workflows/release-please.yml
@@ -0,0 +1,20 @@
+name: Release Please
+on:
+ push:
+ branches:
+ - main
+
+permissions:
+ contents: write
+ pull-requests: write
+
+jobs:
+ release-please:
+ if: github.repository == 'openlayer-ai/openlayer-java'
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: googleapis/release-please-action@5c625bfb5d1ff62eadeeb3772007f7f66fdcf071 # v4.4.1
+ id: release
+ with:
+ token: ${{ secrets.RELEASE_PLEASE_TOKEN }}
diff --git a/.stats.yml b/.stats.yml
index 60080a09..e8ba8c9f 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,3 +1 @@
configured_endpoints: 32
-openapi_spec_hash: 72e2dd8871904fe6c130d1c81b033d5a
-config_hash: f75dd97d47c446f8fdc8bcb36f445eea
diff --git a/README.md b/README.md
index d8bbe81e..7ecfe780 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
[](https://central.sonatype.com/artifact/com.openlayer.api/openlayer-java/0.10.0)
-[](https://javadoc.io/doc/com.openlayer.api/openlayer-java/0.10.0)
+[](https://javadoc.io/doc/com.openlayer.api/openlayer-java/0.10.0)
diff --git a/examples/.keep b/examples/.keep
deleted file mode 100644
index d8c73e93..00000000
--- a/examples/.keep
+++ /dev/null
@@ -1,4 +0,0 @@
-File generated from our OpenAPI spec by Stainless.
-
-This directory can be used to store example files demonstrating usage of this SDK.
-It is ignored by Stainless code generation and its content (other than this keep file) won't be touched.
\ No newline at end of file
diff --git a/openlayer-java-core/build.gradle.kts b/openlayer-java-core/build.gradle.kts
index 396e8396..7655ccfd 100644
--- a/openlayer-java-core/build.gradle.kts
+++ b/openlayer-java-core/build.gradle.kts
@@ -38,4 +38,5 @@ dependencies {
testImplementation("org.mockito:mockito-core:5.14.2")
testImplementation("org.mockito:mockito-junit-jupiter:5.14.2")
testImplementation("org.mockito.kotlin:mockito-kotlin:4.1.0")
+ testImplementation("org.slf4j:slf4j-nop:1.7.36")
}
diff --git a/openlayer-java-example/build.gradle.kts b/openlayer-java-example/build.gradle.kts
index 150fb60e..1fa6ecb0 100644
--- a/openlayer-java-example/build.gradle.kts
+++ b/openlayer-java-example/build.gradle.kts
@@ -8,7 +8,8 @@ repositories {
}
dependencies {
- implementation(project(":openlayer-java"))
+ implementation(project(":openlayer-java-core"))
+ implementation(project(":openlayer-java-client-okhttp"))
}
tasks.withType().configureEach {
diff --git a/release-please-config.json b/release-please-config.json
index 8f987198..0a47df51 100644
--- a/release-please-config.json
+++ b/release-please-config.json
@@ -2,11 +2,11 @@
"packages": {
".": {}
},
- "$schema": "https://raw.githubusercontent.com/stainless-api/release-please/main/schemas/config.json",
+ "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
"include-v-in-tag": true,
"include-component-in-tag": false,
"versioning": "prerelease",
- "prerelease": true,
+ "prerelease": false,
"bump-minor-pre-major": true,
"bump-patch-for-minor-pre-major": false,
"pull-request-header": "Automated Release PR",
diff --git a/scripts/mock b/scripts/mock
index feebe5ed..474f5a99 100755
--- a/scripts/mock
+++ b/scripts/mock
@@ -4,32 +4,40 @@ set -e
cd "$(dirname "$0")/.."
+if [ "$1" == "--install" ]; then
+ npm exec --package=@stdy/cli@0.22.1 -- steady --version
+ exit 0
+fi
+
if [[ -n "$1" && "$1" != '--'* ]]; then
URL="$1"
shift
+elif [ -n "$STAINLESS_OPENAPI_SPEC_URL" ]; then
+ URL="$STAINLESS_OPENAPI_SPEC_URL"
else
- URL="$(grep 'openapi_spec_url' .stats.yml | cut -d' ' -f2)"
-fi
-
-# Check if the URL is empty
-if [ -z "$URL" ]; then
- echo "Error: No OpenAPI spec path/url provided or found in .stats.yml"
- exit 1
+ # Embedded OpenAPI spec (base64-encoded, gzipped)
+ EMBEDDED_SPEC="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"
+ SPEC_TMPFILE="$(mktemp)"
+ trap 'rm -f "$SPEC_TMPFILE"' EXIT
+ echo "$EMBEDDED_SPEC" | base64 --decode | gunzip > "$SPEC_TMPFILE"
+ URL="$SPEC_TMPFILE"
fi
echo "==> Starting mock server with URL ${URL}"
# Run steady mock on the given spec
+MOCK_PORT="${STAINLESS_MOCK_PORT:-4010}"
+
if [ "$1" == "--daemon" ]; then
# Pre-install the package so the download doesn't eat into the startup timeout
npm exec --package=@stdy/cli@0.22.1 -- steady --version
- npm exec --package=@stdy/cli@0.22.1 -- steady --host 127.0.0.1 -p 4010 --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL" &> .stdy.log &
+ npm exec --package=@stdy/cli@0.22.1 -- steady --host 127.0.0.1 -p "$MOCK_PORT" --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL" &> .stdy.log &
# Wait for server to come online via health endpoint (max 30s)
echo -n "Waiting for server"
attempts=0
- while ! curl --silent --fail "http://127.0.0.1:4010/_x-steady/health" >/dev/null 2>&1; do
+ while ! curl --silent --fail "http://127.0.0.1:$MOCK_PORT/_x-steady/health" >/dev/null 2>&1; do
if ! kill -0 $! 2>/dev/null; then
echo
cat .stdy.log
@@ -48,5 +56,5 @@ if [ "$1" == "--daemon" ]; then
echo
else
- npm exec --package=@stdy/cli@0.22.1 -- steady --host 127.0.0.1 -p 4010 --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL"
+ npm exec --package=@stdy/cli@0.22.1 -- steady --host 127.0.0.1 -p "$MOCK_PORT" --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets "$URL"
fi
diff --git a/scripts/test b/scripts/test
index 7d7f08e3..29eb2fa9 100755
--- a/scripts/test
+++ b/scripts/test
@@ -9,8 +9,10 @@ GREEN='\033[0;32m'
YELLOW='\033[0;33m'
NC='\033[0m' # No Color
+MOCK_PORT="${STAINLESS_MOCK_PORT:-4010}"
+
function steady_is_running() {
- curl --silent "http://127.0.0.1:4010/_x-steady/health" >/dev/null 2>&1
+ curl --silent "http://127.0.0.1:$MOCK_PORT/_x-steady/health" >/dev/null 2>&1
}
kill_server_on_port() {
@@ -27,7 +29,7 @@ function is_overriding_api_base_url() {
if ! is_overriding_api_base_url && ! steady_is_running ; then
# When we exit this script, make sure to kill the background mock server process
- trap 'kill_server_on_port 4010' EXIT
+ trap 'kill_server_on_port "$MOCK_PORT"' EXIT
# Start the dev server
./scripts/mock --daemon
@@ -43,7 +45,7 @@ elif ! steady_is_running ; then
echo -e "To run the server, pass in the path or url of your OpenAPI"
echo -e "spec to the steady command:"
echo
- echo -e " \$ ${YELLOW}npm exec --package=@stdy/cli@0.22.1 -- steady path/to/your.openapi.yml --host 127.0.0.1 -p 4010 --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets${NC}"
+ echo -e " \$ ${YELLOW}npm exec --package=@stdy/cli@0.22.1 -- steady path/to/your.openapi.yml --host 127.0.0.1 -p $MOCK_PORT --validator-query-array-format=comma --validator-form-array-format=comma --validator-query-object-format=brackets --validator-form-object-format=brackets${NC}"
echo
exit 1
@@ -52,5 +54,9 @@ else
echo
fi
+if [ -n "${STAINLESS_MOCK_PORT:-}" ] && ! is_overriding_api_base_url ; then
+ export TEST_API_BASE_URL="http://127.0.0.1:$MOCK_PORT"
+fi
+
echo "==> Running tests"
./gradlew test "$@"
diff --git a/scripts/upload-artifacts b/scripts/upload-artifacts
index 10f3c705..5c1fbefc 100755
--- a/scripts/upload-artifacts
+++ b/scripts/upload-artifacts
@@ -91,6 +91,7 @@ generate_instructions() {
Maven Repo
+
Stainless SDK Maven Repository
From dae544a6273a7f4b1229de293b1c3d2054f09dd0 Mon Sep 17 00:00:00 2001
From: Jon Harrell <4829245+jharrell@users.noreply.github.com>
Date: Tue, 25 Aug 2026 09:19:13 -0500
Subject: [PATCH 06/16] ci: add stlc promote and back-sync workflows
---
.github/workflows/stlc-promote.yml | 80 ++++++++++
.github/workflows/stlc-sync.yml | 225 +++++++++++++++++++++++++++++
2 files changed, 305 insertions(+)
create mode 100644 .github/workflows/stlc-promote.yml
create mode 100644 .github/workflows/stlc-sync.yml
diff --git a/.github/workflows/stlc-promote.yml b/.github/workflows/stlc-promote.yml
new file mode 100644
index 00000000..4b212ec8
--- /dev/null
+++ b/.github/workflows/stlc-promote.yml
@@ -0,0 +1,80 @@
+# NOTE(stlc migration, 2026-08-25): repo names below point at the
+# stainless-sdks placeholder repos used to validate the migration.
+# At cutover, replace:
+# - the production repo with openlayer-ai/openlayer-java
+# - the staging/config repo owner with your own org after transfer
+name: Promote SDKs
+
+# Promote staging to production by fast-forwarding production main up to staging,
+# preserving SHAs so the trunks stay identical and linear (nothing to heal on the
+# next stlc build). Manual dispatch by design: a maintainer promotes the accumulated
+# batch to cut a release; release-please then opens its version PR on production.
+on:
+ workflow_dispatch: {}
+
+permissions:
+ contents: read
+
+jobs:
+ promote:
+ # Runner comes from the STLC_RUNNER repo/org variable when set; defaults to GitHub-hosted.
+ runs-on: ${{ vars.STLC_RUNNER || 'ubuntu-latest' }}
+ if: github.repository == 'stainless-sdks/openlayer-java-staging'
+ # Optional gate: add required reviewers to this environment to approve each
+ # promote. With none it only scopes secrets and adds no gate. Remove if unused.
+ environment: production
+ env:
+ PRODUCTION_REPO: stainless-sdks/openlayer-java-prod
+ GH_TOKEN: ${{ secrets.PRODUCTION_REPO_TOKEN }}
+ steps:
+ - name: Check out staging
+ uses: actions/checkout@v6
+ with:
+ fetch-depth: 0
+ persist-credentials: false
+
+ - name: Fetch production main
+ run: |
+ git remote add production \
+ "https://x-access-token:${GH_TOKEN}@github.com/${PRODUCTION_REPO}.git"
+ git fetch production main
+
+ - name: Check whether production already has staging's content
+ id: diff
+ run: |
+ # After a release, production has release-please commits staging lacks, so compare trees.
+ MERGED=$(git merge-tree --write-tree production/main origin/main) || MERGED=conflict
+ PRODUCTION_TREE=$(git rev-parse 'production/main^{tree}')
+ if [ "$MERGED" = "$PRODUCTION_TREE" ]; then
+ echo "Production already contains staging's content. Nothing to promote."
+ echo "synced=true" >> "$GITHUB_OUTPUT"
+ else
+ echo "synced=false" >> "$GITHUB_OUTPUT"
+ fi
+
+ - name: Promote staging to production (fast-forward)
+ if: steps.diff.outputs.synced == 'false'
+ run: |
+ # Refuse unless production is an ancestor of staging: otherwise the trunks
+ # have forked (production advanced without a back-sync) and FF is unsafe.
+ if ! git merge-base --is-ancestor production/main origin/main; then
+ echo "::error title=Promote blocked::production/main is not an ancestor of staging main. Back-sync production into staging first."
+ exit 1
+ fi
+ git push production origin/main:refs/heads/main
+ echo "Fast-forwarded production/main to staging/main."
+
+ - name: Alert on failure
+ if: failure()
+ env:
+ ALERT_WEBHOOK_URL: ${{ secrets.STLC_ALERT_WEBHOOK_URL }}
+ run: |
+ run_url="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
+ msg="stlc promote failed in ${{ github.repository }}. A stalled promote or back-sync lets custom-code tracking drift, which later builds refuse on — investigate before the next build. Run: $run_url"
+ echo "::error title=stlc workflow failed::$msg"
+ { echo "### ⚠️ stlc workflow failed"; echo ""; echo "$msg"; } >> "$GITHUB_STEP_SUMMARY"
+ if [ -n "${ALERT_WEBHOOK_URL:-}" ]; then
+ curl -sS -X POST -H 'Content-Type: application/json' \
+ -d "$(jq -n --arg text "$msg" '{text:$text}')" "$ALERT_WEBHOOK_URL" \
+ || echo "::warning::Alert webhook POST failed"
+ fi
diff --git a/.github/workflows/stlc-sync.yml b/.github/workflows/stlc-sync.yml
new file mode 100644
index 00000000..2051d379
--- /dev/null
+++ b/.github/workflows/stlc-sync.yml
@@ -0,0 +1,225 @@
+# NOTE(stlc migration, 2026-08-25): repo names below point at the
+# stainless-sdks placeholder repos used to validate the migration.
+# At cutover, replace:
+# - the production repo with openlayer-ai/openlayer-java
+# - the staging/config repo owner with your own org after transfer
+name: Sync SDK repos
+
+# Keeps the staging and production trunks in sync and the config repo's
+# tracking files fresh. Each job self-routes by repo + event, so this one file
+# can live in both repos and only the right job runs. The dispatch jobs are
+# eager-only (the polls cover them) and no-op when their token isn't set.
+on:
+ schedule:
+ # back-sync poll: a cheap pure-git check, twice hourly so an unsynced production
+ # change (e.g. a community PR between releases) can't hold codegen for long.
+ - cron: '7,37 * * * *'
+ workflow_dispatch: {}
+ repository_dispatch:
+ types: [prod-released]
+ release:
+ types: [published]
+ push:
+ # main only. stlc preview/integrated/codegen branches never push to main.
+ branches: [main]
+
+jobs:
+ back-sync:
+ # Fast-forward production main back onto staging so the trunks stay identical.
+ # Runner comes from the STLC_RUNNER repo/org variable when set; defaults to GitHub-hosted.
+ runs-on: ${{ vars.STLC_RUNNER || 'ubuntu-latest' }}
+ if: >-
+ github.repository == 'stainless-sdks/openlayer-java-staging' &&
+ (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || github.event_name == 'repository_dispatch')
+ permissions:
+ contents: write
+ concurrency:
+ group: stlc-back-sync
+ cancel-in-progress: true
+ env:
+ PRODUCTION_REPO: stainless-sdks/openlayer-java-prod
+ steps:
+ - name: Check out staging
+ uses: actions/checkout@v6
+ with:
+ fetch-depth: 0
+
+ - name: Fetch production main
+ env:
+ PRODUCTION_REPO_TOKEN: ${{ secrets.PRODUCTION_REPO_TOKEN }}
+ run: |
+ # Public production reads with no credential; a private production
+ # repo needs PRODUCTION_REPO_TOKEN (the same token the promote uses).
+ if [ -n "${PRODUCTION_REPO_TOKEN:-}" ]; then
+ git remote add production "https://x-access-token:${PRODUCTION_REPO_TOKEN}@github.com/${PRODUCTION_REPO}.git"
+ else
+ git remote add production "https://github.com/${PRODUCTION_REPO}.git"
+ fi
+ # actions/checkout persists this repo's token as an auth header, which
+ # outranks the remote URL credential; blank it for this fetch only.
+ git -c "http.https://github.com/.extraheader=" fetch production main
+
+ - name: Check whether production has content staging lacks
+ id: diff
+ run: |
+ # Content compare: would merging production into staging change its tree?
+ # If not, staging already has production's content (release-please commits).
+ MERGED=$(git merge-tree --write-tree origin/main production/main) || MERGED=conflict
+ STAGING_TREE=$(git rev-parse 'origin/main^{tree}')
+ if [ "$MERGED" = "$STAGING_TREE" ]; then
+ echo "Staging already has production's content. Nothing to pull back."
+ echo "behind=false" >> "$GITHUB_OUTPUT"
+ else
+ echo "behind=true" >> "$GITHUB_OUTPUT"
+ fi
+
+ - name: Sync production to staging (fast-forward)
+ if: steps.diff.outputs.behind == 'true'
+ run: |
+ # Refuse unless staging is an ancestor of production: otherwise the
+ # trunks have forked and a fast-forward would be unsafe.
+ if ! git merge-base --is-ancestor origin/main production/main; then
+ echo "::error title=Back-sync blocked::staging main is not an ancestor of production/main."
+ exit 1
+ fi
+ git push origin production/main:refs/heads/main
+ echo "Fast-forwarded staging/main to production/main."
+
+ - name: Alert on failure
+ if: failure()
+ env:
+ ALERT_WEBHOOK_URL: ${{ secrets.STLC_ALERT_WEBHOOK_URL }}
+ run: |
+ run_url="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
+ msg="stlc back-sync (sync from production) failed in ${{ github.repository }}. A stalled back-sync lets custom-code tracking drift, which later builds refuse on — investigate before the next build. Run: $run_url"
+ echo "::error title=stlc workflow failed::$msg"
+ { echo "### ⚠️ stlc workflow failed"; echo ""; echo "$msg"; } >> "$GITHUB_STEP_SUMMARY"
+ if [ -n "${ALERT_WEBHOOK_URL:-}" ]; then
+ curl -sS -X POST -H 'Content-Type: application/json' \
+ -d "$(jq -n --arg text "$msg" '{text:$text}')" "$ALERT_WEBHOOK_URL" \
+ || echo "::warning::Alert webhook POST failed"
+ fi
+
+ notify-back-sync:
+ # On a published release, tell staging to back-sync now instead of waiting for
+ # the poll. Dispatch-only: it cannot write production or staging contents.
+ runs-on: ${{ vars.STLC_RUNNER || 'ubuntu-latest' }}
+ if: >-
+ github.repository == 'stainless-sdks/openlayer-java-prod' &&
+ (github.event_name == 'release' || github.event_name == 'workflow_dispatch')
+ permissions:
+ contents: read
+ env:
+ STAGING_REPO: stainless-sdks/openlayer-java-staging
+ steps:
+ - name: Dispatch back-sync to staging
+ env:
+ DISPATCH_TOKEN: ${{ secrets.STAGING_DISPATCH_TOKEN }}
+ REF_NAME: ${{ github.ref_name }}
+ run: |
+ set -euo pipefail
+
+ if [ -z "${DISPATCH_TOKEN:-}" ]; then
+ echo "::notice::STAGING_DISPATCH_TOKEN not configured — skipping the eager back-sync notify. The staging repo's twice-hourly poll covers this."
+ exit 0
+ fi
+
+ payload=$(jq -n --arg ref "$REF_NAME" '{event_type:"prod-released",client_payload:{ref:$ref}}')
+ code=$(curl -sS -o /tmp/dispatch.txt -w '%{http_code}' -X POST \
+ -H "Authorization: Bearer ${DISPATCH_TOKEN}" \
+ -H "Accept: application/vnd.github+json" \
+ -H "X-GitHub-Api-Version: 2022-11-28" \
+ "https://api.github.com/repos/${STAGING_REPO}/dispatches" \
+ -d "$payload")
+ if [ "$code" = "204" ]; then
+ echo "Back-sync dispatched to ${STAGING_REPO}."
+ else
+ echo "Dispatch failed (HTTP $code)" >&2; cat /tmp/dispatch.txt >&2; exit 1
+ fi
+
+ - name: Alert on failure
+ if: failure()
+ env:
+ ALERT_WEBHOOK_URL: ${{ secrets.STLC_ALERT_WEBHOOK_URL }}
+ run: |
+ run_url="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
+ msg="stlc release back-sync trigger failed in ${{ github.repository }} — the staging repo was NOT notified to back-sync this release (likely an expired STAGING_DISPATCH_TOKEN). Staging catches up on its next poll, but verify the token. Run: $run_url"
+ echo "::error title=stlc workflow failed::$msg"
+ { echo "### ⚠️ stlc workflow failed"; echo ""; echo "$msg"; } >> "$GITHUB_STEP_SUMMARY"
+ if [ -n "${ALERT_WEBHOOK_URL:-}" ]; then
+ curl -sS -X POST -H 'Content-Type: application/json' \
+ -d "$(jq -n --arg text "$msg" '{text:$text}')" "$ALERT_WEBHOOK_URL" \
+ || echo "::warning::Alert webhook POST failed"
+ fi
+
+ seal-dispatch:
+ # When out-of-band custom code lands on staging main, tell the config repo to
+ # re-seal now instead of waiting for its scheduled sync. The loop guards skip
+ # stlc's own pushes, so the bot's commits can't trigger a re-seal loop.
+ runs-on: ${{ vars.STLC_RUNNER || 'ubuntu-latest' }}
+ if: >-
+ github.repository == 'stainless-sdks/openlayer-java-staging' &&
+ github.event_name == 'push'
+ permissions:
+ contents: read
+ concurrency:
+ group: seal-dispatch-${{ github.ref }}
+ cancel-in-progress: false
+ env:
+ CONFIG_REPO: stainless-sdks/openlayer-config
+ steps:
+ - name: Loop-guard and send re-seal dispatch
+ env:
+ DISPATCH_TOKEN: ${{ secrets.CONFIG_DISPATCH_TOKEN }}
+ HEAD_MSG: ${{ github.event.head_commit.message }}
+ HEAD_AUTHOR_NAME: ${{ github.event.head_commit.author.name }}
+ SHA: ${{ github.sha }}
+ REPO: ${{ github.repository }}
+ run: |
+ set -euo pipefail
+
+ # Loop guard 1: skip the stlc "Build SDK" squash commit (Stainless-Generated-From trailer).
+ if printf '%s' "$HEAD_MSG" | grep -q 'Stainless-Generated-From'; then
+ echo "Head commit is an stlc build — skipping re-seal dispatch."
+ exit 0
+ fi
+
+ # Loop guard 2: skip stlc-bot commits (e.g. a regeneration commit).
+ if [ "$HEAD_AUTHOR_NAME" = "stlc-bot" ]; then
+ echo "Head commit authored by stlc-bot — skipping re-seal dispatch."
+ exit 0
+ fi
+
+ if [ -z "${DISPATCH_TOKEN:-}" ]; then
+ echo "::notice::CONFIG_DISPATCH_TOKEN not configured — skipping the eager re-seal. The config repo's scheduled sync covers this."
+ exit 0
+ fi
+
+ payload=$(jq -n --arg sha "$SHA" --arg repo "$REPO" \
+ '{event_type:"seal-custom-code",client_payload:{target:"all",sha:$sha,repo:$repo}}')
+ code=$(curl -sS -o /tmp/dispatch.txt -w '%{http_code}' -X POST \
+ -H "Authorization: Bearer ${DISPATCH_TOKEN}" \
+ -H "Accept: application/vnd.github+json" \
+ -H "X-GitHub-Api-Version: 2022-11-28" \
+ "https://api.github.com/repos/${CONFIG_REPO}/dispatches" \
+ -d "$payload")
+ if [ "$code" = "204" ]; then
+ echo "Re-seal dispatched to ${CONFIG_REPO}."
+ else
+ echo "Dispatch failed (HTTP $code)" >&2; cat /tmp/dispatch.txt >&2; exit 1
+ fi
+
+ - name: Alert on failure
+ if: failure()
+ env:
+ ALERT_WEBHOOK_URL: ${{ secrets.STLC_ALERT_WEBHOOK_URL }}
+ run: |
+ run_url="${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
+ msg="stlc seal-dispatch failed in ${{ github.repository }} — the config repo was NOT notified to re-seal (likely an expired CONFIG_DISPATCH_TOKEN). The config repo's scheduled sync is the backstop, but verify the token. Run: $run_url"
+ echo "::error title=stlc workflow failed::$msg"
+ { echo "### ⚠️ stlc workflow failed"; echo ""; echo "$msg"; } >> "$GITHUB_STEP_SUMMARY"
+ if [ -n "${ALERT_WEBHOOK_URL:-}" ]; then
+ curl -sS -X POST -H 'Content-Type: application/json' \
+ -d "$(jq -n --arg text "$msg" '{text:$text}')" "$ALERT_WEBHOOK_URL" \
+ || echo "::warning::Alert webhook POST failed"
+ fi
From 2cd45118be15cd53549202857e3675a939e8f33a Mon Sep 17 00:00:00 2001
From: stlc-bot
Date: Tue, 25 Aug 2026 17:55:29 +0000
Subject: [PATCH 07/16] feat(stlc): add stlc workspace and CI automation
Stainless-Generated-From: 81b14ec50109111ba0147804538449c883544a98
---
scripts/mock | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/mock b/scripts/mock
index 474f5a99..099a4c9c 100755
--- a/scripts/mock
+++ b/scripts/mock
@@ -16,7 +16,7 @@ elif [ -n "$STAINLESS_OPENAPI_SPEC_URL" ]; then
URL="$STAINLESS_OPENAPI_SPEC_URL"
else
# Embedded OpenAPI spec (base64-encoded, gzipped)
- EMBEDDED_SPEC="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"
+ EMBEDDED_SPEC="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"
SPEC_TMPFILE="$(mktemp)"
trap 'rm -f "$SPEC_TMPFILE"' EXIT
echo "$EMBEDDED_SPEC" | base64 --decode | gunzip > "$SPEC_TMPFILE"
From cc6b2fe9e219a7907bdb324f2e46ddf3cebd858e Mon Sep 17 00:00:00 2001
From: Jon Harrell <4829245+jharrell@users.noreply.github.com>
Date: Thu, 27 Aug 2026 09:38:39 -0500
Subject: [PATCH 08/16] chore(ci): point stlc workflows at openlayer-ai
---
.github/workflows/stlc-promote.yml | 11 ++++-------
.github/workflows/stlc-sync.yml | 19 ++++++++-----------
2 files changed, 12 insertions(+), 18 deletions(-)
diff --git a/.github/workflows/stlc-promote.yml b/.github/workflows/stlc-promote.yml
index 4b212ec8..80b41044 100644
--- a/.github/workflows/stlc-promote.yml
+++ b/.github/workflows/stlc-promote.yml
@@ -1,8 +1,5 @@
-# NOTE(stlc migration, 2026-08-25): repo names below point at the
-# stainless-sdks placeholder repos used to validate the migration.
-# At cutover, replace:
-# - the production repo with openlayer-ai/openlayer-java
-# - the staging/config repo owner with your own org after transfer
+# NOTE(stlc migration): repo names below are set for openlayer-ai. CONFIG_REPO is
+# left as a TODO -- set it to your config repo, then re-seal with `stlc build --push`.
name: Promote SDKs
# Promote staging to production by fast-forwarding production main up to staging,
@@ -19,12 +16,12 @@ jobs:
promote:
# Runner comes from the STLC_RUNNER repo/org variable when set; defaults to GitHub-hosted.
runs-on: ${{ vars.STLC_RUNNER || 'ubuntu-latest' }}
- if: github.repository == 'stainless-sdks/openlayer-java-staging'
+ if: github.repository == 'openlayer-ai/openlayer-java-staging'
# Optional gate: add required reviewers to this environment to approve each
# promote. With none it only scopes secrets and adds no gate. Remove if unused.
environment: production
env:
- PRODUCTION_REPO: stainless-sdks/openlayer-java-prod
+ PRODUCTION_REPO: openlayer-ai/openlayer-java
GH_TOKEN: ${{ secrets.PRODUCTION_REPO_TOKEN }}
steps:
- name: Check out staging
diff --git a/.github/workflows/stlc-sync.yml b/.github/workflows/stlc-sync.yml
index 2051d379..fc0fb8e0 100644
--- a/.github/workflows/stlc-sync.yml
+++ b/.github/workflows/stlc-sync.yml
@@ -1,8 +1,5 @@
-# NOTE(stlc migration, 2026-08-25): repo names below point at the
-# stainless-sdks placeholder repos used to validate the migration.
-# At cutover, replace:
-# - the production repo with openlayer-ai/openlayer-java
-# - the staging/config repo owner with your own org after transfer
+# NOTE(stlc migration): repo names below are set for openlayer-ai. CONFIG_REPO is
+# left as a TODO -- set it to your config repo, then re-seal with `stlc build --push`.
name: Sync SDK repos
# Keeps the staging and production trunks in sync and the config repo's
@@ -29,7 +26,7 @@ jobs:
# Runner comes from the STLC_RUNNER repo/org variable when set; defaults to GitHub-hosted.
runs-on: ${{ vars.STLC_RUNNER || 'ubuntu-latest' }}
if: >-
- github.repository == 'stainless-sdks/openlayer-java-staging' &&
+ github.repository == 'openlayer-ai/openlayer-java-staging' &&
(github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || github.event_name == 'repository_dispatch')
permissions:
contents: write
@@ -37,7 +34,7 @@ jobs:
group: stlc-back-sync
cancel-in-progress: true
env:
- PRODUCTION_REPO: stainless-sdks/openlayer-java-prod
+ PRODUCTION_REPO: openlayer-ai/openlayer-java
steps:
- name: Check out staging
uses: actions/checkout@v6
@@ -105,12 +102,12 @@ jobs:
# the poll. Dispatch-only: it cannot write production or staging contents.
runs-on: ${{ vars.STLC_RUNNER || 'ubuntu-latest' }}
if: >-
- github.repository == 'stainless-sdks/openlayer-java-prod' &&
+ github.repository == 'openlayer-ai/openlayer-java' &&
(github.event_name == 'release' || github.event_name == 'workflow_dispatch')
permissions:
contents: read
env:
- STAGING_REPO: stainless-sdks/openlayer-java-staging
+ STAGING_REPO: openlayer-ai/openlayer-java-staging
steps:
- name: Dispatch back-sync to staging
env:
@@ -158,7 +155,7 @@ jobs:
# stlc's own pushes, so the bot's commits can't trigger a re-seal loop.
runs-on: ${{ vars.STLC_RUNNER || 'ubuntu-latest' }}
if: >-
- github.repository == 'stainless-sdks/openlayer-java-staging' &&
+ github.repository == 'openlayer-ai/openlayer-java-staging' &&
github.event_name == 'push'
permissions:
contents: read
@@ -166,7 +163,7 @@ jobs:
group: seal-dispatch-${{ github.ref }}
cancel-in-progress: false
env:
- CONFIG_REPO: stainless-sdks/openlayer-config
+ CONFIG_REPO: TODO-set-to-your-config-repo # e.g. openlayer-ai/openlayer-config
steps:
- name: Loop-guard and send re-seal dispatch
env:
From 558246d6f68f8f8fa61a230d86994af5eccda02c Mon Sep 17 00:00:00 2001
From: Vinicius Mello
Date: Thu, 3 Sep 2026 13:00:36 -0300
Subject: [PATCH 09/16] Build SDK
Stainless-Generated-From: 7286f84b91b4f8f61a6ae4262c9d59367397d26b
---
scripts/mock | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/mock b/scripts/mock
index 099a4c9c..474f5a99 100755
--- a/scripts/mock
+++ b/scripts/mock
@@ -16,7 +16,7 @@ elif [ -n "$STAINLESS_OPENAPI_SPEC_URL" ]; then
URL="$STAINLESS_OPENAPI_SPEC_URL"
else
# Embedded OpenAPI spec (base64-encoded, gzipped)
- EMBEDDED_SPEC="H4sIAAAAAAAAA+19i1cbObL3v6Lbe78DzLXNmyTeZXdJYGa5AwmXx8y3X+Ajwi3bvWl3e/oB8XL8v99TpUdL3ep229gECHvOngltPUpSqar0U1Xp3gmHLKBDz2k7m6211qbTcLygGzrte6cTBgntJPBPNqCe77SdOB0Owyj5O1Ty6YhFrU44cBpOQAfMaTuf5Gen4aQRVOgnyTBur64aFVadccNxWdyJvGHihYHTdvZODkk3jIgXJCyincQLeuTOS/ok6TOimiUxi25Z1HIaTuIlvtEl2Ts5dBrOLYti3uR6a81pON+aftjD4ZgEwddWx2c0uvESJMoc03jccHhvsdP+nK9Nh17LHNLtupMf06c0IsModMkN7XxlgeuMr6DNThp5yQgbvWE0YtFemvSd9ucr+HlIk34M1K7ehdHXeEg7LF69V/8+dMfwY4/hqsTpYECjkdN2TlkSeeyWEUpUWXIzIl4Sk8N9mK9wyCIKhB26Thsa+F2Wez86dAu0T25wSCM6YImcn/+MWNdpO39a7YSDYRiwIIlXsyKr2ghwGiIWD8MgZjjWjbU1+E+eAl6CfPoVugNmZAEOmw6HvtfBwaz+K4bC907c6bMBhX/ZCOG/xqtqzM54PEYe7NLUT8qqKSJXLwL2bcg6CXMPoiiMkDu+NTuhy87oYOgzPgc+DXpO2xmOkn4YOA0nDtOoA0zajcIBUfxCvAFsooytL4PLoON7LEjIbvZ1eUV+bWW80IrEwiyrb9eeu3vprL/duHG32XZzh63T5laXbTXpm3fvmpTuuO/oDr3Z2GGXzspl4IwbitJkNBRzrlObJ48g+UuK/qU/I8FhECfaoHZJwO506v98GdA76mllrOPQmbtN6g5knBtJL9RHMKSdr7THyIB6AdAqRrR8GRByyVnpW3LpwE/woecl/fTGFAJN6ml/9EIoXbfsaohMDFVWtLVt72pT8ZHdfcDPsMx8lX/PZucXliwLMlvnn/Y/La80ak9Nbmb+RW+pZXU74UCTYCDPBK+pFeTk/VnNXmmN8CuIxazip6//SJLh5OqD0GV+nA37F5acgMSIp6wkJQWyZY58UtxXOnktYO2D4Ba59TIokkKG/D+7pPhb6yb1fBdYnf8LG7ERRqQgIbuksKOXV1o9lizzfqAFffE6oHa0xYO/SbMZsT9SFifkl4NzcnkJjNlswi9V6klXKHUYSTXcZ9RlEVkCNRVG3r9R8LbJe9Rd5C9J+JUFf10Cuq/GDWeY5lTTxdCliaFHiuooxTLVGsnezg+vhQQrvA/dkbTZahEIot9pO+HNv1gHpP8wgiVJPD4X3J6rOYzVrO4qVgTTyU97MzWAFcdghN56CfsQurPRoVUfj/k0fx99zVkbNc9MGrsBNWFWdy+d41EmhcQvMF27l85g1LzLfkG180T0vDb+2TR9A0cP5XPDx7HDd3Pw48Lon7dt0CkYBxfZlOZsBE7GFIyV9ana561zDXcPZQj5iAuQlf15Ob8YvGtCznBJzJLm8vCS40ZhlZ6PnaLP0PT1FmCt6ARZDBb952qbxaRwktkitvZMlsvJxZOxXFRxlyaULAmev0QdeOlYBI8sAPKHF8iLX0LGwiAaN8pP8jDY5lc2Qo07DOOc4fQhYtzgAXkL+MhXNiJekLeATHulZiXT/Opgpb2h9ysbHWbcMG/zar1oXp0lNEljwql252Zh8aE4QvF/PxOJ01G0jx7RIqFD7xp4wLKFW+K3uMUZYG5GCvDdr2z0PQwRnHCySyosEl7GGPS9PuoZTRM16JdmgPD5ahAWRVCqaI/snRzihH5kd4sySngXH9ldHbtErcQLsDVyA5+p6gIsjhxZFqMjV6La7iiQOsn0EHt4eaUVsLsZLZBPZ4szQZRqX4QtoonXmoYGPw3Hk64OfA8EbJeI4hPthh5LDnnR9yPdaii9SpjcwQMMjsbE4kPaY7XKsegEi9aCiIQNwwEivsxY+FszYN+SYvk94nvBV5KEeLcFZQgQBvOSddYo2iFxEnlBz0HLYWYbBrjfi5jrtD87XsIGsXOVN2z456wujSI6gmtB+b3K4uH8ICyc53nDIpizBcw6u0n0lDCYwohmvHN5YYZN0ZIR0qx1BBP1w92/iNHD4Ke3NrTKC7A3CqRZLI5CmWqbw0LwJKtD7KPlFb6TntyVjdTzs17dFCAIPkckjVkUg8KqtAZ45xdQ9jwsNwcmtPlIiMOU1znPWo0uBv9Al6CZB3jMBjcs0pER7mKE9Ib+RGSlWH+AX+K+N9S/Ylvf9wZIat+5gCx81nc/Xzr/CvvB392QgawAKOLS+RcNWPblCsvD+Hcvnb3948OPT9MoscIw010Q8Ulpk1qzglMCrYs5+XGsmgXiM7yLPD5zINflip9d7ievz1ig66fmIj1/ICc3QzNVXZhhVQXk5ErUMaqmAHIyk+qJAjmzmVRlOA6XVIDk1JbgUA1EFod/lCA3kZ9hFIKStiM8YOISVSJvtoEpe5L9aFpLWHUUplGmspZi1db09trUCEyNopyYj9zxZGLxhMZfz8FgeQV3pjbaBJtkZuk2n7InjewoZsUz23e2f3LE/PkFGh5SlthBlKyuKJcd1+/zPr1PXrkXhjBdnfmp8wIhmR4v/GRV4BaqLJpbcu/jASCyxwciGgntgZRxlJ6DQIy8o4Xoq8Q74kT9WuJwIarDnYapMFvO4nCJutL6OyEI9cl7DIUgV6jAz/oZNPNiEASKw4e2Wvxn2Zr2Q0uUlTbG7qXj+4PmDY2/x4UAL5MNulQXidHfy+G3yVI2/KX86PmvttEvGYNvkyU5+KXLYPyydJ0Yft4pQuk+OGpPVH3mcbnEmUFxIT+on6vZ1UuWNy3LH/mD9zRm0AioWa+LlP/HLgk8n2D/Qxp4nWUWRS3c98srK5fB+HkqZC6Tp1XJvNbclbJOTEEt6z9mipkf+1qwF/NMIH7Stt1yhTSSxeWeXLZ1K1mkdXR0fP1+7+xA1srMg9xglIlQKlGXV6RUeYQj/YxGQqH4B67Wmnx/5TVbPd8MU2nAz9qKqFIVugOqyOXi5XUVYj/1r96Lf4nw0CFNOv3Jdo+IqCmze7h7b5ndo8JxRPWlmAxYQmFuwIIxwly5tw6GuDbsQa9TYQhyrN8xhOcJ2Fb5wz91XQ+KUv9EO/F3qR+zWVxXxQhtsT3G9E7dil4b48WiYRjPQo6sOW44KMhhx9SFMIyLo6yybGqf3TIfCszaXNYAzBdN6CmDVfXCYJ+OZiGy2MZjXmqVW85aeA+RooBfam126dvt7s5Wc/vN+pvm1vbORvNms9tpbnTe7Wx2d3Zol+4omZdZ3acM/u0WBKlpf+8FhPfslsvSp2pua1O2VGeSuFl9n00Ut8BzE7VUnKc2WZowT0uoUS6DH8s4nxQ/NQXnFgzv+tFTBUaXMVT7+gqa1SayveHx/LKN/CmjsIxaczfy7RFYlh8LRr6yZpbrMl7xeFBkJesxYTL3lBv+EyPDNMv/QXFhe+cf/jG96b9aZ+qewvmgTL1ZzgkTl0s/DoBV5rOETbb697FcqdXPmymz+kXlDO00UsI8VaP/YSZ66VFrVeQa0m9d5dwLA3AAprwx/fplLEirgVd9J/ub6OP9qGxNsEW4bRStkWXZvKRvhTvai88z3Npmk//qZP907mEFazw/Z/sMeeYcmzmmGyeI2i5JT+VS1xjOvTYecGdbqjOcpcaLg8rz1vcHMUlHcs0tNrg2bTN6pkm8EjvT75ifoQ+ZdjkrJm+W22ZRdSGXzrm2q81DsUvkJbK0f6ZYZkLKpiRvXnMTm/bY8vqR8Ykrn+X1NeOzMHyLB+JF3GlbTYk5XXSXmh/mXbcwGaqvvKWaqUw1wBsqmB5ztDwW6N0/pa59upfpJpXfU6NrN+qz6XQiWGr3/tIZsDimPXGIuhBnIrDrhlE4GCbSazhOwoj22HUaebuXTrzZXl1ttVpPwOu9bHZmNhHk5LTJ1LNzEXlQTp+dH8TgmL/7u2Fk5J3fP4gVqrynz1Xlf95LjXTMVzaPAhbXuJWhh2OViklbb7N+tvYrz9ca4tqHT9hsN/287oLu+83G6xpEmtSc1SQqzovVJuJ9LpdW4v+2VcXqQuaUMmOuuLCrdAIycWRy5Byssdm8B+ZhjhUgwMnCGdz+s7ng5bLpmHTbv+oFXRaxoMOaQ2/IfC9gNjTqOAy8JERkowhGqSZI1oQNkDqU5U5ksRqYlKXxJw1GNeTtOP8P5KF02s4fKYtGhUH+7PkJi7KkFgDdACAKNVsGDCRu4cvRplcMbPoI2Rw3PmMYTG2Sa7VJXgok5hWERmFkU1m+L9tULYrYx4HJCv2+DMSsYlgPbGTuVmMFqYX75IqyldfLtdOXlF0CV05FtY1blAOPH0QyyXCaE/ZWZmwJvKxoEZUia4GlcMF6siF3hYU6DDJLbbEXr/NH4Oya/gmCcGWEPoZJUTQhLM56NjtjDkCdcN6Dp27SDleApSEzooSFsb+j015BOOXc3Cuc+Sz2jZ7QwvCLnBLiU85+2bQt2Xz8Jk7sUuYU9qKsp8Lcl3r8WeyqCjRwcWZVHiOscPWrsV0k0mdzMNQ34w/kFPicLb7KQKHK0nO0+oRTocE+FTFH1fw5hSWZk7jT25KPH240Z3NyHu6GurNhQR2XhiJVLuJloGOQEhdVYxc3jua7dKX5X3O3w2SZw9Ar0o3Qc61JZkUn4lkgS+pa8zr7cVwR1ci/fxjSHC+nHxH+kpeh6iU4aX8K7nhG79oVhlLYHj/qy3ZireUd7I/0rp25Oad53K5Qc+7GR56ogr2RL1CVNaRIp0V/Z5ecj/PandJUC3vrrvROLmFxYrzpYnPIL/GlgrotxwIb8Z9qoT/nLJ4zzvMonlZANuQoeKrwTo6+KTSl2O9hfBnMrDRx9YuQDvKa6TcwK4yjgJyPIXFTPkuMROFdXBKEed73Ys6VnT7rfI3xAWezJvArXD6CjRqzJAtyT3h6FHjuuQd2mvohTm/Eb6ql0/DuQ5gGWbBM0o9Y3A99FxKhCn8B5TQDqswLYq/Xx5xw3NAtb4tXGDAapxEDf8nyCuRP5CKGh6lhRPQmDv2UD5N0sITWHt+WYcQb+8turrtb6qdI2Rr5EzmEOYCl57+O+T9k8r80ZvF1ZqRfw0zunkcpA3J+DiMyUHAzAfXBazHoAZn8+s4L3PBud3NnbQ2qrJN+mEZyOX06kgXW9A6TiHqBF/SuxcLt/ow32FqJW+p7LlUk6WWebuitsVvy3ndTY55QpWyvGBDdQ7ZKgqe/4k4R+6SKubNtAukmA2OXaDtk0v7Q9kbpziCrq7X2htwXhV2BOwL2A7Rk7AjcD3w3AOOdqK2wTxPaJgluhdXVsr2Q7YTfkc/bhO+E1VVtK+BGkL+vqb7OxS7Y50vSJl21C+Dn39QWKBR4YS6VkyKqz3FfLczBEpqv8/aTZTPWCKqeaW/KdmvkYjKoh/KHcisrV025l+u3I6rs5zejokvf+1cTaJJllXTQlOmhLijMibNIghVNzR3rcmOqmp+UlKg/IbLOEYvj8z4NPkUHf6TU15v9jcsYvc217Hehd2UC6osyWcN/PrCLFclsBXHCG6wQKLxAhUgB195Z4fvF45+oWb97gHW55WoBPx9ivl6iTcPbKdqwl47QzpOMz0sn09E8KfTjWbMzmaslRuqlU1TNUF7bMJdOXhNDAW3TwAqpbYOdGY3ntg4U0DcPL1TYPmaxLFg+5x9bfjDnjqzI3GkATGqcvnOetLxc9REdfF5QXT49x9cJRXsh9Xnm7MxJNk57PRYnzK3lKQsbTNXgs9WyOaDehKHPKI84EyAALuK4BpVe0PFTl+1Fnb53y1yd2DDyel6Q4faVJOPdwi0Ta8qPDC7cU1ASD1nH63qd/HWGdSzCmbbhdMNoQBPIq5Z6LjrIUvdT4I+Ud7DZ/3mflV+X8HsS9g3BB6ddK3GI03CC1PfpDdSAjTnWpqa4faeZnTsv6VuMc7Kc2eMrExY6T9qrQ/S0DtEGPPWoF0HzgrfiUnzrIc7Q3wmNkAOagEVYUwVMcVp6YQdNnJQJx8wqj+jpPOQXZE4/3Dl1FmtauaOmNU0bkcFTqeE53hdsVF9/YxZj8kfK0inffK9+kQzSpp6yOPWTi8i3iO+GVgJsMYt8fzrpPHV1MaQjP6SuRWOoX4pKY0C/HbGgB14OW2trjYJysSsm16KVLFOVN2fGjVpJRaWOemBWUVszubSiVNp/MzRFM9tRO5/N0pJWe9zQjGWbBcSCdOC0P6MxeDXO/lftdQPcmPrJ9CmoRMIGPP/KNsrOKnzLZOF+ZRkhVNSf3ipa/TTnolNMFDGzBNL8cL7/sWiGw0mN5rmd+5opa3qj+JeQ+px7n194oHQqgs10LTZT0RKewVnq+4cH6kM7zY/M4jtVz2v+5Xm457ynNFlcJy5wBuez3P0L7zjr9pmHBZYPZ8bK8/PLqmq90ptK20IPyqhVPjfW/BGPkimrht0zs+eWxWF79b7gWW76Ndsj/Eq8nS3e1FObOBZ6dECTfRvSYAKOeYBlMswy4OAr18BxvTQFBZWbPwwI29XJksqq168csGVfUuTg947mswXxKb9jvkOLRZ6XeWAJqjNGaNkWrykEykPdwOm6xFKwzuTsjPLkLYCy8KMZvLNtbSw+SKzcY7u8aCE8zLLqC0kPUO0RPimi63H8xOtGc9mNg/lgtFX2hEBpF2ZNvCTVPC/sdfrXkgrDeSDCWdleDuqMmCgrfB4uIs9mo2l48PoaAMLmlWvDuYu8hPEbaf6heCEtEpWRNPIAH8J3TlX3ykuG/A7bHY4oLHBJqtxCT9BAImf7v5Iwwi8Xh4A79Wng+qykNfEGQtx61AePpjXAjGeQHmx+Ec0Xn90R7vjzJM0ybdwPM8oAdcBnLX73kv5HHoScjX3lRzTbqp8peqjlVmPCX4htN9tDQSXNLN7Cq3xKqLL0Quy8oMAaUxiA07waZLUBH/SU0MVTNQOLaUI1F1Y10VVP+1RZjOKNnu9rMc7x/Z2nqfH5mrxcwEUb3yvcMpXe3s9m7hVxKVWnfJYerJV5M4vXyjq5k7WyXvq7oS/m1MygfIUImEn57h8cHZwfPFH9O8MtED7A24yTiNGBLbS/LOnjSXrje3E/2/YFJxvepnC5NpWorGwkgkSbYRh6QQJnZ2uOyKcPDVX5gcRpp8NiiyeI/KHCewqAiysJFGxzep8KjgQBRZZLtaI3jkgnbllx4WrvBcM0iQnc64VpAv/WowE+34M7f3TN7wPbzl2fJgRCnfoMYnkhiAba970u+xtwI7bgtJ2tDafh4A6JnfYbWExg8bXW2kbDSbwBixM6GDrt9Z2NNf4/YJAMRBKXh6Vuhvb3yUUgAsxx1+tBvTBgn7qlPCsBsqOjY9wyZR5UyiuP3qQ+jT74NI7h/lMFB9Wtecp6EYvj2rXYt8TW2ZW2QPcOT/6Pg4xCXwRgRPoGcu7vSbaKZDzGJnDhf6ORB1MOpwSUPdpqX8n1/BD66SD4KAJf+BJry2j8nC0uX3TjR+QCWOfBp+45MIdZlbNLHtx0PuByplzMoQegDKMjXN61yD4bssCNSRhw5O+nnzLDVjoHgr8uRsD/9FNL7UwpJ3A/Kc65WgQ4+CdyxJKlmMR0RO4YuaNc6PIh4JC6oe+Hd7ClovCuQe76XqdPIjaMWAx8QSgGovtkGDHXw8iY9mWA87BLRMq2bPn4CRD265J9u6pMbnxFefmtDfWZLwd8ftOQFnSMxXAbi0JyueF7tpvRyx2GfBKxIY2YeFIUJtdYQDlIN7d+Ys2AcrlqLXII8ZNeDM12aMwaMIt9eou5jY+OjmWldj5ypIUnINvBS64TkHLNF+KaWyji8AP07lp+bnGePPJR16qD2zBNrm/FjrqGYzjkFDHWRAY58jm/7iD/Xwt8Vi6ERG3TwXXYvcZ1yJWUayNKwsLkSvC1kjlO5Crlm8lWT5TkwmT38/0lChPOFDAA/riIECn8c16qXIJYMc8+uXOxPpFFE9J6MqYJbfEa8wTEYbvvfobGr9QUwoLu8v88/iG63jE6Nxn3uRmZESyXg2/rGT3yuqFNPi9lq710pWJ68yqiTZb4pyVVxCbv22SJM3FWzFQXbbIEH7KfLfoGGpFfs4Kch9vk8z0BHm4TJHypQQT3tslSnnWXyFiOaKyxiD2IOqtZT8Lq89QmS1sbS9pnPglSxmYToUnZ3PB1OZslHGjoQdQvz3m1wOMgd89wK8hDaT7Sy4amwAY606WJFVYp3VRTShnd+7V4olYDMFKRcPdJvh215BKfp2iJV78IvDC4Wp66ntBpGjmEfCrscTMFh1RceoIMQj5at71ZUyoys+aHnCQw63DVZtY4twmHXFeZstPrjvU/TnHT6/U+Xw3o8DO/+L6C7AxRl3bY/fi+5LNO1CzmWFbXapZlP+fNs+yXgpmmVbKba/p0qPl42Tm+J+6Gh7WhgYiiFZiRVpp4PnrbPxxcXF3VzhNgF8tjOeTJwpM9/sF8dgsnja7HIC9IMHHcrdPwDtvYJbXK2l9JTpO9/BF9tGzuhwb57zgMznALtcLu8oTdsVKnfWVBF9qGHVSrCWVaYxMf08ENi6CJN7VqC7M7Vxd24orF410upEjLqeabyAknmPqATzk5URBbjWXMcOXJq2is4MMh5RY3J5cnd8w1TivsyoNU7SqiQpH5Wnl7VFdPqpBpamY6RRUoGsDLsG05L+lcnC1ry2bm6ipOFbRYsjn9pIrKxy75xEbhnSJjys2ZaynHgMf0KxPyAtHKSgZTtwA1jDKyq5m1uWOecT0Aq78iDzePkHh/JrD+u2Th56mnilkX7dZFGTir2Q8VpoXdrCgxKSrQH2LmWrwUwBoUU5m25KOlZZmqCviD/uMEIEIdi/RTEU9/ld/XBgHmnJqV85ZZtnk5FTn0xmJ05WsU4RfTiMuXNzCdrKhN7ogOxGLimdB8fKE+/8urhupbqrKbB8x8hlHbC7xcWujbrXEYiZWoDo6CaYcRc6gTyiO8i9lsgulecM06p3Gnutff+yzpswicYIMw0XpEOjLaMZNY3GGBi1IhcllUL17Lkj/rx8mq1HCuByyhcw4kh8xWp+FdFkU+OcnJMSTag5WTftFP7oL0yaVYFx7sPF3cd8izzsU0HXrXX9loN4xbLLj1ojDAWJRL59PJwcejvX8enF7vnRxe/3rwT+UoiyKzOkQvvIv18Nx5uIwNIy9IlrFlZOK5A+Bqikz0G3U+f1SnDdAtMB1M1eelwgwh6jxe0doUU8Wx81L7UpuverB41kXos5Yf9vR5mQ+uCn92B48IsXbToINkLa9wO6sacxXXVJlb997J4a9sxB/r2js5JL+ykQTS8EgBM1QDggWELcs3UAK/TomzVmCcp+FdLs+AINcCa9mBLWFEdgfgqOcFCRwA/89/3V5ewlNYOOrWodgvEzAwyRtFPEnc5v9Z45ing5Sp/ZSTP8bUPrwdw+1uCM5KHdL1AuqTDrhAkGPqBdkbmN4tACbHgp3HfBMRIurFCU28DrkNPZezPEeCPl8RGvXiFf2c8SAMTjaSGwIpkeD6gReKqBwLddGVP6uTVY7VovRmpLOa0PA8G6/QUihp9FtINcJ2W4wuYHfLQmGJF92ynQ61xbgsl5R25VQfNbpELyQUsytP4tSPQ33c4/74ASGdZV59YPUv9uAlDirq50m5cM8wecQI7fuMLs8lFBxc+BEeuzWPJzyKsNzuf+7+hU8wVjUK72yFBl6gO92tYzSo8WVtzXDCm2ikI7Ymbi2RnW3phfPuWotw0prWbygK7655VJHmNpR9jDO/rF4UpoF7nURp0pcZ4xmJ0wDwundbra0362Tg+T54uA08n8XckoZNwmiU9PnjmZpPUqFrgYyjWaX3lnP5MQmp9NaZdACZf5xq1gjWfbu5MXr31t3U3XZ2tel9Rq47+Qmbm+uOJnd3l+SElfr18NU/h8U3vGh0rljS7n/FpLd1i0kvOxMjG+3bXFVqxuLNXd//TZ9MOZeiqylMgOkMgCLab6DkcxEccrKtOLyVJ3hXZueNB8PI2k/TJ8P6mSWdPmTM94KebwtJxFtrePxX/XK43yA8TSZAZ5/OmU/ihA1nyFA8vfUzpEn/qVowNfQ8ppgtM2GeXVL42bE4zAxXA42bd9asSeowQ+yQQiDieSB2ckJrYXbGrE6hFw1NaEHzsjlbYDagh8jGGXMBzRTcPaVIbRHI66LCKqg78IKYdGhAhiyCTN7cG4ligMIzkbRbluuX8I4ICdhNfX9E+Ny6GIG+tbZZrPFzGN14rsuC8hnibXDUkLdT0jPc5XVB+T5qwPv3k7OTxOt8I+RrCNenLElriU5txh4iOBcYpvvo8nFKg7U0GX5ZfC6mrFeic7ps+MUcZqUJ8X2KTRfz4j87D4s5ZsN/TW3/o6a2t+kMe5r7F5hZxZ70nmu4JctOXqoLL5VhM887jKj8XrpuOvx5pEorva1+Mcnxa43s4e3ML1VLLYIrfOrr5LqfS7IW0DnL60fqT65Nl9fX1o5s+VxqTqAloYv11tryQMDis+pObbI9gnEIbsJTe8X+whJCe72I9fD9T2iD39WWWm88kGdIe17Asx9Amg7wSMRQYFjgU5akUQBXp9LjFkkjd/2QB8djcBoF7ZxFBRU70nDSyyDpMy/CA/ytl4y4N0WceJ0YDsR9uKiNeRYL0gG3xLiBGVojV/2JE0vSmPZYA0kGz+W4dRk8ZWP01d13srvv43hpTpkR8Anb1Rcxi/bEjhcZlnOnCmhN7lolHGBruZjqpdpBmAtT2umwYcLcBhcmXkxuGKw6POY31zcRK30aZEIazi0/0P1AjSwWEsa+Rtk8f6ddQcRzctzN5m0imiUm70LN3VTpIgvIvz5Vr768dl/e+ikVfmHJhcbUC3bnlb0tzp9X8scP59NbdJ3W991DvHyrW37Ofr/1Rlb3cJUTdM/GKTgb3QTH4JwWnN47WPT0NDyE+Tnr+7gIT3dYFae1h55X5aFv/kdWSaDKDVd5QLWdTC8DeTStOorCMbSB9ydBZ8RPpph3z4vAjA5c4lO0TaCF1+Pq63H1RzuunvF9WO/EKsXB66H1hR9apXR+PbfOdG4906fv9ej6pI6uZyZrL/70Kjt8PcA+3gHWnPMFNf4ij7H5wU17ks2218s9zMZTj/GJnmfVIez7HWnFk5CrkPHc6wXMhfHZTq1nvGDFi+mUqEYITFISEmhEvTpJo8TrUvFqee6QJ0433KDE5PS5Q07e1bj4uGWgHbd4O61K57Dp38Ga0zFC8BqfFXjts3CiEEtQHKMxwUBQ/pVQcAan8P4ANDFuODwHpcVxGr/DEvEzPpz/ceZuQnckZzEdwtFAuFYHjLnMBc/0eDPrWAtdycZjJV1ywcUpPhoaw9uiN7Sj3Pvg3/CNdhMWad2TOxqD3hgKV/D8mOdwhsCNAH4W8eo9/Ae2Jrulfkq5Y3/dx2LOI6/XA+JBZogG5PsJnTROIEhM5h8jEQ16RY9T0QSk5WfNsNvVmwm7EDeAsdxehwwUEbw/RIdKumldBucYIACPHcSqTVGVY0B9D1bI61CfHw9NmiHQwAvhuYA0iT2XoccCiVgP3tjQibzzAhfc+Dt95qY+PCGQEOrHoew7vGURvFQrH5Vl3wBNkoOQ/oOIA8Wsk0ZeMkIBcYMiEOSi0/58BaKbnyfwr6tpQSO+yo4FssjLmfmErCc0Ss61ZzpY4GZ/FgPZzeJZ4+BY0sOHRtQ+94JkZ6sY8Q8taFzgBSRmnRDee1i+CLxvhA3DTn9FP4+v77x79w7TCY5z9M3Q/wHAfFP1/gZ63tnC3m2QnuVF5EzWpZ5bIOFwX4oxC2CahJJngUO7iJQNo/DWcwEeob5vqcSTPCKbIicwFJ93nu+TG6aaQwmlhuWsb2yyre2dN0329t1Nc33D3WzSre2d5tbGzs761vqbrbW1NZCecluw08wF3oK32YC+JFSbqmQ76RQJVE9JS/xbytCcPrRgSQfZTsdnQv5IWQo4tRa108oyg8dqeqjP1VY28ZqwuIGoGxrBjLopSjT2jXVSGcw0ly04YDEA0mB5iPX8AHC1owQAc8/yu1T9cqBvh4YDI7fggLILC6tmDFFjAoEfTCJtOzCHNWPiY/PdKQvjgi4VPYLM15WLAc5tjMvnZQZxwPW/KZJGYUpUF2Q5kxHlUsm+HjPSwwwRVZMaXUpxLpj4IJjEbsG+4cHdfOG9gBMpDQRGO/1MQGUr41S8yaUzODTKhccF2pfZ3xi2N8xEaYFxzaoW9s3lvzk9gn3c6TOw3vjSQlwHiltAlc2ROuMcMQ8Q5ZamhwvTETAWvlRoIckwje8EWD8mZE3In8i5lt9eDJf7ldIABHo48JKEuSXgNpqVLakTBQ0YITJ91CCDdAhyo+5mW1D8jHJFL6AkhhX3FkL6aSLfZHW19rwjRl6NkOdWoSYQzrEu3QJsk9ysmwYq5KHW5lwRVkDR5dzPHUd/ySj6OS7igbmV5ouaQxeyg9zLOAcGG+ivtKBmXc4YYyV71OUsxx6WaophVlaM3DQLweWP1Z5/bk+m8B1cXJ+Zqs4vdKdIUBanU/ytEJTDT99Tx+HoIkljPBWEY0oljccsYTq2ebFA7TiJyyuZDH2EZxJKgKjv8BACiBRzUvmjA5qw54X0lcEianFwj2pwc25w5QHfKPYQXtNRIA3zaRQwoauJEd/wh1MIHy9GdeOnVnk4eEWN2XCohforiaQYv7Eo5jNT6T+EcP6tdYwKe5RpNm55k1U4e9EEL6QZLCYa0XCfB9Nqj8+fD7mInB8GsdfrI8pSQeqhgNn5YYPXwPB2AYrA6U8bho3ELBWU5ovG4+9LL0sU3GOC/+BKhVA+Vl9m8Yp1UgqeTMUAe50SEz2ZgSJYOrmMCbysksYitapwU8suB3JwgpX8AEGRHByACIFOODPBnbmSjVQC4TesG4o3eQ3gYWq6XxMtPCjRQsMBf9OLIP7qDYfMFd/b97lt3pgudUOJ4122DOSUceMATnYANkeMuiMymuOrEhJ9rA9LzuXmDFdeloUmMnbLA8r56oX5ygqA/R9Gc5sbwFsAx8NuCxOEv05CETc3AGxiknDbTI5N7X9fdo8xWduJ9FpF0NICU3kuWabk4uJwf2Wa9M15RYfUc7VuUJl9m0SbNAo8d050ZAZLgZyCLTORKmGqkOVOOBh4ycocyLwLo6/xkHbMZdW/TiJOlZ0DNcKUzAgRHybRgEbHHNZMiBi5TvyupcIgwsUBJZOEJMLwBPRIl2EMzOWJya0KMtuiAy/wBpDae12TY+tIkDCENZrEl0qyjuk3aJAE2YUKKBmNyiGLkPApKBvwRjFPt0bnxvZYYOOYcklbOvmpklRhfciIDk7nzYhj1kBPPX/+7JKK50h3fH/QvKExw0uEG7jgb6JDHZjT8kpC/hCxXsSdmOAj+5bki15pGxr9erJRBhY3n3ojlJsaWphqkECMlraqPcGOrqTGOHQoW7pF9m6ph6aE+MJiQiNGvkRpAM8DfmmQL0OYIv7PLvV88U9hk3zhUTJfUNd8mTC8embKaqbwVsVI5UzkOa8u13E9y/kNU6MBv2ljR0SdDxz3BBzhYZAADHsxRgPhTPD8lTToMDEbUcDiWM5BFN6kcYJfZmRm1Tm3JWTfDgoI2TVINNEz9KI65dwrznl7Uafv3TJThZu/1Jk4PJ6KCtz9xipILFE28qpelkb+3ROIyKSYDG+G6zEQ0QBVf2UjpSGoC95g4jDcEBNRbDhvTg/otyMW9ACpWd9Y0y/Ez1gnYgnA4ZX9860O1ipNGH+8t3pEUK4J56wC2VXddKBlEVaT9cefSFhEfxj9xpPUm10ewTElfkCf+RWYREOsEYCYGzP5yuLLEH9thn7zp7L/bZ/8vuYUl77+5ADyCQTlXqLgnKqxgblIufnTRwP5es1wMsu+yU9c/rAAwXO8tu1IamH8Q35K3dbOq2HAPnURIEy8RGwDEZcnCMt7WGrzDkc6GqcRG+DBKPPGvkbs9zpmiUp+CacVPENRL4ivgxCTXOK84rmIJjgn5jkya1trRdayHC81Wia5DuT9dPlsIs9l9JYL8/xA1N80GBl/+gDHhwG7DruwJuJfMFQx9nIoQVsa03Ro5PGZMX8OJVvDj+mARV5n1nXcQ9tUW7e/7maLtbH9jNbpr06DE++BPv0L/B/++o9d6xIU4a6uH1LbVlRTt9Z6t2nOPY/XmHXqf2FhL6LD/shcACRfkOv8wsBYQO+s57IOSH9+1ssYXJfs2ViL6DNwPdpFMQM75n/A2PkUVW2pfD+aRthEV6ocxm40vRe48207CJOzxVFutj534qPw7tCFe6gaqiffjQZ+O+wbWq6nc2kOGvzFS07ZMJyXIVowNHue6TqmehemQBgEiBzOaC/NxdAbN5ybiAadvuXgWW4qF9oQsWrWw0ChcOynvVqtpnbXPiNgxFItCsNk37Nhnjm8cJYV3etgzog6DViNQM4UeQ7Im4MCZ5DTKuasIUasA5wGSSA04Qj9HqCQhbD1BDguE8ebXfp2u7uz1dx+s/6mubW9s9G82ex2mhuddzub3Z0d2qU7yGJck9rgqJo98xaM3tcreFe37Tm0ZW9V4DTZiD6GxE05nM/fZljc0S53pNOp2Fjb2GqubTY3Ns7X19ub6+219db62+3/t7hzn3bec6clSG9s8rGlZCm0z2bX6HeIRdCxl9+jm2skY8TUg+igSJSj8u/ozG+z6yxnIg6HbmyjI4nVPbsQJZD5ZIuINC0Kg4cxqbvXYRS6aUelxzAGurmDmtVlPh1NQbJEc9fqkY/Nz5lydDoXcN1kszFD5Yxl1vGw6TCyK3yf6mZKCkQNkwjFVqfhnQzDkMTQIBxQP0xjbsvLnzt9iil1IyFvGg4CzYeDG+oDeafAK9gJ3CDyunvn4Xt2GPA/3uPg8PMti/g9AP97P/K6ifrrTCY4Ul9+A8s5PqZJp88nqOt7HbjVP6I3zNeGIM+fJ56n/fUb9T2X++R3wihikAvJ/ZnRJI1UDAqPtDsGd5bOeT9icT/0UZHZJmowTEaifu5PWcSFERU66fI/jz0En/moss/4N9IqMf4eCM4DnE/8FOO3MB2+H31QUxV/AGkBRq3v/xxGA+ZqpHrxB37z6sX/HWObvj84TW/0Uf62AZ9hJuU6DArTELC7DzRhvTAayaYDdofTr/5OfX0pouyfw+FZJ7SN74+Uxt4H8KCmQZJNqO2zbCv+w/8fCe4CWxvtxQyuqjtMcWjs/VvxJfojUf+DZONY/YAbyGgoiagHXHfEKLhCq2HBDkRtFkaz2Fy1dYToo2CGbL99xzpsZ7O59Y5uNLfWb7aa796y9eb62vbWmzc76+7WDQ9mi7wevlhbuMWdP8EV97vkrs+Ez40Kfupw82I28yqRLGkD/soxAeHuJaLabQhBaYDPA6EDrQLomvIwxaKcGZt01+pOVOCIxZT9aSDfBEk/DyFfFOmeC1t334Ph3aRiI85V1sc5OV9DvGviWdIv/jyJwq7ns0VL6TLhHBtC2WOxJpHjojQWIrhEuMZTy87pxaZgzRPDP2cC4FHO4JmbD3h28X1PQrDswGiOw4Fp/MQt8jNE+HH2b/CUi5ndJ/OqUJklEPZPQ/cU1TpUEbWf75egHLwuoz03vdQgSyhW4Ptejy2Nr+oGEIpjcglsWXYCrMYrJf1dRGRNGaBR7ej4ZFYCAHGOLinJe2z6ahUQT5omIQRVdvBwGqTULyYs0QKnweRWVQg3PeHZwYRxGzyMCG+FaLJfu5KVfUzAY4uTJEsLMZnGIiI3MY4+5oQhhm5AuwpnL4XYiz3jT6JbcBqgUU44rzWKELG88bDAwY0iMFTff1g8KE+1q/W6Ue8KK4nVdboxDH5bzs/xe8X2qw/yeVEw+WCPN7iGqWGlqvKEH6e9HgYg14D+6syLag/4GHLnNm3mj5woMJxYkJRHnOtn4MkTkjlQiYZjmYNUhkoYB1vwkzn2YXv7s3ABd7MJyPERwfgn6wihUKYxxEXw7L3BVhJtZZBIPsMl7/UcVJMX9B7eZyJasvaoD/SUCVfRh/cZyaZkp2RZyz4D843Kb6WUlhOFagAxM1OSA0fqU2HDjjOoh+u9SocCjbiG9JGSWIh+Jis9+xiHh5xQ0jd+bhuCLIegpVcM+hWDfsWgXzHoVwz6FYN+xaBfMehXDPoVg37FoF8x6FcM+hWDfsWgXzHoVwz6FYN+xaBfMehXDPrJYtAqjvQfKtF6KSFFK0APAa3QJTKZfz6Zu5dxvQhZnh4FyjKFnId7vq8eH5luBJVyI0R6RhmtCeaN1zIZL/O0OphLJV4hXHlp2Z6AMcJuVmGmYYpZtI2wbnBEmRd7aXrg0iFCjvG+B9mhFJzVD1PfxazaOCx3pkGKCJAnPkjIlfOggT7rqx8t0dCjXP6cVCdLmR6tgAwDTo00BXi/JcovFFaadSC2lDSPCiTNRvaMLylMT7k1MdFsNL/ewE0iCOwGzLFbLYwflh0gy183I4UHgbtw+iCX3nTUxSrzS9nxXeRpwVyeeEvBs4P4/F8iSYueTcz61oFKiG85a6iGFT3H5U9HTJ4J0ZvI85a7UeUQUPa4hExCDgewsUQxmStuYibHqs4DFv4UKHDmi1bxC8cFYt1aXYp11ANM+eGQRdm9TJ0o8uKMYSNZwxnqIdPPcezCEn/rh3cP6x66wUZm6J6/0QKOCpVpOSqzCwvVEq/WEcer0NnfEHvdvdVhzuKUikch8FUofOepWzhxOIJ6+dRS/UefbR3qD5VhjyLbconNZ00cZ0vANymxiCZ8c7KukWWRMnc1mHKFBx8fz51njrr5ARG/k1MGTk9OLgPfwwnKJ+TLSFrb3u667s16c2Nnvdvc2tnear7dfve22d3Z3HrD2NYOXXunzZAzZUpRYXkbg5q2jd9VxQd5S1nYpeg7lR20Xk22OgRBOiL+4ssp67AF48BIK7ffsEsSiT5nJPwk9P0pCC4hCJ8RlK5biE4Psd3WxDHC5UuYwFG4E0ZuXA8dnn7asA8NM454d7rHmXyl0nROXBPeXDbfONvG216z0FdrI1Z7zmXiPc5uc7KdauQWk48fLJwP849hTs+Cn7of2bckezhtgRRj6uuHUSxse0A15n+NweEu0YVBE6SHEqeURXYtuig45+LemWfH+c2oMiWqbncqT3OTe9AOaZb3Wu2PguVvj8WrtNrpkb+uBwRox8iUJ6KDyZNAn6qYBl+D8C7gro3THgZrj1IcDh8yWnyRwzxLKs8aYHxIIV9ywW8SqdvmdGh5/xQ+1jzhDHMnnMFIWUH1TjjFx7pr1eM570ElvOcaoc6BRha1PCphAalrYNN2w8Im5EskaR7f1pPhFASZRcAUNn7pGUjyBz8LoUdGvaCGh9uW88rttBDobTGAGUC/s2VlqnFu2NmqlLyFpH1cMsJnXfLNIO/weMXATetTwFnCcve4ELB+UVA6d2cfhsPUxw2p5RWtj47M6Fr2JB2yvmVjqnbGApe2GnClln4tP/GTvD2KGdRqOlFYK9bz+bBWreVFYa1Zw+ehUE9NuyUVXB3ksb266ocd6vfDOGm/XXu7Ni/UcWb0MK9eH4Lw6aq5VNPlhZQVfbTue8nYJnfaWa+Mr0qYxsoRamePG/Ly9/FwyQWjf3l59z3QwMpIiYcTKGfwocEStZR+FQFFgPB4RDRMczEAoTH8pwIUSqLmHmVpW5WNt7WQJElTKXx0PLKXAWMqjYZhPMPV5O/glINPtY3ihA04jObF2bYHZC1hgctfwHNDk6S9IIZbMh6tAK/VeT6cPQhe8oAuQerQ0fK8xBio6b9U8FeCKfvqBS6CA9gDh9NyIzDoxWdTUI5ihX12y3wQmrPMW0hcUd3FCaxJgrPXGTCydyh4m54yeDkLRf3Ilri3IsJ0M0/URwXEuHQkX8OhXkA090cESDmaoFFIPqa+D1FAQSx8EWNRF4fjsq4XeAnzR63LwIiRBUxVvqg6Gd8pOXU4d+zGacC7oWK4JRf2/HE2YaCqyc29zlPmMTDfB3OsaJh80sdGojCu5g/5SatN+iHFKxILt7Hfhu2QNH+iijBVXEXVuvAqWyguWUkAvxvA/QxeDotEZ+VNRdab8EnulpK3jRJL7uFHIK7gL11N27NEFZ1xQaccwTikh4S+e3tZ4vRKL0lRbCKiYMMSzTfpdJ/VGiijkMEN/VUyQ+SUbnt955XsATvz6WCh6U/7+KeTufliLtYGLpA5o1Fc/0bl4Tce1kt/JF89pnYYeIlHfX/UEO9f4K9eTL7wbr/g96BBoM6dl3T63C9cvbbWIj97AW/AS0iHBuBO/oUTKN9fw3+FETxOJqj8UnbRs5hLGmPQdke+D6JIuSuf4ZtTw9dEfxTOEyMLIV75IvKqhyWiUO4iL2GTbp+wRXJxeqhFwovh3qSB6+NlNRTLB6nFm+3V1VYLh8YrTMIqcWPTNOkL2TZQgMyAAyn49TYPmHAXfRNcwW8Q3Hzm/ZtDPWpmrFzrgkHr43mByuEt57YmBgUtRlbJbTGjZFJzNhdieGuQ+0A9WgPUzYZMLMiziM/XjCJS8UWdHFc13He9fzNzqtTOCMjNKGFxzp7cgPuX0ledK8ZrFSxC0Uu7ZDDkZkm2ZWowxfQSjx9pZ2VY2x5eCJnF6MqZaS5KmIVQnI/NnJneKZVBHU+EueiCnpdwXXjWtz+8O5mSs3/sZRsu4m+UuzBnPRAKFmlVO9xJ0nYK2ncWp5SIdacjbUC9wOj6wv7Oz+SuwYN7YtfiwfihH47AkD8rtRaNp6zsKlM2Iu0eGsdhx0NhdOclfY09lmJLRLWzjy1wo+xVXP3g4qoyfcMkwDUL9M4OGE8hoYOgRpDy9BwRMe4W3ngWfSlfMoukeiQHRUWS6KuKpMdzXKyiYucZo1w1nuatuCXPfM3EAc+wOmY9tuUCrGdyYwPg6QN4p+NV+TEznCdKgKehaY5b+Gddy4Owbt3vaRSBQhyilT7G3JcndZpV6UBFTIfoZGN7ApYOF2IEYuFUjzgRhyVPPZp7YTLvY/tZszCUeTQLxMbFOK+h4CsxZ8ZYDApgdY+OjpVPjHhC9ujo2PJmbM7jKR186p7DM8s8sVm9xHQfC0+4ZhZOQV5A4+aRD3rlbzvHNp84SPzGviXzIkg0B5d0kcdAA5K9LOHC6d4vmGmhQ2PIrnEShbceWol6VRYAgTEUbqrUHCJrWx5Zwxoc5InnOIY4KdiTjHb6ECqYpyDG7iFfXeCeR2nSnxcVvEmSQJu5cfOfrvEnI1D/0J1X79lFmQdJfzFChAeGdFOfeF0yClNyR3laRvEEPQZSggIlkDUwIsPQCxK8ufEGrEUOu5iQY4iLztwGoSQNvD9S6ALa7rEAUooxl9yMyCelXMzkvy4f7zBNfqORB4wCo7Dd35dkEcG65FZURt+TuEUOYHVzP2mZUpSBKZ9QNu7uITHV9R+YVdWSClOlCoM8hJiWeF5rxJvzchCP7AUPNiyhLrXrn1xUNX7mbcta/KXoNBmmc9ta/CjE28yRzT8KLHowtD0qXMg3Mhgmyjg6Ojo21+XeiUJsGdZHpLjkD3bf35Nszch47IzrpzDlbU6ag9PQ1y8nERfTB4skjTWaJjX4gResarM4KrSwpMvLvJYwc6GpLdlllSlEu6yC6t8bsDihg+HctKZsECSb+jcZpDHmC/ICcvHx8P9CynPCz2IW4ZVgJgA/pG7WnAydM4eifna4Y200PykNrYlDb+lr91w8iTsa7jwyPwJEgxNpEOWuLW8xFwQMPlvBHV4+GN4teZNLFCJFd5nKHdwROV871Bf5W6dRIWroqDnwzsb3idYmEQluC48NkINWr0U+X4Ij+qXTIJfOLyzsRXTYH106Vzmdon6aoFJw7PXoh5faMZshVBHkgwvVN65x0WWaCKu6lPZT4XzFB3DwzUvg31eAyQZkrUHW8fjsBWAfRKJNq9KUDTkN0cqEgXZnXCpYHa7YRQtC5ZvU7KHJX3fSfzR7y+d56udltUCKZRgi09ILerEsKKXwTz/9m0VhU3KoYMz4p58aZABpr6Vy8YGt5SChsS/ZnviSt4xumO88U0NsGDHXQ0Qhnqs1tgTelqppQuPymc9ncZC1TPIwU/biaYR1jzN5NozCG3rj+R6I+XJSr2Ok7mWZFTmNqukETZeeKt/RMj1qepc+bR36C7h+RzXUKBSbQrQvQM28KhJNkbzKXbtMqxKtCY16bG5HcN5aTJZ1gEkkT1vJiRgs+sJkJT6K9y2ZcLQAIHLac8WPYor/eFLr1fz9QcTwj2T+zvHWB+9tCs/96cD4y9IhlfY2XicnEaODD/AsU4/7SNaIPfiRxKrFAbyYLvVRxZSFgJocW+0g9CQ5+LveWFpmup8OaPAzYy6kyJsHPdgg6YoWTWLwt2v5my1TbsP5Xc+jOY+YockJAmbJpgMR3NnA1Hab0B8PuIf7AD/tTfK/3DAu6bQehjRJWASt///PtPnvtea7q/9a/lu7qf5Y+ek/JxAC/avEgvP31M86yjnrLyx+P+vREsE/7eOX07v85QYskjqgyX7rJexDydtjswTnaNyLbZNO6PIx3nm+26GRux+Ce/E0eXayOKT5O/iJhhWipOjnAQsMys2/V95uWadhkPT90UUuFCN7j9Psp24ydWj1n4xakwcYbG3arXUGjznfWQdflwR9dTxlZoA1fiUtuXH+0d3QbslsD1nkhS6m5tk37bHJOVWmEwLZuwdKMwnXPJmGgtOikXUQuAsmSj52UIOkmA58aGwPowWtPtHlPtCZXMDnJKnvgz15tnd8hLFdkFOiI54GrPWgAu0k3i3jrpjJtYuZ7dNgSFFCduA5VR4j6gUyztL445p9G6KdDu6eHvWNENOrgtKtyKWIurI62FmPjTYEmSlgzA1Q5Mw8U6hp4ukPoeq8rJI6+d9Rugs9shg9LTVIQUmLCX300ea0J5xjy4yxgqwzsx6Zh+H1jc2Sd4eNbmV/rar0ShUdr28YZuGpF/fpDTmlAxrQpG/ZwBYaRP/jmpu0w4Z8DwwZxv3YI11FHyI+u5Cvfhr/9YlbU99xBUf3xeW33CixyOtZ22btqa3tuezQB5lDyDBsQD1rHJnqnZeoYlrYA3/HYhBeUMWxvBDP8Gf3zZNsurd/fPjRaTjHB8fvD06dhvPb4cHvB6eVvAptlrwKYvKblFVa0ELG3A01YqQRBPkxzvHjiTa+plKkzSpVavej5Nc8VMbkOGjRa1GFPBIviv4zXhSWf98b2iVbxkvIEZqSqbIxCoJsriwvBiFYvlrvzaTnRAeGfluMSVHKD4s598uBcQhVdGYPcLKuseLBjGsklKylCNdetRb3lO+93v8Avm4mCK8WKOIVirK8ZAUwQLLSjdcTTu7jhvrjQxgEPM5pFkxj0qNABVrK9+hg1BwaKSPLA0+na1U0xS/ib/ya+UIrm8R2eJRllHh4mJ64GGbanP29f8Km/vTx/B9Ow/nnwd4prkoHLxycOgluixcUBdgnz74645RwgBmY5+rBdmLuFJFX+My64ON9HnT2GGws49uuqoZnEHcWhHddn35lj0FeLDvjOc7lXw/eZ7AWN3RSKs66G+JGPLnKWerhbYp25B6b3w57zB1hXyxt6tV8yWGWbAYoH3mdr/F+4j/KllAdXruJj4zn6jQ8mPnmLjgfc1nLp2KSVDtlbtz3uo8i1iLRF66e/OPBC8dncvLFp0xtkMiIvHrFH3MZrXNijFAn376gJ2GcgI/sYyzoUPSFCyr/eFUDT19eWNeqphaAtb6IWbTX60Wsl3+wrDxxHX+f52cvihP+zp36Bi/5qE8iDCvGJvB9OoxtF7HhGMxcEyorHoGEF4gISQOcv+shWFQ8Go5tBNc9jOV6Vi4P4l4D+liKSRdaJuyWBclqEgkIRs98st5c32hurp+vvW2vrbXX1rQH47Qpmy9ReCdcQdNGc229ubZh0qTWzAbE5YNEUx4iKtZCVs3yaotQ2CxP9jjjhMntn+ezDcAgYnxxo7yL9e2x4rGsi9oPLmOXWJ10cHilHW1vbK+JTAAzd4Sh/6U9rLXWN7bxVH/GZ3aWbWoCOzU2rZtG0gE527Q8jrS4fRuaP1PXaNnP2nzoHs+iPq3bXPy8tT1z5tqctzSFNDirgxBfg+7AraXm6RTogai1dtTCZA8XOuIp6bqUvWlvv21vLFb+oOCZki5jxiQLTr+v9kVVcsOSO8YCMUk0cE2qluE5ALiLjlknDNx4JfdI6vabndbm1vqD5JWoyYVvXDERKLPkFqvvv1Lm5q+rxsN9kWYKsZ+ON0QHIekEbqHls4aowr9gW10tQqTaZ2K+QtXax1prbWM78/ecuR9RP9/VBNba2F5rYXoxqzwocVMX+dXQxUBte6haZCrqugjxUf9Ek7nKxXXGPsXembrLMU+K7p6Gd3VuXE01oe4jr6Pw7tpQGlZvoXykf746QnAx66SRl4zOwCgWRyZGIxbtga9o1gOkHpO2MzqjYKHCLL3HzzlfE9Jn1BU2C8jpMBqQL6LkX3An/PVLQ+QV/SI/gBMths5kLi17J4fkKxu1yBlj5PPPXuDyEuL71bLMj3Z3d5fLj+aGnXhVtdSkgSvx6ni16wVuExpq0qHX/MpGK8jDgxDjdzjvg8fMZYCXCv8LIf3XxbcJAgA="
+ EMBEDDED_SPEC="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"
SPEC_TMPFILE="$(mktemp)"
trap 'rm -f "$SPEC_TMPFILE"' EXIT
echo "$EMBEDDED_SPEC" | base64 --decode | gunzip > "$SPEC_TMPFILE"
From 3f92890a84d9e9df6e1f672359d7eabd88682284 Mon Sep 17 00:00:00 2001
From: Vinicius Mello
Date: Thu, 3 Sep 2026 13:12:36 -0300
Subject: [PATCH 10/16] ci(stlc): route promote/sync workflows to the
openlayer-ai repo names
The transferred staging repos live at openlayer-ai/openlayer--staging-new,
but the shipped stlc-promote.yml / stlc-sync.yml gates named
openlayer--staging (and openlayer-typescript-staging for TS), so every
job was being skipped silently. Point the `github.repository ==` gates and
STAGING_REPO at the real slugs and set CONFIG_REPO to the stlc config repo.
Co-Authored-By: Claude Fable 5.1
Claude-Session: https://claude.ai/code/session_01XwEaNPPVYspSLwxPo3yquG
---
.github/workflows/stlc-promote.yml | 4 +---
.github/workflows/stlc-sync.yml | 10 ++++------
2 files changed, 5 insertions(+), 9 deletions(-)
diff --git a/.github/workflows/stlc-promote.yml b/.github/workflows/stlc-promote.yml
index 80b41044..808cccc5 100644
--- a/.github/workflows/stlc-promote.yml
+++ b/.github/workflows/stlc-promote.yml
@@ -1,5 +1,3 @@
-# NOTE(stlc migration): repo names below are set for openlayer-ai. CONFIG_REPO is
-# left as a TODO -- set it to your config repo, then re-seal with `stlc build --push`.
name: Promote SDKs
# Promote staging to production by fast-forwarding production main up to staging,
@@ -16,7 +14,7 @@ jobs:
promote:
# Runner comes from the STLC_RUNNER repo/org variable when set; defaults to GitHub-hosted.
runs-on: ${{ vars.STLC_RUNNER || 'ubuntu-latest' }}
- if: github.repository == 'openlayer-ai/openlayer-java-staging'
+ if: github.repository == 'openlayer-ai/openlayer-java-staging-new'
# Optional gate: add required reviewers to this environment to approve each
# promote. With none it only scopes secrets and adds no gate. Remove if unused.
environment: production
diff --git a/.github/workflows/stlc-sync.yml b/.github/workflows/stlc-sync.yml
index fc0fb8e0..d2d586b3 100644
--- a/.github/workflows/stlc-sync.yml
+++ b/.github/workflows/stlc-sync.yml
@@ -1,5 +1,3 @@
-# NOTE(stlc migration): repo names below are set for openlayer-ai. CONFIG_REPO is
-# left as a TODO -- set it to your config repo, then re-seal with `stlc build --push`.
name: Sync SDK repos
# Keeps the staging and production trunks in sync and the config repo's
@@ -26,7 +24,7 @@ jobs:
# Runner comes from the STLC_RUNNER repo/org variable when set; defaults to GitHub-hosted.
runs-on: ${{ vars.STLC_RUNNER || 'ubuntu-latest' }}
if: >-
- github.repository == 'openlayer-ai/openlayer-java-staging' &&
+ github.repository == 'openlayer-ai/openlayer-java-staging-new' &&
(github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || github.event_name == 'repository_dispatch')
permissions:
contents: write
@@ -107,7 +105,7 @@ jobs:
permissions:
contents: read
env:
- STAGING_REPO: openlayer-ai/openlayer-java-staging
+ STAGING_REPO: openlayer-ai/openlayer-java-staging-new
steps:
- name: Dispatch back-sync to staging
env:
@@ -155,7 +153,7 @@ jobs:
# stlc's own pushes, so the bot's commits can't trigger a re-seal loop.
runs-on: ${{ vars.STLC_RUNNER || 'ubuntu-latest' }}
if: >-
- github.repository == 'openlayer-ai/openlayer-java-staging' &&
+ github.repository == 'openlayer-ai/openlayer-java-staging-new' &&
github.event_name == 'push'
permissions:
contents: read
@@ -163,7 +161,7 @@ jobs:
group: seal-dispatch-${{ github.ref }}
cancel-in-progress: false
env:
- CONFIG_REPO: TODO-set-to-your-config-repo # e.g. openlayer-ai/openlayer-config
+ CONFIG_REPO: openlayer-ai/openlayer-public-api
steps:
- name: Loop-guard and send re-seal dispatch
env:
From 4c46263ca504a15ca4879c049c15f69a43bdfb97 Mon Sep 17 00:00:00 2001
From: Vinicius Mello
Date: Thu, 3 Sep 2026 15:02:36 -0300
Subject: [PATCH 11/16] ci(stlc): route promote/sync workflows to the renamed
staging repos
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The staging repos were renamed openlayer--staging-new → openlayer--staging
(legacy mirrors moved to -staging-old). Update the `github.repository ==` gates and
STAGING_REPO accordingly so promote, back-sync and seal-dispatch keep running.
Co-Authored-By: Claude Fable 5.1
Claude-Session: https://claude.ai/code/session_01XwEaNPPVYspSLwxPo3yquG
---
.github/workflows/stlc-promote.yml | 2 +-
.github/workflows/stlc-sync.yml | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/.github/workflows/stlc-promote.yml b/.github/workflows/stlc-promote.yml
index 808cccc5..0c8f57a5 100644
--- a/.github/workflows/stlc-promote.yml
+++ b/.github/workflows/stlc-promote.yml
@@ -14,7 +14,7 @@ jobs:
promote:
# Runner comes from the STLC_RUNNER repo/org variable when set; defaults to GitHub-hosted.
runs-on: ${{ vars.STLC_RUNNER || 'ubuntu-latest' }}
- if: github.repository == 'openlayer-ai/openlayer-java-staging-new'
+ if: github.repository == 'openlayer-ai/openlayer-java-staging'
# Optional gate: add required reviewers to this environment to approve each
# promote. With none it only scopes secrets and adds no gate. Remove if unused.
environment: production
diff --git a/.github/workflows/stlc-sync.yml b/.github/workflows/stlc-sync.yml
index d2d586b3..751210b1 100644
--- a/.github/workflows/stlc-sync.yml
+++ b/.github/workflows/stlc-sync.yml
@@ -24,7 +24,7 @@ jobs:
# Runner comes from the STLC_RUNNER repo/org variable when set; defaults to GitHub-hosted.
runs-on: ${{ vars.STLC_RUNNER || 'ubuntu-latest' }}
if: >-
- github.repository == 'openlayer-ai/openlayer-java-staging-new' &&
+ github.repository == 'openlayer-ai/openlayer-java-staging' &&
(github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' || github.event_name == 'repository_dispatch')
permissions:
contents: write
@@ -105,7 +105,7 @@ jobs:
permissions:
contents: read
env:
- STAGING_REPO: openlayer-ai/openlayer-java-staging-new
+ STAGING_REPO: openlayer-ai/openlayer-java-staging
steps:
- name: Dispatch back-sync to staging
env:
@@ -153,7 +153,7 @@ jobs:
# stlc's own pushes, so the bot's commits can't trigger a re-seal loop.
runs-on: ${{ vars.STLC_RUNNER || 'ubuntu-latest' }}
if: >-
- github.repository == 'openlayer-ai/openlayer-java-staging-new' &&
+ github.repository == 'openlayer-ai/openlayer-java-staging' &&
github.event_name == 'push'
permissions:
contents: read
From b1d58670595651deeff9addf5a6c2a2c9bdda072 Mon Sep 17 00:00:00 2001
From: stlc-bot
Date: Thu, 3 Sep 2026 22:01:01 +0000
Subject: [PATCH 12/16] Build SDK
Stainless-Generated-From: 39bef380b74dea5e4d728931c000440338a60806
---
scripts/mock | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/mock b/scripts/mock
index 474f5a99..099a4c9c 100755
--- a/scripts/mock
+++ b/scripts/mock
@@ -16,7 +16,7 @@ elif [ -n "$STAINLESS_OPENAPI_SPEC_URL" ]; then
URL="$STAINLESS_OPENAPI_SPEC_URL"
else
# Embedded OpenAPI spec (base64-encoded, gzipped)
- EMBEDDED_SPEC="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"
+ EMBEDDED_SPEC="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"
SPEC_TMPFILE="$(mktemp)"
trap 'rm -f "$SPEC_TMPFILE"' EXIT
echo "$EMBEDDED_SPEC" | base64 --decode | gunzip > "$SPEC_TMPFILE"
From f48936b0b408e13e150eaea39d115d680dd48b4a Mon Sep 17 00:00:00 2001
From: Vinicius Mello
Date: Wed, 9 Sep 2026 12:33:57 -0300
Subject: [PATCH 13/16] ci(stlc): promote via pull request; back-sync
fast-forwards to descendants
Production `main` is protected (PR + review) and should stay that way, so the
promote no longer force-pushes main. It pushes staging's tip to `stlc/promote`
on the production repo and opens/refreshes a PR listing the commits; the PR is
the human review gate before publishing and must be merged with a merge commit.
Back-sync now also fast-forwards when production is a strict descendant of
staging with an identical tree (the merged promote PR), so codegen isn't held
between the promote merge and the release commit.
Co-Authored-By: Claude Fable 5.1
Claude-Session: https://claude.ai/code/session_01WL7jhZTnnSYDo5vECWpXUw
---
.github/workflows/stlc-promote.yml | 42 ++++++++++++++++++++++++------
.github/workflows/stlc-sync.yml | 8 +++++-
2 files changed, 41 insertions(+), 9 deletions(-)
diff --git a/.github/workflows/stlc-promote.yml b/.github/workflows/stlc-promote.yml
index 0c8f57a5..4c65a7e6 100644
--- a/.github/workflows/stlc-promote.yml
+++ b/.github/workflows/stlc-promote.yml
@@ -1,9 +1,12 @@
name: Promote SDKs
-# Promote staging to production by fast-forwarding production main up to staging,
-# preserving SHAs so the trunks stay identical and linear (nothing to heal on the
-# next stlc build). Manual dispatch by design: a maintainer promotes the accumulated
-# batch to cut a release; release-please then opens its version PR on production.
+# Promote staging to production by opening a pull request on the production repo
+# whose head is staging main (pushed to the `stlc/promote` branch). Production `main`
+# stays fully protected; the PR is the human review gate before publishing. It must
+# be merged with a MERGE COMMIT (never squash/rebase) so the trunks keep shared
+# history; back-sync then fast-forwards staging to the merge commit. Manual dispatch
+# by design: a maintainer promotes the accumulated batch to cut a release;
+# release-please then opens its version PR on production.
on:
workflow_dispatch: {}
@@ -47,17 +50,40 @@ jobs:
echo "synced=false" >> "$GITHUB_OUTPUT"
fi
- - name: Promote staging to production (fast-forward)
+ - name: Promote staging to production (pull request)
if: steps.diff.outputs.synced == 'false'
+ env:
+ PROMOTE_BRANCH: stlc/promote
run: |
# Refuse unless production is an ancestor of staging: otherwise the trunks
- # have forked (production advanced without a back-sync) and FF is unsafe.
+ # have forked (production advanced without a back-sync) and the PR would be
+ # a real merge. Back-sync production into staging first.
if ! git merge-base --is-ancestor production/main origin/main; then
echo "::error title=Promote blocked::production/main is not an ancestor of staging main. Back-sync production into staging first."
exit 1
fi
- git push production origin/main:refs/heads/main
- echo "Fast-forwarded production/main to staging/main."
+ # Publish staging's tip as a branch on production and open (or refresh) the
+ # promote PR. `main` is protected on production; the PR is the review gate.
+ git push --force production "origin/main:refs/heads/${PROMOTE_BRANCH}"
+ tip=$(git rev-parse --short origin/main)
+ {
+ echo "Promotes \`${PRODUCTION_REPO}\` \`main\` to the staging trunk (\`${tip}\`)."
+ echo
+ echo "**Merge with a merge commit — do not squash or rebase.** Squashing rewrites the commits and forks the trunks; the next back-sync and promote refuse until repaired by hand."
+ echo
+ echo "After merging, release-please opens the version PR on this repo; merging that one tags and publishes."
+ echo
+ echo "### Commits"
+ git log --format='- %h %s' production/main..origin/main
+ } > /tmp/promote-body.md
+ existing=$(gh pr list -R "$PRODUCTION_REPO" --head "$PROMOTE_BRANCH" --state open --json number --jq '.[0].number // empty')
+ if [ -n "$existing" ]; then
+ gh pr edit "$existing" -R "$PRODUCTION_REPO" --title "Promote staging to production (${tip})" --body-file /tmp/promote-body.md
+ echo "Refreshed promote PR #${existing} on ${PRODUCTION_REPO}."
+ else
+ gh pr create -R "$PRODUCTION_REPO" --base main --head "$PROMOTE_BRANCH" \
+ --title "Promote staging to production (${tip})" --body-file /tmp/promote-body.md
+ fi
- name: Alert on failure
if: failure()
diff --git a/.github/workflows/stlc-sync.yml b/.github/workflows/stlc-sync.yml
index 751210b1..2f363a51 100644
--- a/.github/workflows/stlc-sync.yml
+++ b/.github/workflows/stlc-sync.yml
@@ -61,7 +61,13 @@ jobs:
# If not, staging already has production's content (release-please commits).
MERGED=$(git merge-tree --write-tree origin/main production/main) || MERGED=conflict
STAGING_TREE=$(git rev-parse 'origin/main^{tree}')
- if [ "$MERGED" = "$STAGING_TREE" ]; then
+ if [ "$(git rev-parse origin/main)" != "$(git rev-parse production/main)" ] \
+ && git merge-base --is-ancestor origin/main production/main; then
+ # Production is a strict descendant of staging — e.g. the merged promote PR
+ # (a merge commit with an identical tree) or a release commit. Fast-forward
+ # even when the trees match, so the trunks share history and codegen isn't held.
+ echo "behind=true" >> "$GITHUB_OUTPUT"
+ elif [ "$MERGED" = "$STAGING_TREE" ]; then
echo "Staging already has production's content. Nothing to pull back."
echo "behind=false" >> "$GITHUB_OUTPUT"
else
From 205f1061a29e08b17c77a068eb66c0b92f35b4a8 Mon Sep 17 00:00:00 2001
From: Vinicius Mello
Date: Wed, 9 Sep 2026 21:13:10 -0300
Subject: [PATCH 14/16] ci(stlc): back-sync pushes staging main as the
automation identity
Staging main is getting a pull-request rule whose only bypass is the
automation's repository role. The back-sync job pushed with GITHUB_TOKEN,
which cannot be a bypass actor (GitHub Actions is not an org-owned app), so
push with PRODUCTION_REPO_TOKEN (the service account) instead. Token pushes
also trigger seal-dispatch, so the config repo re-seals immediately after a
back-sync rather than at the next scheduled run.
Co-Authored-By: Claude Fable 5.1
Claude-Session: https://claude.ai/code/session_017oDfpQ4KpmpTzYm2fZ9eaL
---
.github/workflows/stlc-sync.yml | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/.github/workflows/stlc-sync.yml b/.github/workflows/stlc-sync.yml
index 2f363a51..850faf9e 100644
--- a/.github/workflows/stlc-sync.yml
+++ b/.github/workflows/stlc-sync.yml
@@ -76,6 +76,8 @@ jobs:
- name: Sync production to staging (fast-forward)
if: steps.diff.outputs.behind == 'true'
+ env:
+ PUSH_TOKEN: ${{ secrets.PRODUCTION_REPO_TOKEN }}
run: |
# Refuse unless staging is an ancestor of production: otherwise the
# trunks have forked and a fast-forward would be unsafe.
@@ -83,7 +85,17 @@ jobs:
echo "::error title=Back-sync blocked::staging main is not an ancestor of production/main."
exit 1
fi
- git push origin production/main:refs/heads/main
+ # Push as the automation identity (PRODUCTION_REPO_TOKEN), not GITHUB_TOKEN:
+ # staging main requires a pull request for humans and only the automation's
+ # repository role bypasses that rule. A token push (unlike GITHUB_TOKEN) also
+ # triggers seal-dispatch, so the config repo re-seals right away instead of
+ # at the next scheduled sync. Blank the persisted GITHUB_TOKEN header first.
+ if [ -n "${PUSH_TOKEN:-}" ]; then
+ git -c "http.https://github.com/.extraheader=" push \
+ "https://x-access-token:${PUSH_TOKEN}@github.com/${GITHUB_REPOSITORY}.git" production/main:refs/heads/main
+ else
+ git push origin production/main:refs/heads/main
+ fi
echo "Fast-forwarded staging/main to production/main."
- name: Alert on failure
From 2f0277293687b9ee4094cccbda250e1bddd1dec4 Mon Sep 17 00:00:00 2001
From: stlc-bot
Date: Mon, 21 Sep 2026 05:14:49 +0000
Subject: [PATCH 15/16] docs(closes OPEN-9410): expose the governance framework
endpoints
Stainless-Generated-From: 44bcbc25bd2ffab3a47ee5b7834b5c799cfe15b6
---
.../inferencepipelines/InferencePipelineRetrieveResponse.kt | 6 ------
.../inferencepipelines/InferencePipelineUpdateResponse.kt | 6 ------
.../openlayer/api/models/projects/ProjectCreateParams.kt | 6 ------
.../openlayer/api/models/projects/ProjectCreateResponse.kt | 6 ------
.../openlayer/api/models/projects/ProjectListResponse.kt | 6 ------
.../openlayer/api/models/projects/ProjectUpdateResponse.kt | 6 ------
.../inferencepipelines/InferencePipelineCreateParams.kt | 6 ------
.../inferencepipelines/InferencePipelineCreateResponse.kt | 6 ------
.../inferencepipelines/InferencePipelineListResponse.kt | 6 ------
scripts/mock | 2 +-
10 files changed, 1 insertion(+), 55 deletions(-)
diff --git a/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/inferencepipelines/InferencePipelineRetrieveResponse.kt b/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/inferencepipelines/InferencePipelineRetrieveResponse.kt
index 4c9e736e..ff2f6bfc 100644
--- a/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/inferencepipelines/InferencePipelineRetrieveResponse.kt
+++ b/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/inferencepipelines/InferencePipelineRetrieveResponse.kt
@@ -7987,8 +7987,6 @@ private constructor(
@JvmField val API = of("api")
- @JvmField val NULL = of("null")
-
@JvmStatic fun of(value: String) = Source(JsonField.of(value))
}
@@ -7996,7 +7994,6 @@ private constructor(
enum class Known {
WEB,
API,
- NULL,
}
/**
@@ -8011,7 +8008,6 @@ private constructor(
enum class Value {
WEB,
API,
- NULL,
/**
* An enum member indicating that [Source] was instantiated with an unknown value.
*/
@@ -8029,7 +8025,6 @@ private constructor(
when (this) {
WEB -> Value.WEB
API -> Value.API
- NULL -> Value.NULL
else -> Value._UNKNOWN
}
@@ -8046,7 +8041,6 @@ private constructor(
when (this) {
WEB -> Known.WEB
API -> Known.API
- NULL -> Known.NULL
else -> throw OpenlayerInvalidDataException("Unknown Source: $value")
}
diff --git a/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/inferencepipelines/InferencePipelineUpdateResponse.kt b/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/inferencepipelines/InferencePipelineUpdateResponse.kt
index 193ba8a9..3ad90222 100644
--- a/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/inferencepipelines/InferencePipelineUpdateResponse.kt
+++ b/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/inferencepipelines/InferencePipelineUpdateResponse.kt
@@ -7987,8 +7987,6 @@ private constructor(
@JvmField val API = of("api")
- @JvmField val NULL = of("null")
-
@JvmStatic fun of(value: String) = Source(JsonField.of(value))
}
@@ -7996,7 +7994,6 @@ private constructor(
enum class Known {
WEB,
API,
- NULL,
}
/**
@@ -8011,7 +8008,6 @@ private constructor(
enum class Value {
WEB,
API,
- NULL,
/**
* An enum member indicating that [Source] was instantiated with an unknown value.
*/
@@ -8029,7 +8025,6 @@ private constructor(
when (this) {
WEB -> Value.WEB
API -> Value.API
- NULL -> Value.NULL
else -> Value._UNKNOWN
}
@@ -8046,7 +8041,6 @@ private constructor(
when (this) {
WEB -> Known.WEB
API -> Known.API
- NULL -> Known.NULL
else -> throw OpenlayerInvalidDataException("Unknown Source: $value")
}
diff --git a/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/projects/ProjectCreateParams.kt b/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/projects/ProjectCreateParams.kt
index 950cd7f8..afe97d7a 100644
--- a/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/projects/ProjectCreateParams.kt
+++ b/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/projects/ProjectCreateParams.kt
@@ -2080,8 +2080,6 @@ private constructor(
@JvmField val API = of("api")
- @JvmField val NULL = of("null")
-
@JvmStatic fun of(value: String) = Source(JsonField.of(value))
}
@@ -2089,7 +2087,6 @@ private constructor(
enum class Known {
WEB,
API,
- NULL,
}
/**
@@ -2104,7 +2101,6 @@ private constructor(
enum class Value {
WEB,
API,
- NULL,
/** An enum member indicating that [Source] was instantiated with an unknown value. */
_UNKNOWN,
}
@@ -2120,7 +2116,6 @@ private constructor(
when (this) {
WEB -> Value.WEB
API -> Value.API
- NULL -> Value.NULL
else -> Value._UNKNOWN
}
@@ -2137,7 +2132,6 @@ private constructor(
when (this) {
WEB -> Known.WEB
API -> Known.API
- NULL -> Known.NULL
else -> throw OpenlayerInvalidDataException("Unknown Source: $value")
}
diff --git a/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/projects/ProjectCreateResponse.kt b/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/projects/ProjectCreateResponse.kt
index 3ca748e3..6e47cabf 100644
--- a/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/projects/ProjectCreateResponse.kt
+++ b/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/projects/ProjectCreateResponse.kt
@@ -1155,8 +1155,6 @@ private constructor(
@JvmField val API = of("api")
- @JvmField val NULL = of("null")
-
@JvmStatic fun of(value: String) = Source(JsonField.of(value))
}
@@ -1164,7 +1162,6 @@ private constructor(
enum class Known {
WEB,
API,
- NULL,
}
/**
@@ -1179,7 +1176,6 @@ private constructor(
enum class Value {
WEB,
API,
- NULL,
/** An enum member indicating that [Source] was instantiated with an unknown value. */
_UNKNOWN,
}
@@ -1195,7 +1191,6 @@ private constructor(
when (this) {
WEB -> Value.WEB
API -> Value.API
- NULL -> Value.NULL
else -> Value._UNKNOWN
}
@@ -1212,7 +1207,6 @@ private constructor(
when (this) {
WEB -> Known.WEB
API -> Known.API
- NULL -> Known.NULL
else -> throw OpenlayerInvalidDataException("Unknown Source: $value")
}
diff --git a/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/projects/ProjectListResponse.kt b/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/projects/ProjectListResponse.kt
index 6949d350..6a1ed5fa 100644
--- a/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/projects/ProjectListResponse.kt
+++ b/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/projects/ProjectListResponse.kt
@@ -1348,8 +1348,6 @@ private constructor(
@JvmField val API = of("api")
- @JvmField val NULL = of("null")
-
@JvmStatic fun of(value: String) = Source(JsonField.of(value))
}
@@ -1357,7 +1355,6 @@ private constructor(
enum class Known {
WEB,
API,
- NULL,
}
/**
@@ -1372,7 +1369,6 @@ private constructor(
enum class Value {
WEB,
API,
- NULL,
/**
* An enum member indicating that [Source] was instantiated with an unknown value.
*/
@@ -1390,7 +1386,6 @@ private constructor(
when (this) {
WEB -> Value.WEB
API -> Value.API
- NULL -> Value.NULL
else -> Value._UNKNOWN
}
@@ -1407,7 +1402,6 @@ private constructor(
when (this) {
WEB -> Known.WEB
API -> Known.API
- NULL -> Known.NULL
else -> throw OpenlayerInvalidDataException("Unknown Source: $value")
}
diff --git a/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/projects/ProjectUpdateResponse.kt b/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/projects/ProjectUpdateResponse.kt
index 097d8c84..e6d76465 100644
--- a/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/projects/ProjectUpdateResponse.kt
+++ b/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/projects/ProjectUpdateResponse.kt
@@ -1155,8 +1155,6 @@ private constructor(
@JvmField val API = of("api")
- @JvmField val NULL = of("null")
-
@JvmStatic fun of(value: String) = Source(JsonField.of(value))
}
@@ -1164,7 +1162,6 @@ private constructor(
enum class Known {
WEB,
API,
- NULL,
}
/**
@@ -1179,7 +1176,6 @@ private constructor(
enum class Value {
WEB,
API,
- NULL,
/** An enum member indicating that [Source] was instantiated with an unknown value. */
_UNKNOWN,
}
@@ -1195,7 +1191,6 @@ private constructor(
when (this) {
WEB -> Value.WEB
API -> Value.API
- NULL -> Value.NULL
else -> Value._UNKNOWN
}
@@ -1212,7 +1207,6 @@ private constructor(
when (this) {
WEB -> Known.WEB
API -> Known.API
- NULL -> Known.NULL
else -> throw OpenlayerInvalidDataException("Unknown Source: $value")
}
diff --git a/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/projects/inferencepipelines/InferencePipelineCreateParams.kt b/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/projects/inferencepipelines/InferencePipelineCreateParams.kt
index 67e82d3e..159e854b 100644
--- a/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/projects/inferencepipelines/InferencePipelineCreateParams.kt
+++ b/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/projects/inferencepipelines/InferencePipelineCreateParams.kt
@@ -9017,8 +9017,6 @@ private constructor(
@JvmField val API = of("api")
- @JvmField val NULL = of("null")
-
@JvmStatic fun of(value: String) = Source(JsonField.of(value))
}
@@ -9026,7 +9024,6 @@ private constructor(
enum class Known {
WEB,
API,
- NULL,
}
/**
@@ -9041,7 +9038,6 @@ private constructor(
enum class Value {
WEB,
API,
- NULL,
/**
* An enum member indicating that [Source] was instantiated with an unknown value.
*/
@@ -9059,7 +9055,6 @@ private constructor(
when (this) {
WEB -> Value.WEB
API -> Value.API
- NULL -> Value.NULL
else -> Value._UNKNOWN
}
@@ -9076,7 +9071,6 @@ private constructor(
when (this) {
WEB -> Known.WEB
API -> Known.API
- NULL -> Known.NULL
else -> throw OpenlayerInvalidDataException("Unknown Source: $value")
}
diff --git a/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/projects/inferencepipelines/InferencePipelineCreateResponse.kt b/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/projects/inferencepipelines/InferencePipelineCreateResponse.kt
index 142d37f4..f09c2452 100644
--- a/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/projects/inferencepipelines/InferencePipelineCreateResponse.kt
+++ b/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/projects/inferencepipelines/InferencePipelineCreateResponse.kt
@@ -7987,8 +7987,6 @@ private constructor(
@JvmField val API = of("api")
- @JvmField val NULL = of("null")
-
@JvmStatic fun of(value: String) = Source(JsonField.of(value))
}
@@ -7996,7 +7994,6 @@ private constructor(
enum class Known {
WEB,
API,
- NULL,
}
/**
@@ -8011,7 +8008,6 @@ private constructor(
enum class Value {
WEB,
API,
- NULL,
/**
* An enum member indicating that [Source] was instantiated with an unknown value.
*/
@@ -8029,7 +8025,6 @@ private constructor(
when (this) {
WEB -> Value.WEB
API -> Value.API
- NULL -> Value.NULL
else -> Value._UNKNOWN
}
@@ -8046,7 +8041,6 @@ private constructor(
when (this) {
WEB -> Known.WEB
API -> Known.API
- NULL -> Known.NULL
else -> throw OpenlayerInvalidDataException("Unknown Source: $value")
}
diff --git a/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/projects/inferencepipelines/InferencePipelineListResponse.kt b/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/projects/inferencepipelines/InferencePipelineListResponse.kt
index 6464f3ba..efac5577 100644
--- a/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/projects/inferencepipelines/InferencePipelineListResponse.kt
+++ b/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/projects/inferencepipelines/InferencePipelineListResponse.kt
@@ -8345,8 +8345,6 @@ private constructor(
@JvmField val API = of("api")
- @JvmField val NULL = of("null")
-
@JvmStatic fun of(value: String) = Source(JsonField.of(value))
}
@@ -8354,7 +8352,6 @@ private constructor(
enum class Known {
WEB,
API,
- NULL,
}
/**
@@ -8369,7 +8366,6 @@ private constructor(
enum class Value {
WEB,
API,
- NULL,
/**
* An enum member indicating that [Source] was instantiated with an unknown
* value.
@@ -8388,7 +8384,6 @@ private constructor(
when (this) {
WEB -> Value.WEB
API -> Value.API
- NULL -> Value.NULL
else -> Value._UNKNOWN
}
@@ -8405,7 +8400,6 @@ private constructor(
when (this) {
WEB -> Known.WEB
API -> Known.API
- NULL -> Known.NULL
else -> throw OpenlayerInvalidDataException("Unknown Source: $value")
}
diff --git a/scripts/mock b/scripts/mock
index 099a4c9c..4e11791c 100755
--- a/scripts/mock
+++ b/scripts/mock
@@ -16,7 +16,7 @@ elif [ -n "$STAINLESS_OPENAPI_SPEC_URL" ]; then
URL="$STAINLESS_OPENAPI_SPEC_URL"
else
# Embedded OpenAPI spec (base64-encoded, gzipped)
- EMBEDDED_SPEC="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"
+ EMBEDDED_SPEC="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"
SPEC_TMPFILE="$(mktemp)"
trap 'rm -f "$SPEC_TMPFILE"' EXIT
echo "$EMBEDDED_SPEC" | base64 --decode | gunzip > "$SPEC_TMPFILE"
From 518719213a8e40ff931b03d1079f0760ed6689b3 Mon Sep 17 00:00:00 2001
From: stlc-bot
Date: Mon, 21 Sep 2026 16:24:53 +0000
Subject: [PATCH 16/16] feat(governance): add the governance write endpoints
and generate governance SDK methods
Stainless-Generated-From: 0a6e7353594165268369b587f1ece87ddae1ce62
---
.stats.yml | 2 +-
.../openlayer/api/client/OpenlayerClient.kt | 10 +
.../api/client/OpenlayerClientAsync.kt | 10 +
.../api/client/OpenlayerClientAsyncImpl.kt | 28 +
.../api/client/OpenlayerClientImpl.kt | 28 +
.../BackgroundTaskRetrieveParams.kt | 201 +
.../BackgroundTaskRetrieveResponse.kt | 458 ++
.../frameworks/FrameworkCreateParams.kt | 1382 +++++
.../frameworks/FrameworkCreateResponse.kt | 2923 ++++++++++
.../frameworks/FrameworkExportParams.kt | 445 ++
.../frameworks/FrameworkExportResponse.kt | 241 +
.../frameworks/FrameworkListParams.kt | 795 +++
.../FrameworkListProjectRuleStatsParams.kt | 490 ++
.../FrameworkListProjectRuleStatsResponse.kt | 2094 +++++++
.../frameworks/FrameworkListProjectsParams.kt | 250 +
.../FrameworkListProjectsResponse.kt | 2319 ++++++++
.../frameworks/FrameworkListResponse.kt | 3174 ++++++++++
.../frameworks/FrameworkListRulesParams.kt | 249 +
.../frameworks/FrameworkListRulesResponse.kt | 5145 +++++++++++++++++
.../frameworks/FrameworkRetrieveParams.kt | 194 +
.../frameworks/FrameworkRetrieveResponse.kt | 2923 ++++++++++
.../frameworks/FrameworkUpdateParams.kt | 2056 +++++++
.../frameworks/FrameworkUpdateResponse.kt | 2923 ++++++++++
.../documents/DocumentListParams.kt | 249 +
.../documents/DocumentListResponse.kt | 4383 ++++++++++++++
.../documents/DocumentRetrieveParams.kt | 222 +
.../documents/DocumentRetrieveResponse.kt | 4106 +++++++++++++
.../sections/SectionListRulesParams.kt | 537 ++
.../sections/SectionListRulesResponse.kt | 5145 +++++++++++++++++
.../subsections/SubsectionListRulesParams.kt | 507 ++
.../SubsectionListRulesResponse.kt | 5145 +++++++++++++++++
.../RuleResultCreateEvidenceParams.kt | 725 +++
.../RuleResultCreateEvidenceResponse.kt | 530 ++
.../RuleResultListEvidenceParams.kt | 250 +
.../RuleResultListEvidenceResponse.kt | 724 +++
.../ruleresults/RuleResultListParams.kt | 868 +++
.../ruleresults/RuleResultListResponse.kt | 2027 +++++++
.../ruleresults/RuleResultRetrieveParams.kt | 200 +
.../ruleresults/RuleResultRetrieveResponse.kt | 1809 ++++++
.../ruleresults/RuleResultUpdateParams.kt | 1490 +++++
.../ruleresults/RuleResultUpdateResponse.kt | 1809 ++++++
.../governance/rules/RuleCreateParams.kt | 1870 ++++++
.../governance/rules/RuleCreateResponse.kt | 4821 +++++++++++++++
.../governance/rules/RuleDeleteParams.kt | 235 +
.../models/governance/rules/RuleListParams.kt | 1316 +++++
.../governance/rules/RuleListResponse.kt | 5145 +++++++++++++++++
.../governance/rules/RuleRetrieveParams.kt | 189 +
.../governance/rules/RuleRetrieveResponse.kt | 4821 +++++++++++++++
.../governance/rules/RuleUpdateParams.kt | 885 +++
.../governance/rules/RuleUpdateResponse.kt | 4821 +++++++++++++++
.../rulestats/RuleStatRetrieveParams.kt | 235 +
.../rulestats/RuleStatRetrieveResponse.kt | 3874 +++++++++++++
.../governance/ruletags/RuleTagListParams.kt | 248 +
.../ruletags/RuleTagListResponse.kt | 675 +++
.../PresignedUrlRetrieveParams.kt | 212 +
.../PresignedUrlRetrieveResponse.kt | 181 +
.../async/BackgroundTaskServiceAsync.kt | 128 +
.../async/BackgroundTaskServiceAsyncImpl.kt | 91 +
.../services/async/GovernanceServiceAsync.kt | 62 +
.../async/GovernanceServiceAsyncImpl.kt | 94 +
.../async/governance/FrameworkServiceAsync.kt | 756 +++
.../governance/FrameworkServiceAsyncImpl.kt | 425 ++
.../governance/RuleResultServiceAsync.kt | 483 ++
.../governance/RuleResultServiceAsyncImpl.kt | 260 +
.../async/governance/RuleServiceAsync.kt | 430 ++
.../async/governance/RuleServiceAsyncImpl.kt | 254 +
.../async/governance/RuleStatServiceAsync.kt | 126 +
.../governance/RuleStatServiceAsyncImpl.kt | 89 +
.../async/governance/RuleTagServiceAsync.kt | 123 +
.../governance/RuleTagServiceAsyncImpl.kt | 89 +
.../frameworks/DocumentServiceAsync.kt | 186 +
.../frameworks/DocumentServiceAsyncImpl.kt | 136 +
.../frameworks/SectionServiceAsync.kt | 102 +
.../frameworks/SectionServiceAsyncImpl.kt | 95 +
.../frameworks/SubsectionServiceAsync.kt | 104 +
.../frameworks/SubsectionServiceAsyncImpl.kt | 95 +
.../async/storage/PresignedUrlServiceAsync.kt | 38 +
.../storage/PresignedUrlServiceAsyncImpl.kt | 39 +
.../blocking/BackgroundTaskService.kt | 125 +
.../blocking/BackgroundTaskServiceImpl.kt | 85 +
.../services/blocking/GovernanceService.kt | 59 +
.../blocking/GovernanceServiceImpl.kt | 90 +
.../blocking/governance/FrameworkService.kt | 748 +++
.../governance/FrameworkServiceImpl.kt | 398 ++
.../blocking/governance/RuleResultService.kt | 483 ++
.../governance/RuleResultServiceImpl.kt | 244 +
.../blocking/governance/RuleService.kt | 417 ++
.../blocking/governance/RuleServiceImpl.kt | 232 +
.../blocking/governance/RuleStatService.kt | 120 +
.../governance/RuleStatServiceImpl.kt | 85 +
.../blocking/governance/RuleTagService.kt | 117 +
.../blocking/governance/RuleTagServiceImpl.kt | 85 +
.../governance/frameworks/DocumentService.kt | 180 +
.../frameworks/DocumentServiceImpl.kt | 129 +
.../governance/frameworks/SectionService.kt | 97 +
.../frameworks/SectionServiceImpl.kt | 91 +
.../frameworks/SubsectionService.kt | 102 +
.../frameworks/SubsectionServiceImpl.kt | 91 +
.../blocking/storage/PresignedUrlService.kt | 38 +
.../storage/PresignedUrlServiceImpl.kt | 36 +
.../BackgroundTaskRetrieveParamsTest.kt | 28 +
.../BackgroundTaskRetrieveResponseTest.kt | 103 +
.../frameworks/FrameworkCreateParamsTest.kt | 110 +
.../frameworks/FrameworkCreateResponseTest.kt | 227 +
.../frameworks/FrameworkExportParamsTest.kt | 52 +
.../frameworks/FrameworkExportResponseTest.kt | 43 +
.../frameworks/FrameworkListParamsTest.kt | 90 +
...FrameworkListProjectRuleStatsParamsTest.kt | 69 +
...ameworkListProjectRuleStatsResponseTest.kt | 172 +
.../FrameworkListProjectsParamsTest.kt | 58 +
.../FrameworkListProjectsResponseTest.kt | 173 +
.../frameworks/FrameworkListResponseTest.kt | 235 +
.../FrameworkListRulesParamsTest.kt | 58 +
.../FrameworkListRulesResponseTest.kt | 333 ++
.../frameworks/FrameworkRetrieveParamsTest.kt | 28 +
.../FrameworkRetrieveResponseTest.kt | 227 +
.../frameworks/FrameworkUpdateParamsTest.kt | 144 +
.../frameworks/FrameworkUpdateResponseTest.kt | 227 +
.../documents/DocumentListParamsTest.kt | 54 +
.../documents/DocumentListResponseTest.kt | 361 ++
.../documents/DocumentRetrieveParamsTest.kt | 31 +
.../documents/DocumentRetrieveResponseTest.kt | 312 +
.../sections/SectionListRulesParamsTest.kt | 80 +
.../sections/SectionListRulesResponseTest.kt | 330 ++
.../SubsectionListRulesParamsTest.kt | 77 +
.../SubsectionListRulesResponseTest.kt | 333 ++
.../RuleResultCreateEvidenceParamsTest.kt | 64 +
.../RuleResultCreateEvidenceResponseTest.kt | 70 +
.../RuleResultListEvidenceParamsTest.kt | 58 +
.../RuleResultListEvidenceResponseTest.kt | 77 +
.../ruleresults/RuleResultListParamsTest.kt | 90 +
.../ruleresults/RuleResultListResponseTest.kt | 130 +
.../RuleResultRetrieveParamsTest.kt | 28 +
.../RuleResultRetrieveResponseTest.kt | 132 +
.../ruleresults/RuleResultUpdateParamsTest.kt | 97 +
.../RuleResultUpdateResponseTest.kt | 131 +
.../governance/rules/RuleCreateParamsTest.kt | 109 +
.../rules/RuleCreateResponseTest.kt | 287 +
.../governance/rules/RuleDeleteParamsTest.kt | 24 +
.../governance/rules/RuleListParamsTest.kt | 104 +
.../governance/rules/RuleListResponseTest.kt | 312 +
.../rules/RuleRetrieveParamsTest.kt | 24 +
.../rules/RuleRetrieveResponseTest.kt | 288 +
.../governance/rules/RuleUpdateParamsTest.kt | 66 +
.../rules/RuleUpdateResponseTest.kt | 287 +
.../rulestats/RuleStatRetrieveParamsTest.kt | 63 +
.../rulestats/RuleStatRetrieveResponseTest.kt | 300 +
.../ruletags/RuleTagListParamsTest.kt | 54 +
.../ruletags/RuleTagListResponseTest.kt | 73 +
.../PresignedUrlRetrieveParamsTest.kt | 25 +
.../PresignedUrlRetrieveResponseTest.kt | 32 +
.../async/BackgroundTaskServiceAsyncTest.kt | 28 +
.../governance/FrameworkServiceAsyncTest.kt | 245 +
.../governance/RuleResultServiceAsyncTest.kt | 145 +
.../async/governance/RuleServiceAsyncTest.kt | 143 +
.../governance/RuleStatServiceAsyncTest.kt | 35 +
.../governance/RuleTagServiceAsyncTest.kt | 35 +
.../frameworks/DocumentServiceAsyncTest.kt | 57 +
.../frameworks/SectionServiceAsyncTest.kt | 40 +
.../frameworks/SubsectionServiceAsyncTest.kt | 39 +
.../storage/PresignedUrlServiceAsyncTest.kt | 19 +
.../blocking/BackgroundTaskServiceTest.kt | 26 +
.../governance/FrameworkServiceTest.kt | 237 +
.../governance/RuleResultServiceTest.kt | 139 +
.../blocking/governance/RuleServiceTest.kt | 137 +
.../governance/RuleStatServiceTest.kt | 34 +
.../blocking/governance/RuleTagServiceTest.kt | 34 +
.../frameworks/DocumentServiceTest.kt | 55 +
.../frameworks/SectionServiceTest.kt | 39 +
.../frameworks/SubsectionServiceTest.kt | 38 +
.../storage/PresignedUrlServiceTest.kt | 18 +
.../api/proguard/ProGuardCompatibilityTest.kt | 2 +
scripts/mock | 2 +-
173 files changed, 105276 insertions(+), 2 deletions(-)
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/backgroundtasks/BackgroundTaskRetrieveParams.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/backgroundtasks/BackgroundTaskRetrieveResponse.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/frameworks/FrameworkCreateParams.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/frameworks/FrameworkCreateResponse.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/frameworks/FrameworkExportParams.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/frameworks/FrameworkExportResponse.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/frameworks/FrameworkListParams.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/frameworks/FrameworkListProjectRuleStatsParams.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/frameworks/FrameworkListProjectRuleStatsResponse.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/frameworks/FrameworkListProjectsParams.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/frameworks/FrameworkListProjectsResponse.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/frameworks/FrameworkListResponse.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/frameworks/FrameworkListRulesParams.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/frameworks/FrameworkListRulesResponse.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/frameworks/FrameworkRetrieveParams.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/frameworks/FrameworkRetrieveResponse.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/frameworks/FrameworkUpdateParams.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/frameworks/FrameworkUpdateResponse.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/frameworks/documents/DocumentListParams.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/frameworks/documents/DocumentListResponse.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/frameworks/documents/DocumentRetrieveParams.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/frameworks/documents/DocumentRetrieveResponse.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/frameworks/sections/SectionListRulesParams.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/frameworks/sections/SectionListRulesResponse.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/frameworks/subsections/SubsectionListRulesParams.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/frameworks/subsections/SubsectionListRulesResponse.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/ruleresults/RuleResultCreateEvidenceParams.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/ruleresults/RuleResultCreateEvidenceResponse.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/ruleresults/RuleResultListEvidenceParams.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/ruleresults/RuleResultListEvidenceResponse.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/ruleresults/RuleResultListParams.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/ruleresults/RuleResultListResponse.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/ruleresults/RuleResultRetrieveParams.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/ruleresults/RuleResultRetrieveResponse.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/ruleresults/RuleResultUpdateParams.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/ruleresults/RuleResultUpdateResponse.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/rules/RuleCreateParams.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/rules/RuleCreateResponse.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/rules/RuleDeleteParams.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/rules/RuleListParams.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/rules/RuleListResponse.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/rules/RuleRetrieveParams.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/rules/RuleRetrieveResponse.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/rules/RuleUpdateParams.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/rules/RuleUpdateResponse.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/rulestats/RuleStatRetrieveParams.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/rulestats/RuleStatRetrieveResponse.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/ruletags/RuleTagListParams.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/ruletags/RuleTagListResponse.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/storage/presignedurl/PresignedUrlRetrieveParams.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/models/storage/presignedurl/PresignedUrlRetrieveResponse.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/services/async/BackgroundTaskServiceAsync.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/services/async/BackgroundTaskServiceAsyncImpl.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/services/async/GovernanceServiceAsync.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/services/async/GovernanceServiceAsyncImpl.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/services/async/governance/FrameworkServiceAsync.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/services/async/governance/FrameworkServiceAsyncImpl.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/services/async/governance/RuleResultServiceAsync.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/services/async/governance/RuleResultServiceAsyncImpl.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/services/async/governance/RuleServiceAsync.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/services/async/governance/RuleServiceAsyncImpl.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/services/async/governance/RuleStatServiceAsync.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/services/async/governance/RuleStatServiceAsyncImpl.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/services/async/governance/RuleTagServiceAsync.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/services/async/governance/RuleTagServiceAsyncImpl.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/services/async/governance/frameworks/DocumentServiceAsync.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/services/async/governance/frameworks/DocumentServiceAsyncImpl.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/services/async/governance/frameworks/SectionServiceAsync.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/services/async/governance/frameworks/SectionServiceAsyncImpl.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/services/async/governance/frameworks/SubsectionServiceAsync.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/services/async/governance/frameworks/SubsectionServiceAsyncImpl.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/services/blocking/BackgroundTaskService.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/services/blocking/BackgroundTaskServiceImpl.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/services/blocking/GovernanceService.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/services/blocking/GovernanceServiceImpl.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/services/blocking/governance/FrameworkService.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/services/blocking/governance/FrameworkServiceImpl.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/services/blocking/governance/RuleResultService.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/services/blocking/governance/RuleResultServiceImpl.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/services/blocking/governance/RuleService.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/services/blocking/governance/RuleServiceImpl.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/services/blocking/governance/RuleStatService.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/services/blocking/governance/RuleStatServiceImpl.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/services/blocking/governance/RuleTagService.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/services/blocking/governance/RuleTagServiceImpl.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/services/blocking/governance/frameworks/DocumentService.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/services/blocking/governance/frameworks/DocumentServiceImpl.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/services/blocking/governance/frameworks/SectionService.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/services/blocking/governance/frameworks/SectionServiceImpl.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/services/blocking/governance/frameworks/SubsectionService.kt
create mode 100644 openlayer-java-core/src/main/kotlin/com/openlayer/api/services/blocking/governance/frameworks/SubsectionServiceImpl.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/backgroundtasks/BackgroundTaskRetrieveParamsTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/backgroundtasks/BackgroundTaskRetrieveResponseTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/frameworks/FrameworkCreateParamsTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/frameworks/FrameworkCreateResponseTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/frameworks/FrameworkExportParamsTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/frameworks/FrameworkExportResponseTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/frameworks/FrameworkListParamsTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/frameworks/FrameworkListProjectRuleStatsParamsTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/frameworks/FrameworkListProjectRuleStatsResponseTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/frameworks/FrameworkListProjectsParamsTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/frameworks/FrameworkListProjectsResponseTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/frameworks/FrameworkListResponseTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/frameworks/FrameworkListRulesParamsTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/frameworks/FrameworkListRulesResponseTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/frameworks/FrameworkRetrieveParamsTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/frameworks/FrameworkRetrieveResponseTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/frameworks/FrameworkUpdateParamsTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/frameworks/FrameworkUpdateResponseTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/frameworks/documents/DocumentListParamsTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/frameworks/documents/DocumentListResponseTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/frameworks/documents/DocumentRetrieveParamsTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/frameworks/documents/DocumentRetrieveResponseTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/frameworks/sections/SectionListRulesParamsTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/frameworks/sections/SectionListRulesResponseTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/frameworks/subsections/SubsectionListRulesParamsTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/frameworks/subsections/SubsectionListRulesResponseTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/ruleresults/RuleResultCreateEvidenceParamsTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/ruleresults/RuleResultCreateEvidenceResponseTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/ruleresults/RuleResultListEvidenceParamsTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/ruleresults/RuleResultListEvidenceResponseTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/ruleresults/RuleResultListParamsTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/ruleresults/RuleResultListResponseTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/ruleresults/RuleResultRetrieveParamsTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/ruleresults/RuleResultRetrieveResponseTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/ruleresults/RuleResultUpdateParamsTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/ruleresults/RuleResultUpdateResponseTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/rules/RuleCreateParamsTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/rules/RuleCreateResponseTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/rules/RuleDeleteParamsTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/rules/RuleListParamsTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/rules/RuleListResponseTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/rules/RuleRetrieveParamsTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/rules/RuleRetrieveResponseTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/rules/RuleUpdateParamsTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/rules/RuleUpdateResponseTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/rulestats/RuleStatRetrieveParamsTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/rulestats/RuleStatRetrieveResponseTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/ruletags/RuleTagListParamsTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/governance/ruletags/RuleTagListResponseTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/storage/presignedurl/PresignedUrlRetrieveParamsTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/models/storage/presignedurl/PresignedUrlRetrieveResponseTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/services/async/BackgroundTaskServiceAsyncTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/services/async/governance/FrameworkServiceAsyncTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/services/async/governance/RuleResultServiceAsyncTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/services/async/governance/RuleServiceAsyncTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/services/async/governance/RuleStatServiceAsyncTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/services/async/governance/RuleTagServiceAsyncTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/services/async/governance/frameworks/DocumentServiceAsyncTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/services/async/governance/frameworks/SectionServiceAsyncTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/services/async/governance/frameworks/SubsectionServiceAsyncTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/services/blocking/BackgroundTaskServiceTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/services/blocking/governance/FrameworkServiceTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/services/blocking/governance/RuleResultServiceTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/services/blocking/governance/RuleServiceTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/services/blocking/governance/RuleStatServiceTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/services/blocking/governance/RuleTagServiceTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/services/blocking/governance/frameworks/DocumentServiceTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/services/blocking/governance/frameworks/SectionServiceTest.kt
create mode 100644 openlayer-java-core/src/test/kotlin/com/openlayer/api/services/blocking/governance/frameworks/SubsectionServiceTest.kt
diff --git a/.stats.yml b/.stats.yml
index e8ba8c9f..b4620cc9 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1 +1 @@
-configured_endpoints: 32
+configured_endpoints: 58
diff --git a/openlayer-java-core/src/main/kotlin/com/openlayer/api/client/OpenlayerClient.kt b/openlayer-java-core/src/main/kotlin/com/openlayer/api/client/OpenlayerClient.kt
index 61c86d06..297c90db 100644
--- a/openlayer-java-core/src/main/kotlin/com/openlayer/api/client/OpenlayerClient.kt
+++ b/openlayer-java-core/src/main/kotlin/com/openlayer/api/client/OpenlayerClient.kt
@@ -3,7 +3,9 @@
package com.openlayer.api.client
import com.openlayer.api.core.ClientOptions
+import com.openlayer.api.services.blocking.BackgroundTaskService
import com.openlayer.api.services.blocking.CommitService
+import com.openlayer.api.services.blocking.GovernanceService
import com.openlayer.api.services.blocking.InferencePipelineService
import com.openlayer.api.services.blocking.ProjectService
import com.openlayer.api.services.blocking.StorageService
@@ -59,6 +61,10 @@ interface OpenlayerClient {
fun tests(): TestService
+ fun backgroundTasks(): BackgroundTaskService
+
+ fun governance(): GovernanceService
+
/**
* Closes this client, relinquishing any underlying resources.
*
@@ -93,5 +99,9 @@ interface OpenlayerClient {
fun storage(): StorageService.WithRawResponse
fun tests(): TestService.WithRawResponse
+
+ fun backgroundTasks(): BackgroundTaskService.WithRawResponse
+
+ fun governance(): GovernanceService.WithRawResponse
}
}
diff --git a/openlayer-java-core/src/main/kotlin/com/openlayer/api/client/OpenlayerClientAsync.kt b/openlayer-java-core/src/main/kotlin/com/openlayer/api/client/OpenlayerClientAsync.kt
index 960d3f89..69147691 100644
--- a/openlayer-java-core/src/main/kotlin/com/openlayer/api/client/OpenlayerClientAsync.kt
+++ b/openlayer-java-core/src/main/kotlin/com/openlayer/api/client/OpenlayerClientAsync.kt
@@ -3,7 +3,9 @@
package com.openlayer.api.client
import com.openlayer.api.core.ClientOptions
+import com.openlayer.api.services.async.BackgroundTaskServiceAsync
import com.openlayer.api.services.async.CommitServiceAsync
+import com.openlayer.api.services.async.GovernanceServiceAsync
import com.openlayer.api.services.async.InferencePipelineServiceAsync
import com.openlayer.api.services.async.ProjectServiceAsync
import com.openlayer.api.services.async.StorageServiceAsync
@@ -59,6 +61,10 @@ interface OpenlayerClientAsync {
fun tests(): TestServiceAsync
+ fun backgroundTasks(): BackgroundTaskServiceAsync
+
+ fun governance(): GovernanceServiceAsync
+
/**
* Closes this client, relinquishing any underlying resources.
*
@@ -97,5 +103,9 @@ interface OpenlayerClientAsync {
fun storage(): StorageServiceAsync.WithRawResponse
fun tests(): TestServiceAsync.WithRawResponse
+
+ fun backgroundTasks(): BackgroundTaskServiceAsync.WithRawResponse
+
+ fun governance(): GovernanceServiceAsync.WithRawResponse
}
}
diff --git a/openlayer-java-core/src/main/kotlin/com/openlayer/api/client/OpenlayerClientAsyncImpl.kt b/openlayer-java-core/src/main/kotlin/com/openlayer/api/client/OpenlayerClientAsyncImpl.kt
index 6c590e95..b831fefd 100644
--- a/openlayer-java-core/src/main/kotlin/com/openlayer/api/client/OpenlayerClientAsyncImpl.kt
+++ b/openlayer-java-core/src/main/kotlin/com/openlayer/api/client/OpenlayerClientAsyncImpl.kt
@@ -4,8 +4,12 @@ package com.openlayer.api.client
import com.openlayer.api.core.ClientOptions
import com.openlayer.api.core.getPackageVersion
+import com.openlayer.api.services.async.BackgroundTaskServiceAsync
+import com.openlayer.api.services.async.BackgroundTaskServiceAsyncImpl
import com.openlayer.api.services.async.CommitServiceAsync
import com.openlayer.api.services.async.CommitServiceAsyncImpl
+import com.openlayer.api.services.async.GovernanceServiceAsync
+import com.openlayer.api.services.async.GovernanceServiceAsyncImpl
import com.openlayer.api.services.async.InferencePipelineServiceAsync
import com.openlayer.api.services.async.InferencePipelineServiceAsyncImpl
import com.openlayer.api.services.async.ProjectServiceAsync
@@ -57,6 +61,14 @@ class OpenlayerClientAsyncImpl(private val clientOptions: ClientOptions) : Openl
private val tests: TestServiceAsync by lazy { TestServiceAsyncImpl(clientOptionsWithUserAgent) }
+ private val backgroundTasks: BackgroundTaskServiceAsync by lazy {
+ BackgroundTaskServiceAsyncImpl(clientOptionsWithUserAgent)
+ }
+
+ private val governance: GovernanceServiceAsync by lazy {
+ GovernanceServiceAsyncImpl(clientOptionsWithUserAgent)
+ }
+
override fun sync(): OpenlayerClient = sync
override fun withRawResponse(): OpenlayerClientAsync.WithRawResponse = withRawResponse
@@ -76,6 +88,10 @@ class OpenlayerClientAsyncImpl(private val clientOptions: ClientOptions) : Openl
override fun tests(): TestServiceAsync = tests
+ override fun backgroundTasks(): BackgroundTaskServiceAsync = backgroundTasks
+
+ override fun governance(): GovernanceServiceAsync = governance
+
override fun close() = clientOptions.close()
class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) :
@@ -105,6 +121,14 @@ class OpenlayerClientAsyncImpl(private val clientOptions: ClientOptions) : Openl
TestServiceAsyncImpl.WithRawResponseImpl(clientOptions)
}
+ private val backgroundTasks: BackgroundTaskServiceAsync.WithRawResponse by lazy {
+ BackgroundTaskServiceAsyncImpl.WithRawResponseImpl(clientOptions)
+ }
+
+ private val governance: GovernanceServiceAsync.WithRawResponse by lazy {
+ GovernanceServiceAsyncImpl.WithRawResponseImpl(clientOptions)
+ }
+
override fun withOptions(
modifier: Consumer
): OpenlayerClientAsync.WithRawResponse =
@@ -124,5 +148,9 @@ class OpenlayerClientAsyncImpl(private val clientOptions: ClientOptions) : Openl
override fun storage(): StorageServiceAsync.WithRawResponse = storage
override fun tests(): TestServiceAsync.WithRawResponse = tests
+
+ override fun backgroundTasks(): BackgroundTaskServiceAsync.WithRawResponse = backgroundTasks
+
+ override fun governance(): GovernanceServiceAsync.WithRawResponse = governance
}
}
diff --git a/openlayer-java-core/src/main/kotlin/com/openlayer/api/client/OpenlayerClientImpl.kt b/openlayer-java-core/src/main/kotlin/com/openlayer/api/client/OpenlayerClientImpl.kt
index b82d4996..fcfbd34f 100644
--- a/openlayer-java-core/src/main/kotlin/com/openlayer/api/client/OpenlayerClientImpl.kt
+++ b/openlayer-java-core/src/main/kotlin/com/openlayer/api/client/OpenlayerClientImpl.kt
@@ -4,8 +4,12 @@ package com.openlayer.api.client
import com.openlayer.api.core.ClientOptions
import com.openlayer.api.core.getPackageVersion
+import com.openlayer.api.services.blocking.BackgroundTaskService
+import com.openlayer.api.services.blocking.BackgroundTaskServiceImpl
import com.openlayer.api.services.blocking.CommitService
import com.openlayer.api.services.blocking.CommitServiceImpl
+import com.openlayer.api.services.blocking.GovernanceService
+import com.openlayer.api.services.blocking.GovernanceServiceImpl
import com.openlayer.api.services.blocking.InferencePipelineService
import com.openlayer.api.services.blocking.InferencePipelineServiceImpl
import com.openlayer.api.services.blocking.ProjectService
@@ -51,6 +55,14 @@ class OpenlayerClientImpl(private val clientOptions: ClientOptions) : OpenlayerC
private val tests: TestService by lazy { TestServiceImpl(clientOptionsWithUserAgent) }
+ private val backgroundTasks: BackgroundTaskService by lazy {
+ BackgroundTaskServiceImpl(clientOptionsWithUserAgent)
+ }
+
+ private val governance: GovernanceService by lazy {
+ GovernanceServiceImpl(clientOptionsWithUserAgent)
+ }
+
override fun async(): OpenlayerClientAsync = async
override fun withRawResponse(): OpenlayerClient.WithRawResponse = withRawResponse
@@ -70,6 +82,10 @@ class OpenlayerClientImpl(private val clientOptions: ClientOptions) : OpenlayerC
override fun tests(): TestService = tests
+ override fun backgroundTasks(): BackgroundTaskService = backgroundTasks
+
+ override fun governance(): GovernanceService = governance
+
override fun close() = clientOptions.close()
class WithRawResponseImpl internal constructor(private val clientOptions: ClientOptions) :
@@ -99,6 +115,14 @@ class OpenlayerClientImpl(private val clientOptions: ClientOptions) : OpenlayerC
TestServiceImpl.WithRawResponseImpl(clientOptions)
}
+ private val backgroundTasks: BackgroundTaskService.WithRawResponse by lazy {
+ BackgroundTaskServiceImpl.WithRawResponseImpl(clientOptions)
+ }
+
+ private val governance: GovernanceService.WithRawResponse by lazy {
+ GovernanceServiceImpl.WithRawResponseImpl(clientOptions)
+ }
+
override fun withOptions(
modifier: Consumer
): OpenlayerClient.WithRawResponse =
@@ -118,5 +142,9 @@ class OpenlayerClientImpl(private val clientOptions: ClientOptions) : OpenlayerC
override fun storage(): StorageService.WithRawResponse = storage
override fun tests(): TestService.WithRawResponse = tests
+
+ override fun backgroundTasks(): BackgroundTaskService.WithRawResponse = backgroundTasks
+
+ override fun governance(): GovernanceService.WithRawResponse = governance
}
}
diff --git a/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/backgroundtasks/BackgroundTaskRetrieveParams.kt b/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/backgroundtasks/BackgroundTaskRetrieveParams.kt
new file mode 100644
index 00000000..314e775a
--- /dev/null
+++ b/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/backgroundtasks/BackgroundTaskRetrieveParams.kt
@@ -0,0 +1,201 @@
+// File generated from our OpenAPI spec by Stainless.
+
+package com.openlayer.api.models.backgroundtasks
+
+import com.openlayer.api.core.Params
+import com.openlayer.api.core.http.Headers
+import com.openlayer.api.core.http.QueryParams
+import java.util.Objects
+import java.util.Optional
+import kotlin.jvm.optionals.getOrNull
+
+/**
+ * Retrieve a background task's status, progress and results.
+ *
+ * Endpoints that cannot answer within one request queue a task and hand back its id -- for example
+ * `POST /frameworks/{frameworkId}/export`. Poll this endpoint until `complete` is `true`, then read
+ * what the task produced from `outputs`.
+ */
+class BackgroundTaskRetrieveParams
+private constructor(
+ private val taskId: String?,
+ private val additionalHeaders: Headers,
+ private val additionalQueryParams: QueryParams,
+) : Params {
+
+ fun taskId(): Optional = Optional.ofNullable(taskId)
+
+ /** Additional headers to send with the request. */
+ fun _additionalHeaders(): Headers = additionalHeaders
+
+ /** Additional query param to send with the request. */
+ fun _additionalQueryParams(): QueryParams = additionalQueryParams
+
+ fun toBuilder() = Builder().from(this)
+
+ companion object {
+
+ @JvmStatic fun none(): BackgroundTaskRetrieveParams = builder().build()
+
+ /**
+ * Returns a mutable builder for constructing an instance of [BackgroundTaskRetrieveParams].
+ */
+ @JvmStatic fun builder() = Builder()
+ }
+
+ /** A builder for [BackgroundTaskRetrieveParams]. */
+ class Builder internal constructor() {
+
+ private var taskId: String? = null
+ private var additionalHeaders: Headers.Builder = Headers.builder()
+ private var additionalQueryParams: QueryParams.Builder = QueryParams.builder()
+
+ @JvmSynthetic
+ internal fun from(backgroundTaskRetrieveParams: BackgroundTaskRetrieveParams) = apply {
+ taskId = backgroundTaskRetrieveParams.taskId
+ additionalHeaders = backgroundTaskRetrieveParams.additionalHeaders.toBuilder()
+ additionalQueryParams = backgroundTaskRetrieveParams.additionalQueryParams.toBuilder()
+ }
+
+ fun taskId(taskId: String?) = apply { this.taskId = taskId }
+
+ /** Alias for calling [Builder.taskId] with `taskId.orElse(null)`. */
+ fun taskId(taskId: Optional) = taskId(taskId.getOrNull())
+
+ fun additionalHeaders(additionalHeaders: Headers) = apply {
+ this.additionalHeaders.clear()
+ putAllAdditionalHeaders(additionalHeaders)
+ }
+
+ fun additionalHeaders(additionalHeaders: Map>) = apply {
+ this.additionalHeaders.clear()
+ putAllAdditionalHeaders(additionalHeaders)
+ }
+
+ fun putAdditionalHeader(name: String, value: String) = apply {
+ additionalHeaders.put(name, value)
+ }
+
+ fun putAdditionalHeaders(name: String, values: Iterable) = apply {
+ additionalHeaders.put(name, values)
+ }
+
+ fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply {
+ this.additionalHeaders.putAll(additionalHeaders)
+ }
+
+ fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply {
+ this.additionalHeaders.putAll(additionalHeaders)
+ }
+
+ fun replaceAdditionalHeaders(name: String, value: String) = apply {
+ additionalHeaders.replace(name, value)
+ }
+
+ fun replaceAdditionalHeaders(name: String, values: Iterable) = apply {
+ additionalHeaders.replace(name, values)
+ }
+
+ fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply {
+ this.additionalHeaders.replaceAll(additionalHeaders)
+ }
+
+ fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply {
+ this.additionalHeaders.replaceAll(additionalHeaders)
+ }
+
+ fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) }
+
+ fun removeAllAdditionalHeaders(names: Set) = apply {
+ additionalHeaders.removeAll(names)
+ }
+
+ fun additionalQueryParams(additionalQueryParams: QueryParams) = apply {
+ this.additionalQueryParams.clear()
+ putAllAdditionalQueryParams(additionalQueryParams)
+ }
+
+ fun additionalQueryParams(additionalQueryParams: Map>) = apply {
+ this.additionalQueryParams.clear()
+ putAllAdditionalQueryParams(additionalQueryParams)
+ }
+
+ fun putAdditionalQueryParam(key: String, value: String) = apply {
+ additionalQueryParams.put(key, value)
+ }
+
+ fun putAdditionalQueryParams(key: String, values: Iterable) = apply {
+ additionalQueryParams.put(key, values)
+ }
+
+ fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply {
+ this.additionalQueryParams.putAll(additionalQueryParams)
+ }
+
+ fun putAllAdditionalQueryParams(additionalQueryParams: Map>) =
+ apply {
+ this.additionalQueryParams.putAll(additionalQueryParams)
+ }
+
+ fun replaceAdditionalQueryParams(key: String, value: String) = apply {
+ additionalQueryParams.replace(key, value)
+ }
+
+ fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply {
+ additionalQueryParams.replace(key, values)
+ }
+
+ fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply {
+ this.additionalQueryParams.replaceAll(additionalQueryParams)
+ }
+
+ fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) =
+ apply {
+ this.additionalQueryParams.replaceAll(additionalQueryParams)
+ }
+
+ fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) }
+
+ fun removeAllAdditionalQueryParams(keys: Set) = apply {
+ additionalQueryParams.removeAll(keys)
+ }
+
+ /**
+ * Returns an immutable instance of [BackgroundTaskRetrieveParams].
+ *
+ * Further updates to this [Builder] will not mutate the returned instance.
+ */
+ fun build(): BackgroundTaskRetrieveParams =
+ BackgroundTaskRetrieveParams(
+ taskId,
+ additionalHeaders.build(),
+ additionalQueryParams.build(),
+ )
+ }
+
+ fun _pathParam(index: Int): String =
+ when (index) {
+ 0 -> taskId ?: ""
+ else -> ""
+ }
+
+ override fun _headers(): Headers = additionalHeaders
+
+ override fun _queryParams(): QueryParams = additionalQueryParams
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) {
+ return true
+ }
+
+ return other is BackgroundTaskRetrieveParams &&
+ taskId == other.taskId &&
+ additionalHeaders == other.additionalHeaders &&
+ additionalQueryParams == other.additionalQueryParams
+ }
+
+ override fun hashCode(): Int = Objects.hash(taskId, additionalHeaders, additionalQueryParams)
+
+ override fun toString() =
+ "BackgroundTaskRetrieveParams{taskId=$taskId, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}"
+}
diff --git a/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/backgroundtasks/BackgroundTaskRetrieveResponse.kt b/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/backgroundtasks/BackgroundTaskRetrieveResponse.kt
new file mode 100644
index 00000000..199e6969
--- /dev/null
+++ b/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/backgroundtasks/BackgroundTaskRetrieveResponse.kt
@@ -0,0 +1,458 @@
+// File generated from our OpenAPI spec by Stainless.
+
+package com.openlayer.api.models.backgroundtasks
+
+import com.fasterxml.jackson.annotation.JsonAnyGetter
+import com.fasterxml.jackson.annotation.JsonAnySetter
+import com.fasterxml.jackson.annotation.JsonCreator
+import com.fasterxml.jackson.annotation.JsonProperty
+import com.openlayer.api.core.ExcludeMissing
+import com.openlayer.api.core.JsonField
+import com.openlayer.api.core.JsonMissing
+import com.openlayer.api.core.JsonValue
+import com.openlayer.api.core.checkRequired
+import com.openlayer.api.errors.OpenlayerInvalidDataException
+import java.time.OffsetDateTime
+import java.util.Collections
+import java.util.Objects
+import java.util.Optional
+import kotlin.jvm.optionals.getOrNull
+
+class BackgroundTaskRetrieveResponse
+@JsonCreator(mode = JsonCreator.Mode.DISABLED)
+private constructor(
+ private val id: JsonField,
+ private val complete: JsonField,
+ private val dateCreated: JsonField,
+ private val dateUpdated: JsonField,
+ private val name: JsonField,
+ private val progress: JsonField,
+ private val error: JsonField,
+ private val outputs: JsonValue,
+ private val additionalProperties: MutableMap,
+) {
+
+ @JsonCreator
+ private constructor(
+ @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(),
+ @JsonProperty("complete") @ExcludeMissing complete: JsonField = JsonMissing.of(),
+ @JsonProperty("dateCreated")
+ @ExcludeMissing
+ dateCreated: JsonField = JsonMissing.of(),
+ @JsonProperty("dateUpdated")
+ @ExcludeMissing
+ dateUpdated: JsonField = JsonMissing.of(),
+ @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(),
+ @JsonProperty("progress") @ExcludeMissing progress: JsonField = JsonMissing.of(),
+ @JsonProperty("error") @ExcludeMissing error: JsonField = JsonMissing.of(),
+ @JsonProperty("outputs") @ExcludeMissing outputs: JsonValue = JsonMissing.of(),
+ ) : this(id, complete, dateCreated, dateUpdated, name, progress, error, outputs, mutableMapOf())
+
+ /**
+ * The background task id.
+ *
+ * @throws OpenlayerInvalidDataException if the JSON field has an unexpected type or is
+ * unexpectedly missing or null (e.g. if the server responded with an unexpected value).
+ */
+ fun id(): String = id.getRequired("id")
+
+ /**
+ * Whether the task has finished. Check this before reading `outputs`.
+ *
+ * @throws OpenlayerInvalidDataException if the JSON field has an unexpected type or is
+ * unexpectedly missing or null (e.g. if the server responded with an unexpected value).
+ */
+ fun complete(): Boolean = complete.getRequired("complete")
+
+ /**
+ * When the task was queued.
+ *
+ * @throws OpenlayerInvalidDataException if the JSON field has an unexpected type or is
+ * unexpectedly missing or null (e.g. if the server responded with an unexpected value).
+ */
+ fun dateCreated(): OffsetDateTime = dateCreated.getRequired("dateCreated")
+
+ /**
+ * When the task last reported progress.
+ *
+ * @throws OpenlayerInvalidDataException if the JSON field has an unexpected type or is
+ * unexpectedly missing or null (e.g. if the server responded with an unexpected value).
+ */
+ fun dateUpdated(): OffsetDateTime = dateUpdated.getRequired("dateUpdated")
+
+ /**
+ * The task's internal name, including the arguments it was queued with.
+ *
+ * @throws OpenlayerInvalidDataException if the JSON field has an unexpected type or is
+ * unexpectedly missing or null (e.g. if the server responded with an unexpected value).
+ */
+ fun name(): String = name.getRequired("name")
+
+ /**
+ * How far along the task is, from 0 to 100.
+ *
+ * @throws OpenlayerInvalidDataException if the JSON field has an unexpected type or is
+ * unexpectedly missing or null (e.g. if the server responded with an unexpected value).
+ */
+ fun progress(): Float = progress.getRequired("progress")
+
+ /**
+ * Why the task failed, or `null` if it has not failed.
+ *
+ * @throws OpenlayerInvalidDataException if the JSON field has an unexpected type (e.g. if the
+ * server responded with an unexpected value).
+ */
+ fun error(): Optional = error.getOptional("error")
+
+ /**
+ * Whatever the task produced, keyed by name. `null` until the task completes. A framework
+ * export returns `storageUri` -- pass it to `GET /storage/presigned-url` to download the
+ * archive -- along with `filename`, `controlCount`, `evidenceCount` and `missingEvidenceCount`.
+ *
+ * This arbitrary value can be deserialized into a custom type using the `convert` method:
+ * ```java
+ * MyClass myObject = backgroundTaskRetrieveResponse.outputs().convert(MyClass.class);
+ * ```
+ */
+ @JsonProperty("outputs") @ExcludeMissing fun _outputs(): JsonValue = outputs
+
+ /**
+ * Returns the raw JSON value of [id].
+ *
+ * Unlike [id], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id
+
+ /**
+ * Returns the raw JSON value of [complete].
+ *
+ * Unlike [complete], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("complete") @ExcludeMissing fun _complete(): JsonField = complete
+
+ /**
+ * Returns the raw JSON value of [dateCreated].
+ *
+ * Unlike [dateCreated], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("dateCreated")
+ @ExcludeMissing
+ fun _dateCreated(): JsonField = dateCreated
+
+ /**
+ * Returns the raw JSON value of [dateUpdated].
+ *
+ * Unlike [dateUpdated], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("dateUpdated")
+ @ExcludeMissing
+ fun _dateUpdated(): JsonField = dateUpdated
+
+ /**
+ * Returns the raw JSON value of [name].
+ *
+ * Unlike [name], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name
+
+ /**
+ * Returns the raw JSON value of [progress].
+ *
+ * Unlike [progress], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("progress") @ExcludeMissing fun _progress(): JsonField = progress
+
+ /**
+ * Returns the raw JSON value of [error].
+ *
+ * Unlike [error], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("error") @ExcludeMissing fun _error(): JsonField = error
+
+ @JsonAnySetter
+ private fun putAdditionalProperty(key: String, value: JsonValue) {
+ additionalProperties.put(key, value)
+ }
+
+ @JsonAnyGetter
+ @ExcludeMissing
+ fun _additionalProperties(): Map =
+ Collections.unmodifiableMap(additionalProperties)
+
+ fun toBuilder() = Builder().from(this)
+
+ companion object {
+
+ /**
+ * Returns a mutable builder for constructing an instance of
+ * [BackgroundTaskRetrieveResponse].
+ *
+ * The following fields are required:
+ * ```java
+ * .id()
+ * .complete()
+ * .dateCreated()
+ * .dateUpdated()
+ * .name()
+ * .progress()
+ * ```
+ */
+ @JvmStatic fun builder() = Builder()
+ }
+
+ /** A builder for [BackgroundTaskRetrieveResponse]. */
+ class Builder internal constructor() {
+
+ private var id: JsonField? = null
+ private var complete: JsonField? = null
+ private var dateCreated: JsonField? = null
+ private var dateUpdated: JsonField? = null
+ private var name: JsonField? = null
+ private var progress: JsonField? = null
+ private var error: JsonField = JsonMissing.of()
+ private var outputs: JsonValue = JsonMissing.of()
+ private var additionalProperties: MutableMap = mutableMapOf()
+
+ @JvmSynthetic
+ internal fun from(backgroundTaskRetrieveResponse: BackgroundTaskRetrieveResponse) = apply {
+ id = backgroundTaskRetrieveResponse.id
+ complete = backgroundTaskRetrieveResponse.complete
+ dateCreated = backgroundTaskRetrieveResponse.dateCreated
+ dateUpdated = backgroundTaskRetrieveResponse.dateUpdated
+ name = backgroundTaskRetrieveResponse.name
+ progress = backgroundTaskRetrieveResponse.progress
+ error = backgroundTaskRetrieveResponse.error
+ outputs = backgroundTaskRetrieveResponse.outputs
+ additionalProperties =
+ backgroundTaskRetrieveResponse.additionalProperties.toMutableMap()
+ }
+
+ /** The background task id. */
+ fun id(id: String) = id(JsonField.of(id))
+
+ /**
+ * Sets [Builder.id] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.id] with a well-typed [String] value instead. This
+ * method is primarily for setting the field to an undocumented or not yet supported value.
+ */
+ fun id(id: JsonField) = apply { this.id = id }
+
+ /** Whether the task has finished. Check this before reading `outputs`. */
+ fun complete(complete: Boolean) = complete(JsonField.of(complete))
+
+ /**
+ * Sets [Builder.complete] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.complete] with a well-typed [Boolean] value instead.
+ * This method is primarily for setting the field to an undocumented or not yet supported
+ * value.
+ */
+ fun complete(complete: JsonField) = apply { this.complete = complete }
+
+ /** When the task was queued. */
+ fun dateCreated(dateCreated: OffsetDateTime) = dateCreated(JsonField.of(dateCreated))
+
+ /**
+ * Sets [Builder.dateCreated] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.dateCreated] with a well-typed [OffsetDateTime] value
+ * instead. This method is primarily for setting the field to an undocumented or not yet
+ * supported value.
+ */
+ fun dateCreated(dateCreated: JsonField) = apply {
+ this.dateCreated = dateCreated
+ }
+
+ /** When the task last reported progress. */
+ fun dateUpdated(dateUpdated: OffsetDateTime) = dateUpdated(JsonField.of(dateUpdated))
+
+ /**
+ * Sets [Builder.dateUpdated] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.dateUpdated] with a well-typed [OffsetDateTime] value
+ * instead. This method is primarily for setting the field to an undocumented or not yet
+ * supported value.
+ */
+ fun dateUpdated(dateUpdated: JsonField) = apply {
+ this.dateUpdated = dateUpdated
+ }
+
+ /** The task's internal name, including the arguments it was queued with. */
+ fun name(name: String) = name(JsonField.of(name))
+
+ /**
+ * Sets [Builder.name] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.name] with a well-typed [String] value instead. This
+ * method is primarily for setting the field to an undocumented or not yet supported value.
+ */
+ fun name(name: JsonField) = apply { this.name = name }
+
+ /** How far along the task is, from 0 to 100. */
+ fun progress(progress: Float) = progress(JsonField.of(progress))
+
+ /**
+ * Sets [Builder.progress] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.progress] with a well-typed [Float] value instead. This
+ * method is primarily for setting the field to an undocumented or not yet supported value.
+ */
+ fun progress(progress: JsonField) = apply { this.progress = progress }
+
+ /** Why the task failed, or `null` if it has not failed. */
+ fun error(error: String?) = error(JsonField.ofNullable(error))
+
+ /** Alias for calling [Builder.error] with `error.orElse(null)`. */
+ fun error(error: Optional) = error(error.getOrNull())
+
+ /**
+ * Sets [Builder.error] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.error] with a well-typed [String] value instead. This
+ * method is primarily for setting the field to an undocumented or not yet supported value.
+ */
+ fun error(error: JsonField) = apply { this.error = error }
+
+ /**
+ * Whatever the task produced, keyed by name. `null` until the task completes. A framework
+ * export returns `storageUri` -- pass it to `GET /storage/presigned-url` to download the
+ * archive -- along with `filename`, `controlCount`, `evidenceCount` and
+ * `missingEvidenceCount`.
+ */
+ fun outputs(outputs: JsonValue) = apply { this.outputs = outputs }
+
+ fun additionalProperties(additionalProperties: Map) = apply {
+ this.additionalProperties.clear()
+ putAllAdditionalProperties(additionalProperties)
+ }
+
+ fun putAdditionalProperty(key: String, value: JsonValue) = apply {
+ additionalProperties.put(key, value)
+ }
+
+ fun putAllAdditionalProperties(additionalProperties: Map) = apply {
+ this.additionalProperties.putAll(additionalProperties)
+ }
+
+ fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) }
+
+ fun removeAllAdditionalProperties(keys: Set) = apply {
+ keys.forEach(::removeAdditionalProperty)
+ }
+
+ /**
+ * Returns an immutable instance of [BackgroundTaskRetrieveResponse].
+ *
+ * Further updates to this [Builder] will not mutate the returned instance.
+ *
+ * The following fields are required:
+ * ```java
+ * .id()
+ * .complete()
+ * .dateCreated()
+ * .dateUpdated()
+ * .name()
+ * .progress()
+ * ```
+ *
+ * @throws IllegalStateException if any required field is unset.
+ */
+ fun build(): BackgroundTaskRetrieveResponse =
+ BackgroundTaskRetrieveResponse(
+ checkRequired("id", id),
+ checkRequired("complete", complete),
+ checkRequired("dateCreated", dateCreated),
+ checkRequired("dateUpdated", dateUpdated),
+ checkRequired("name", name),
+ checkRequired("progress", progress),
+ error,
+ outputs,
+ additionalProperties.toMutableMap(),
+ )
+ }
+
+ private var validated: Boolean = false
+
+ /**
+ * Validates that the types of all values in this object match their expected types recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws OpenlayerInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
+ fun validate(): BackgroundTaskRetrieveResponse = apply {
+ if (validated) {
+ return@apply
+ }
+
+ id()
+ complete()
+ dateCreated()
+ dateUpdated()
+ name()
+ progress()
+ error()
+ validated = true
+ }
+
+ fun isValid(): Boolean =
+ try {
+ validate()
+ true
+ } catch (e: OpenlayerInvalidDataException) {
+ false
+ }
+
+ /**
+ * Returns a score indicating how many valid values are contained in this object recursively.
+ *
+ * Used for best match union deserialization.
+ */
+ @JvmSynthetic
+ internal fun validity(): Int =
+ (if (id.asKnown().isPresent) 1 else 0) +
+ (if (complete.asKnown().isPresent) 1 else 0) +
+ (if (dateCreated.asKnown().isPresent) 1 else 0) +
+ (if (dateUpdated.asKnown().isPresent) 1 else 0) +
+ (if (name.asKnown().isPresent) 1 else 0) +
+ (if (progress.asKnown().isPresent) 1 else 0) +
+ (if (error.asKnown().isPresent) 1 else 0)
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) {
+ return true
+ }
+
+ return other is BackgroundTaskRetrieveResponse &&
+ id == other.id &&
+ complete == other.complete &&
+ dateCreated == other.dateCreated &&
+ dateUpdated == other.dateUpdated &&
+ name == other.name &&
+ progress == other.progress &&
+ error == other.error &&
+ outputs == other.outputs &&
+ additionalProperties == other.additionalProperties
+ }
+
+ private val hashCode: Int by lazy {
+ Objects.hash(
+ id,
+ complete,
+ dateCreated,
+ dateUpdated,
+ name,
+ progress,
+ error,
+ outputs,
+ additionalProperties,
+ )
+ }
+
+ override fun hashCode(): Int = hashCode
+
+ override fun toString() =
+ "BackgroundTaskRetrieveResponse{id=$id, complete=$complete, dateCreated=$dateCreated, dateUpdated=$dateUpdated, name=$name, progress=$progress, error=$error, outputs=$outputs, additionalProperties=$additionalProperties}"
+}
diff --git a/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/frameworks/FrameworkCreateParams.kt b/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/frameworks/FrameworkCreateParams.kt
new file mode 100644
index 00000000..662e5b9d
--- /dev/null
+++ b/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/frameworks/FrameworkCreateParams.kt
@@ -0,0 +1,1382 @@
+// File generated from our OpenAPI spec by Stainless.
+
+package com.openlayer.api.models.governance.frameworks
+
+import com.fasterxml.jackson.annotation.JsonAnyGetter
+import com.fasterxml.jackson.annotation.JsonAnySetter
+import com.fasterxml.jackson.annotation.JsonCreator
+import com.fasterxml.jackson.annotation.JsonProperty
+import com.openlayer.api.core.Enum
+import com.openlayer.api.core.ExcludeMissing
+import com.openlayer.api.core.JsonField
+import com.openlayer.api.core.JsonMissing
+import com.openlayer.api.core.JsonValue
+import com.openlayer.api.core.Params
+import com.openlayer.api.core.checkKnown
+import com.openlayer.api.core.checkRequired
+import com.openlayer.api.core.http.Headers
+import com.openlayer.api.core.http.QueryParams
+import com.openlayer.api.core.toImmutable
+import com.openlayer.api.errors.OpenlayerInvalidDataException
+import java.util.Collections
+import java.util.Objects
+import java.util.Optional
+import kotlin.jvm.optionals.getOrNull
+
+/**
+ * Create a custom governance framework in a workspace.
+ *
+ * Use this to track compliance against an internal policy, or against a standard Openlayer does not
+ * ship as a built-in framework. A new framework starts with no rules -- add them from the Openlayer
+ * app, or map an existing rule to it.
+ *
+ * A framework is created disabled unless you pass `enabled: true`. While it is disabled its rules
+ * are not evaluated and do not count towards compliance.
+ */
+class FrameworkCreateParams
+private constructor(
+ private val workspaceId: String?,
+ private val body: Body,
+ private val additionalHeaders: Headers,
+ private val additionalQueryParams: QueryParams,
+) : Params {
+
+ fun workspaceId(): Optional = Optional.ofNullable(workspaceId)
+
+ /**
+ * The framework name.
+ *
+ * @throws OpenlayerInvalidDataException if the JSON field has an unexpected type or is
+ * unexpectedly missing or null (e.g. if the server responded with an unexpected value).
+ */
+ fun name(): String = body.name()
+
+ /**
+ * A short description of the framework.
+ *
+ * @throws OpenlayerInvalidDataException if the JSON field has an unexpected type (e.g. if the
+ * server responded with an unexpected value).
+ */
+ fun description(): Optional = body.description()
+
+ /**
+ * Whether the framework is active. Rules of a disabled framework are not evaluated and do not
+ * count towards compliance.
+ *
+ * @throws OpenlayerInvalidDataException if the JSON field has an unexpected type (e.g. if the
+ * server responded with an unexpected value).
+ */
+ fun enabled(): Optional = body.enabled()
+
+ /**
+ * Determines which projects the framework applies to. An empty or `null` `match` array applies
+ * the framework to every project in the workspace.
+ *
+ * @throws OpenlayerInvalidDataException if the JSON field has an unexpected type (e.g. if the
+ * server responded with an unexpected value).
+ */
+ fun projectSelector(): Optional = body.projectSelector()
+
+ /**
+ * Free-form labels on the framework.
+ *
+ * @throws OpenlayerInvalidDataException if the JSON field has an unexpected type (e.g. if the
+ * server responded with an unexpected value).
+ */
+ fun tags(): Optional> = body.tags()
+
+ /**
+ * Returns the raw JSON value of [name].
+ *
+ * Unlike [name], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ fun _name(): JsonField = body._name()
+
+ /**
+ * Returns the raw JSON value of [description].
+ *
+ * Unlike [description], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ fun _description(): JsonField = body._description()
+
+ /**
+ * Returns the raw JSON value of [enabled].
+ *
+ * Unlike [enabled], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ fun _enabled(): JsonField = body._enabled()
+
+ /**
+ * Returns the raw JSON value of [projectSelector].
+ *
+ * Unlike [projectSelector], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ fun _projectSelector(): JsonField = body._projectSelector()
+
+ /**
+ * Returns the raw JSON value of [tags].
+ *
+ * Unlike [tags], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ fun _tags(): JsonField> = body._tags()
+
+ fun _additionalBodyProperties(): Map = body._additionalProperties()
+
+ /** Additional headers to send with the request. */
+ fun _additionalHeaders(): Headers = additionalHeaders
+
+ /** Additional query param to send with the request. */
+ fun _additionalQueryParams(): QueryParams = additionalQueryParams
+
+ fun toBuilder() = Builder().from(this)
+
+ companion object {
+
+ /**
+ * Returns a mutable builder for constructing an instance of [FrameworkCreateParams].
+ *
+ * The following fields are required:
+ * ```java
+ * .name()
+ * ```
+ */
+ @JvmStatic fun builder() = Builder()
+ }
+
+ /** A builder for [FrameworkCreateParams]. */
+ class Builder internal constructor() {
+
+ private var workspaceId: String? = null
+ private var body: Body.Builder = Body.builder()
+ private var additionalHeaders: Headers.Builder = Headers.builder()
+ private var additionalQueryParams: QueryParams.Builder = QueryParams.builder()
+
+ @JvmSynthetic
+ internal fun from(frameworkCreateParams: FrameworkCreateParams) = apply {
+ workspaceId = frameworkCreateParams.workspaceId
+ body = frameworkCreateParams.body.toBuilder()
+ additionalHeaders = frameworkCreateParams.additionalHeaders.toBuilder()
+ additionalQueryParams = frameworkCreateParams.additionalQueryParams.toBuilder()
+ }
+
+ fun workspaceId(workspaceId: String?) = apply { this.workspaceId = workspaceId }
+
+ /** Alias for calling [Builder.workspaceId] with `workspaceId.orElse(null)`. */
+ fun workspaceId(workspaceId: Optional) = workspaceId(workspaceId.getOrNull())
+
+ /**
+ * Sets the entire request body.
+ *
+ * This is generally only useful if you are already constructing the body separately.
+ * Otherwise, it's more convenient to use the top-level setters instead:
+ * - [name]
+ * - [description]
+ * - [enabled]
+ * - [projectSelector]
+ * - [tags]
+ * - etc.
+ */
+ fun body(body: Body) = apply { this.body = body.toBuilder() }
+
+ /** The framework name. */
+ fun name(name: String) = apply { body.name(name) }
+
+ /**
+ * Sets [Builder.name] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.name] with a well-typed [String] value instead. This
+ * method is primarily for setting the field to an undocumented or not yet supported value.
+ */
+ fun name(name: JsonField) = apply { body.name(name) }
+
+ /** A short description of the framework. */
+ fun description(description: String?) = apply { body.description(description) }
+
+ /** Alias for calling [Builder.description] with `description.orElse(null)`. */
+ fun description(description: Optional) = description(description.getOrNull())
+
+ /**
+ * Sets [Builder.description] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.description] with a well-typed [String] value instead.
+ * This method is primarily for setting the field to an undocumented or not yet supported
+ * value.
+ */
+ fun description(description: JsonField) = apply { body.description(description) }
+
+ /**
+ * Whether the framework is active. Rules of a disabled framework are not evaluated and do
+ * not count towards compliance.
+ */
+ fun enabled(enabled: Boolean) = apply { body.enabled(enabled) }
+
+ /**
+ * Sets [Builder.enabled] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.enabled] with a well-typed [Boolean] value instead. This
+ * method is primarily for setting the field to an undocumented or not yet supported value.
+ */
+ fun enabled(enabled: JsonField) = apply { body.enabled(enabled) }
+
+ /**
+ * Determines which projects the framework applies to. An empty or `null` `match` array
+ * applies the framework to every project in the workspace.
+ */
+ fun projectSelector(projectSelector: ProjectSelector?) = apply {
+ body.projectSelector(projectSelector)
+ }
+
+ /** Alias for calling [Builder.projectSelector] with `projectSelector.orElse(null)`. */
+ fun projectSelector(projectSelector: Optional) =
+ projectSelector(projectSelector.getOrNull())
+
+ /**
+ * Sets [Builder.projectSelector] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.projectSelector] with a well-typed [ProjectSelector]
+ * value instead. This method is primarily for setting the field to an undocumented or not
+ * yet supported value.
+ */
+ fun projectSelector(projectSelector: JsonField) = apply {
+ body.projectSelector(projectSelector)
+ }
+
+ /** Free-form labels on the framework. */
+ fun tags(tags: List) = apply { body.tags(tags) }
+
+ /**
+ * Sets [Builder.tags] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.tags] with a well-typed `List` value instead.
+ * This method is primarily for setting the field to an undocumented or not yet supported
+ * value.
+ */
+ fun tags(tags: JsonField>) = apply { body.tags(tags) }
+
+ /**
+ * Adds a single [String] to [tags].
+ *
+ * @throws IllegalStateException if the field was previously set to a non-list.
+ */
+ fun addTag(tag: String) = apply { body.addTag(tag) }
+
+ fun additionalBodyProperties(additionalBodyProperties: Map) = apply {
+ body.additionalProperties(additionalBodyProperties)
+ }
+
+ fun putAdditionalBodyProperty(key: String, value: JsonValue) = apply {
+ body.putAdditionalProperty(key, value)
+ }
+
+ fun putAllAdditionalBodyProperties(additionalBodyProperties: Map) =
+ apply {
+ body.putAllAdditionalProperties(additionalBodyProperties)
+ }
+
+ fun removeAdditionalBodyProperty(key: String) = apply { body.removeAdditionalProperty(key) }
+
+ fun removeAllAdditionalBodyProperties(keys: Set) = apply {
+ body.removeAllAdditionalProperties(keys)
+ }
+
+ fun additionalHeaders(additionalHeaders: Headers) = apply {
+ this.additionalHeaders.clear()
+ putAllAdditionalHeaders(additionalHeaders)
+ }
+
+ fun additionalHeaders(additionalHeaders: Map>) = apply {
+ this.additionalHeaders.clear()
+ putAllAdditionalHeaders(additionalHeaders)
+ }
+
+ fun putAdditionalHeader(name: String, value: String) = apply {
+ additionalHeaders.put(name, value)
+ }
+
+ fun putAdditionalHeaders(name: String, values: Iterable) = apply {
+ additionalHeaders.put(name, values)
+ }
+
+ fun putAllAdditionalHeaders(additionalHeaders: Headers) = apply {
+ this.additionalHeaders.putAll(additionalHeaders)
+ }
+
+ fun putAllAdditionalHeaders(additionalHeaders: Map>) = apply {
+ this.additionalHeaders.putAll(additionalHeaders)
+ }
+
+ fun replaceAdditionalHeaders(name: String, value: String) = apply {
+ additionalHeaders.replace(name, value)
+ }
+
+ fun replaceAdditionalHeaders(name: String, values: Iterable) = apply {
+ additionalHeaders.replace(name, values)
+ }
+
+ fun replaceAllAdditionalHeaders(additionalHeaders: Headers) = apply {
+ this.additionalHeaders.replaceAll(additionalHeaders)
+ }
+
+ fun replaceAllAdditionalHeaders(additionalHeaders: Map>) = apply {
+ this.additionalHeaders.replaceAll(additionalHeaders)
+ }
+
+ fun removeAdditionalHeaders(name: String) = apply { additionalHeaders.remove(name) }
+
+ fun removeAllAdditionalHeaders(names: Set) = apply {
+ additionalHeaders.removeAll(names)
+ }
+
+ fun additionalQueryParams(additionalQueryParams: QueryParams) = apply {
+ this.additionalQueryParams.clear()
+ putAllAdditionalQueryParams(additionalQueryParams)
+ }
+
+ fun additionalQueryParams(additionalQueryParams: Map>) = apply {
+ this.additionalQueryParams.clear()
+ putAllAdditionalQueryParams(additionalQueryParams)
+ }
+
+ fun putAdditionalQueryParam(key: String, value: String) = apply {
+ additionalQueryParams.put(key, value)
+ }
+
+ fun putAdditionalQueryParams(key: String, values: Iterable) = apply {
+ additionalQueryParams.put(key, values)
+ }
+
+ fun putAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply {
+ this.additionalQueryParams.putAll(additionalQueryParams)
+ }
+
+ fun putAllAdditionalQueryParams(additionalQueryParams: Map>) =
+ apply {
+ this.additionalQueryParams.putAll(additionalQueryParams)
+ }
+
+ fun replaceAdditionalQueryParams(key: String, value: String) = apply {
+ additionalQueryParams.replace(key, value)
+ }
+
+ fun replaceAdditionalQueryParams(key: String, values: Iterable) = apply {
+ additionalQueryParams.replace(key, values)
+ }
+
+ fun replaceAllAdditionalQueryParams(additionalQueryParams: QueryParams) = apply {
+ this.additionalQueryParams.replaceAll(additionalQueryParams)
+ }
+
+ fun replaceAllAdditionalQueryParams(additionalQueryParams: Map>) =
+ apply {
+ this.additionalQueryParams.replaceAll(additionalQueryParams)
+ }
+
+ fun removeAdditionalQueryParams(key: String) = apply { additionalQueryParams.remove(key) }
+
+ fun removeAllAdditionalQueryParams(keys: Set) = apply {
+ additionalQueryParams.removeAll(keys)
+ }
+
+ /**
+ * Returns an immutable instance of [FrameworkCreateParams].
+ *
+ * Further updates to this [Builder] will not mutate the returned instance.
+ *
+ * The following fields are required:
+ * ```java
+ * .name()
+ * ```
+ *
+ * @throws IllegalStateException if any required field is unset.
+ */
+ fun build(): FrameworkCreateParams =
+ FrameworkCreateParams(
+ workspaceId,
+ body.build(),
+ additionalHeaders.build(),
+ additionalQueryParams.build(),
+ )
+ }
+
+ fun _body(): Body = body
+
+ fun _pathParam(index: Int): String =
+ when (index) {
+ 0 -> workspaceId ?: ""
+ else -> ""
+ }
+
+ override fun _headers(): Headers = additionalHeaders
+
+ override fun _queryParams(): QueryParams = additionalQueryParams
+
+ class Body
+ @JsonCreator(mode = JsonCreator.Mode.DISABLED)
+ private constructor(
+ private val name: JsonField,
+ private val description: JsonField,
+ private val enabled: JsonField,
+ private val projectSelector: JsonField,
+ private val tags: JsonField>,
+ private val additionalProperties: MutableMap,
+ ) {
+
+ @JsonCreator
+ private constructor(
+ @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(),
+ @JsonProperty("description")
+ @ExcludeMissing
+ description: JsonField = JsonMissing.of(),
+ @JsonProperty("enabled") @ExcludeMissing enabled: JsonField = JsonMissing.of(),
+ @JsonProperty("projectSelector")
+ @ExcludeMissing
+ projectSelector: JsonField = JsonMissing.of(),
+ @JsonProperty("tags") @ExcludeMissing tags: JsonField> = JsonMissing.of(),
+ ) : this(name, description, enabled, projectSelector, tags, mutableMapOf())
+
+ /**
+ * The framework name.
+ *
+ * @throws OpenlayerInvalidDataException if the JSON field has an unexpected type or is
+ * unexpectedly missing or null (e.g. if the server responded with an unexpected value).
+ */
+ fun name(): String = name.getRequired("name")
+
+ /**
+ * A short description of the framework.
+ *
+ * @throws OpenlayerInvalidDataException if the JSON field has an unexpected type (e.g. if
+ * the server responded with an unexpected value).
+ */
+ fun description(): Optional = description.getOptional("description")
+
+ /**
+ * Whether the framework is active. Rules of a disabled framework are not evaluated and do
+ * not count towards compliance.
+ *
+ * @throws OpenlayerInvalidDataException if the JSON field has an unexpected type (e.g. if
+ * the server responded with an unexpected value).
+ */
+ fun enabled(): Optional = enabled.getOptional("enabled")
+
+ /**
+ * Determines which projects the framework applies to. An empty or `null` `match` array
+ * applies the framework to every project in the workspace.
+ *
+ * @throws OpenlayerInvalidDataException if the JSON field has an unexpected type (e.g. if
+ * the server responded with an unexpected value).
+ */
+ fun projectSelector(): Optional =
+ projectSelector.getOptional("projectSelector")
+
+ /**
+ * Free-form labels on the framework.
+ *
+ * @throws OpenlayerInvalidDataException if the JSON field has an unexpected type (e.g. if
+ * the server responded with an unexpected value).
+ */
+ fun tags(): Optional> = tags.getOptional("tags")
+
+ /**
+ * Returns the raw JSON value of [name].
+ *
+ * Unlike [name], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name
+
+ /**
+ * Returns the raw JSON value of [description].
+ *
+ * Unlike [description], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("description")
+ @ExcludeMissing
+ fun _description(): JsonField = description
+
+ /**
+ * Returns the raw JSON value of [enabled].
+ *
+ * Unlike [enabled], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("enabled") @ExcludeMissing fun _enabled(): JsonField = enabled
+
+ /**
+ * Returns the raw JSON value of [projectSelector].
+ *
+ * Unlike [projectSelector], this method doesn't throw if the JSON field has an unexpected
+ * type.
+ */
+ @JsonProperty("projectSelector")
+ @ExcludeMissing
+ fun _projectSelector(): JsonField = projectSelector
+
+ /**
+ * Returns the raw JSON value of [tags].
+ *
+ * Unlike [tags], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("tags") @ExcludeMissing fun _tags(): JsonField> = tags
+
+ @JsonAnySetter
+ private fun putAdditionalProperty(key: String, value: JsonValue) {
+ additionalProperties.put(key, value)
+ }
+
+ @JsonAnyGetter
+ @ExcludeMissing
+ fun _additionalProperties(): Map =
+ Collections.unmodifiableMap(additionalProperties)
+
+ fun toBuilder() = Builder().from(this)
+
+ companion object {
+
+ /**
+ * Returns a mutable builder for constructing an instance of [Body].
+ *
+ * The following fields are required:
+ * ```java
+ * .name()
+ * ```
+ */
+ @JvmStatic fun builder() = Builder()
+ }
+
+ /** A builder for [Body]. */
+ class Builder internal constructor() {
+
+ private var name: JsonField? = null
+ private var description: JsonField = JsonMissing.of()
+ private var enabled: JsonField = JsonMissing.of()
+ private var projectSelector: JsonField = JsonMissing.of()
+ private var tags: JsonField>? = null
+ private var additionalProperties: MutableMap = mutableMapOf()
+
+ @JvmSynthetic
+ internal fun from(body: Body) = apply {
+ name = body.name
+ description = body.description
+ enabled = body.enabled
+ projectSelector = body.projectSelector
+ tags = body.tags.map { it.toMutableList() }
+ additionalProperties = body.additionalProperties.toMutableMap()
+ }
+
+ /** The framework name. */
+ fun name(name: String) = name(JsonField.of(name))
+
+ /**
+ * Sets [Builder.name] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.name] with a well-typed [String] value instead. This
+ * method is primarily for setting the field to an undocumented or not yet supported
+ * value.
+ */
+ fun name(name: JsonField) = apply { this.name = name }
+
+ /** A short description of the framework. */
+ fun description(description: String?) = description(JsonField.ofNullable(description))
+
+ /** Alias for calling [Builder.description] with `description.orElse(null)`. */
+ fun description(description: Optional) = description(description.getOrNull())
+
+ /**
+ * Sets [Builder.description] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.description] with a well-typed [String] value
+ * instead. This method is primarily for setting the field to an undocumented or not yet
+ * supported value.
+ */
+ fun description(description: JsonField) = apply {
+ this.description = description
+ }
+
+ /**
+ * Whether the framework is active. Rules of a disabled framework are not evaluated and
+ * do not count towards compliance.
+ */
+ fun enabled(enabled: Boolean) = enabled(JsonField.of(enabled))
+
+ /**
+ * Sets [Builder.enabled] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.enabled] with a well-typed [Boolean] value instead.
+ * This method is primarily for setting the field to an undocumented or not yet
+ * supported value.
+ */
+ fun enabled(enabled: JsonField) = apply { this.enabled = enabled }
+
+ /**
+ * Determines which projects the framework applies to. An empty or `null` `match` array
+ * applies the framework to every project in the workspace.
+ */
+ fun projectSelector(projectSelector: ProjectSelector?) =
+ projectSelector(JsonField.ofNullable(projectSelector))
+
+ /** Alias for calling [Builder.projectSelector] with `projectSelector.orElse(null)`. */
+ fun projectSelector(projectSelector: Optional) =
+ projectSelector(projectSelector.getOrNull())
+
+ /**
+ * Sets [Builder.projectSelector] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.projectSelector] with a well-typed [ProjectSelector]
+ * value instead. This method is primarily for setting the field to an undocumented or
+ * not yet supported value.
+ */
+ fun projectSelector(projectSelector: JsonField) = apply {
+ this.projectSelector = projectSelector
+ }
+
+ /** Free-form labels on the framework. */
+ fun tags(tags: List) = tags(JsonField.of(tags))
+
+ /**
+ * Sets [Builder.tags] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.tags] with a well-typed `List` value
+ * instead. This method is primarily for setting the field to an undocumented or not yet
+ * supported value.
+ */
+ fun tags(tags: JsonField>) = apply {
+ this.tags = tags.map { it.toMutableList() }
+ }
+
+ /**
+ * Adds a single [String] to [tags].
+ *
+ * @throws IllegalStateException if the field was previously set to a non-list.
+ */
+ fun addTag(tag: String) = apply {
+ tags =
+ (tags ?: JsonField.of(mutableListOf())).also { checkKnown("tags", it).add(tag) }
+ }
+
+ fun additionalProperties(additionalProperties: Map) = apply {
+ this.additionalProperties.clear()
+ putAllAdditionalProperties(additionalProperties)
+ }
+
+ fun putAdditionalProperty(key: String, value: JsonValue) = apply {
+ additionalProperties.put(key, value)
+ }
+
+ fun putAllAdditionalProperties(additionalProperties: Map) = apply {
+ this.additionalProperties.putAll(additionalProperties)
+ }
+
+ fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) }
+
+ fun removeAllAdditionalProperties(keys: Set) = apply {
+ keys.forEach(::removeAdditionalProperty)
+ }
+
+ /**
+ * Returns an immutable instance of [Body].
+ *
+ * Further updates to this [Builder] will not mutate the returned instance.
+ *
+ * The following fields are required:
+ * ```java
+ * .name()
+ * ```
+ *
+ * @throws IllegalStateException if any required field is unset.
+ */
+ fun build(): Body =
+ Body(
+ checkRequired("name", name),
+ description,
+ enabled,
+ projectSelector,
+ (tags ?: JsonMissing.of()).map { it.toImmutable() },
+ additionalProperties.toMutableMap(),
+ )
+ }
+
+ private var validated: Boolean = false
+
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws OpenlayerInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
+ fun validate(): Body = apply {
+ if (validated) {
+ return@apply
+ }
+
+ name()
+ description()
+ enabled()
+ projectSelector().ifPresent { it.validate() }
+ tags()
+ validated = true
+ }
+
+ fun isValid(): Boolean =
+ try {
+ validate()
+ true
+ } catch (e: OpenlayerInvalidDataException) {
+ false
+ }
+
+ /**
+ * Returns a score indicating how many valid values are contained in this object
+ * recursively.
+ *
+ * Used for best match union deserialization.
+ */
+ @JvmSynthetic
+ internal fun validity(): Int =
+ (if (name.asKnown().isPresent) 1 else 0) +
+ (if (description.asKnown().isPresent) 1 else 0) +
+ (if (enabled.asKnown().isPresent) 1 else 0) +
+ (projectSelector.asKnown().getOrNull()?.validity() ?: 0) +
+ (tags.asKnown().getOrNull()?.size ?: 0)
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) {
+ return true
+ }
+
+ return other is Body &&
+ name == other.name &&
+ description == other.description &&
+ enabled == other.enabled &&
+ projectSelector == other.projectSelector &&
+ tags == other.tags &&
+ additionalProperties == other.additionalProperties
+ }
+
+ private val hashCode: Int by lazy {
+ Objects.hash(name, description, enabled, projectSelector, tags, additionalProperties)
+ }
+
+ override fun hashCode(): Int = hashCode
+
+ override fun toString() =
+ "Body{name=$name, description=$description, enabled=$enabled, projectSelector=$projectSelector, tags=$tags, additionalProperties=$additionalProperties}"
+ }
+
+ /**
+ * Determines which projects the framework applies to. An empty or `null` `match` array applies
+ * the framework to every project in the workspace.
+ */
+ class ProjectSelector
+ @JsonCreator(mode = JsonCreator.Mode.DISABLED)
+ private constructor(
+ private val match: JsonField>,
+ private val additionalProperties: MutableMap,
+ ) {
+
+ @JsonCreator
+ private constructor(
+ @JsonProperty("match") @ExcludeMissing match: JsonField> = JsonMissing.of()
+ ) : this(match, mutableMapOf())
+
+ /**
+ * Match criteria, ANDed together.
+ *
+ * @throws OpenlayerInvalidDataException if the JSON field has an unexpected type (e.g. if
+ * the server responded with an unexpected value).
+ */
+ fun match(): Optional> = match.getOptional("match")
+
+ /**
+ * Returns the raw JSON value of [match].
+ *
+ * Unlike [match], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("match") @ExcludeMissing fun _match(): JsonField> = match
+
+ @JsonAnySetter
+ private fun putAdditionalProperty(key: String, value: JsonValue) {
+ additionalProperties.put(key, value)
+ }
+
+ @JsonAnyGetter
+ @ExcludeMissing
+ fun _additionalProperties(): Map =
+ Collections.unmodifiableMap(additionalProperties)
+
+ fun toBuilder() = Builder().from(this)
+
+ companion object {
+
+ /** Returns a mutable builder for constructing an instance of [ProjectSelector]. */
+ @JvmStatic fun builder() = Builder()
+ }
+
+ /** A builder for [ProjectSelector]. */
+ class Builder internal constructor() {
+
+ private var match: JsonField>? = null
+ private var additionalProperties: MutableMap = mutableMapOf()
+
+ @JvmSynthetic
+ internal fun from(projectSelector: ProjectSelector) = apply {
+ match = projectSelector.match.map { it.toMutableList() }
+ additionalProperties = projectSelector.additionalProperties.toMutableMap()
+ }
+
+ /** Match criteria, ANDed together. */
+ fun match(match: List?) = match(JsonField.ofNullable(match))
+
+ /** Alias for calling [Builder.match] with `match.orElse(null)`. */
+ fun match(match: Optional>) = match(match.getOrNull())
+
+ /**
+ * Sets [Builder.match] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.match] with a well-typed `List` value
+ * instead. This method is primarily for setting the field to an undocumented or not yet
+ * supported value.
+ */
+ fun match(match: JsonField>) = apply {
+ this.match = match.map { it.toMutableList() }
+ }
+
+ /**
+ * Adds a single [Match] to [Builder.match].
+ *
+ * @throws IllegalStateException if the field was previously set to a non-list.
+ */
+ fun addMatch(match: Match) = apply {
+ this.match =
+ (this.match ?: JsonField.of(mutableListOf())).also {
+ checkKnown("match", it).add(match)
+ }
+ }
+
+ fun additionalProperties(additionalProperties: Map) = apply {
+ this.additionalProperties.clear()
+ putAllAdditionalProperties(additionalProperties)
+ }
+
+ fun putAdditionalProperty(key: String, value: JsonValue) = apply {
+ additionalProperties.put(key, value)
+ }
+
+ fun putAllAdditionalProperties(additionalProperties: Map) = apply {
+ this.additionalProperties.putAll(additionalProperties)
+ }
+
+ fun removeAdditionalProperty(key: String) = apply { additionalProperties.remove(key) }
+
+ fun removeAllAdditionalProperties(keys: Set) = apply {
+ keys.forEach(::removeAdditionalProperty)
+ }
+
+ /**
+ * Returns an immutable instance of [ProjectSelector].
+ *
+ * Further updates to this [Builder] will not mutate the returned instance.
+ */
+ fun build(): ProjectSelector =
+ ProjectSelector(
+ (match ?: JsonMissing.of()).map { it.toImmutable() },
+ additionalProperties.toMutableMap(),
+ )
+ }
+
+ private var validated: Boolean = false
+
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing fields.
+ *
+ * @throws OpenlayerInvalidDataException if any value type in this object doesn't match its
+ * expected type.
+ */
+ fun validate(): ProjectSelector = apply {
+ if (validated) {
+ return@apply
+ }
+
+ match().ifPresent { it.forEach { it.validate() } }
+ validated = true
+ }
+
+ fun isValid(): Boolean =
+ try {
+ validate()
+ true
+ } catch (e: OpenlayerInvalidDataException) {
+ false
+ }
+
+ /**
+ * Returns a score indicating how many valid values are contained in this object
+ * recursively.
+ *
+ * Used for best match union deserialization.
+ */
+ @JvmSynthetic
+ internal fun validity(): Int =
+ (match.asKnown().getOrNull()?.sumOf { it.validity().toInt() } ?: 0)
+
+ class Match
+ @JsonCreator(mode = JsonCreator.Mode.DISABLED)
+ private constructor(
+ private val property: JsonField,
+ private val value: JsonValue,
+ private val operator: JsonField,
+ private val additionalProperties: MutableMap,
+ ) {
+
+ @JsonCreator
+ private constructor(
+ @JsonProperty("property")
+ @ExcludeMissing
+ property: JsonField = JsonMissing.of(),
+ @JsonProperty("value") @ExcludeMissing value: JsonValue = JsonMissing.of(),
+ @JsonProperty("operator")
+ @ExcludeMissing
+ operator: JsonField = JsonMissing.of(),
+ ) : this(property, value, operator, mutableMapOf())
+
+ /**
+ * The project property to match against.
+ *
+ * @throws OpenlayerInvalidDataException if the JSON field has an unexpected type or is
+ * unexpectedly missing or null (e.g. if the server responded with an unexpected
+ * value).
+ */
+ fun property(): Property = property.getRequired("property")
+
+ /**
+ * The value to match against. Pass an array to match any of several values, or `null`
+ * to match projects where the property is unset. Omit it for `exists` and `notExists`.
+ *
+ * This arbitrary value can be deserialized into a custom type using the `convert`
+ * method:
+ * ```java
+ * MyClass myObject = match.value().convert(MyClass.class);
+ * ```
+ */
+ @JsonProperty("value") @ExcludeMissing fun _value(): JsonValue = value
+
+ /**
+ * How to compare the project property with `value`. One of `equals`, `notEquals`,
+ * `contains`, `notContains`, `startsWith`, `endsWith`, `in`, `notIn`, `greaterThan`,
+ * `greaterThanOrEqual`, `lessThan`, `lessThanOrEqual`, `equalsIgnoreCase`,
+ * `containsIgnoreCase`, `matches`, `exists`, or `notExists`.
+ *
+ * @throws OpenlayerInvalidDataException if the JSON field has an unexpected type (e.g.
+ * if the server responded with an unexpected value).
+ */
+ fun operator(): Optional = operator.getOptional("operator")
+
+ /**
+ * Returns the raw JSON value of [property].
+ *
+ * Unlike [property], this method doesn't throw if the JSON field has an unexpected
+ * type.
+ */
+ @JsonProperty("property")
+ @ExcludeMissing
+ fun _property(): JsonField = property
+
+ /**
+ * Returns the raw JSON value of [operator].
+ *
+ * Unlike [operator], this method doesn't throw if the JSON field has an unexpected
+ * type.
+ */
+ @JsonProperty("operator") @ExcludeMissing fun _operator(): JsonField = operator
+
+ @JsonAnySetter
+ private fun putAdditionalProperty(key: String, value: JsonValue) {
+ additionalProperties.put(key, value)
+ }
+
+ @JsonAnyGetter
+ @ExcludeMissing
+ fun _additionalProperties(): Map =
+ Collections.unmodifiableMap(additionalProperties)
+
+ fun toBuilder() = Builder().from(this)
+
+ companion object {
+
+ /**
+ * Returns a mutable builder for constructing an instance of [Match].
+ *
+ * The following fields are required:
+ * ```java
+ * .property()
+ * .value()
+ * ```
+ */
+ @JvmStatic fun builder() = Builder()
+ }
+
+ /** A builder for [Match]. */
+ class Builder internal constructor() {
+
+ private var property: JsonField? = null
+ private var value: JsonValue? = null
+ private var operator: JsonField = JsonMissing.of()
+ private var additionalProperties: MutableMap = mutableMapOf()
+
+ @JvmSynthetic
+ internal fun from(match: Match) = apply {
+ property = match.property
+ value = match.value
+ operator = match.operator
+ additionalProperties = match.additionalProperties.toMutableMap()
+ }
+
+ /** The project property to match against. */
+ fun property(property: Property) = property(JsonField.of(property))
+
+ /**
+ * Sets [Builder.property] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.property] with a well-typed [Property] value
+ * instead. This method is primarily for setting the field to an undocumented or not
+ * yet supported value.
+ */
+ fun property(property: JsonField) = apply { this.property = property }
+
+ /**
+ * The value to match against. Pass an array to match any of several values, or
+ * `null` to match projects where the property is unset. Omit it for `exists` and
+ * `notExists`.
+ */
+ fun value(value: JsonValue) = apply { this.value = value }
+
+ /**
+ * How to compare the project property with `value`. One of `equals`, `notEquals`,
+ * `contains`, `notContains`, `startsWith`, `endsWith`, `in`, `notIn`,
+ * `greaterThan`, `greaterThanOrEqual`, `lessThan`, `lessThanOrEqual`,
+ * `equalsIgnoreCase`, `containsIgnoreCase`, `matches`, `exists`, or `notExists`.
+ */
+ fun operator(operator: String) = operator(JsonField.of(operator))
+
+ /**
+ * Sets [Builder.operator] to an arbitrary JSON value.
+ *
+ * You should usually call [Builder.operator] with a well-typed [String] value
+ * instead. This method is primarily for setting the field to an undocumented or not
+ * yet supported value.
+ */
+ fun operator(operator: JsonField) = apply { this.operator = operator }
+
+ fun additionalProperties(additionalProperties: Map) = apply {
+ this.additionalProperties.clear()
+ putAllAdditionalProperties(additionalProperties)
+ }
+
+ fun putAdditionalProperty(key: String, value: JsonValue) = apply {
+ additionalProperties.put(key, value)
+ }
+
+ fun putAllAdditionalProperties(additionalProperties: Map) =
+ apply {
+ this.additionalProperties.putAll(additionalProperties)
+ }
+
+ fun removeAdditionalProperty(key: String) = apply {
+ additionalProperties.remove(key)
+ }
+
+ fun removeAllAdditionalProperties(keys: Set) = apply {
+ keys.forEach(::removeAdditionalProperty)
+ }
+
+ /**
+ * Returns an immutable instance of [Match].
+ *
+ * Further updates to this [Builder] will not mutate the returned instance.
+ *
+ * The following fields are required:
+ * ```java
+ * .property()
+ * .value()
+ * ```
+ *
+ * @throws IllegalStateException if any required field is unset.
+ */
+ fun build(): Match =
+ Match(
+ checkRequired("property", property),
+ checkRequired("value", value),
+ operator,
+ additionalProperties.toMutableMap(),
+ )
+ }
+
+ private var validated: Boolean = false
+
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing
+ * fields.
+ *
+ * @throws OpenlayerInvalidDataException if any value type in this object doesn't match
+ * its expected type.
+ */
+ fun validate(): Match = apply {
+ if (validated) {
+ return@apply
+ }
+
+ property().validate()
+ operator()
+ validated = true
+ }
+
+ fun isValid(): Boolean =
+ try {
+ validate()
+ true
+ } catch (e: OpenlayerInvalidDataException) {
+ false
+ }
+
+ /**
+ * Returns a score indicating how many valid values are contained in this object
+ * recursively.
+ *
+ * Used for best match union deserialization.
+ */
+ @JvmSynthetic
+ internal fun validity(): Int =
+ (property.asKnown().getOrNull()?.validity() ?: 0) +
+ (if (operator.asKnown().isPresent) 1 else 0)
+
+ /** The project property to match against. */
+ class Property @JsonCreator private constructor(private val value: JsonField) :
+ Enum {
+
+ /**
+ * Returns this class instance's raw value.
+ *
+ * This is usually only useful if this instance was deserialized from data that
+ * doesn't match any known member, and you want to know that value. For example, if
+ * the SDK is on an older version than the API, then the API may respond with new
+ * members that the SDK is unaware of.
+ */
+ @com.fasterxml.jackson.annotation.JsonValue fun _value(): JsonField = value
+
+ companion object {
+
+ @JvmField val TASK_TYPE = of("taskType")
+
+ @JvmField val RISK_LEVEL = of("riskLevel")
+
+ @JvmField val RISK_TOTAL_SCORE = of("riskTotalScore")
+
+ @JvmField val NAME = of("name")
+
+ @JvmField val OWNER_ID = of("ownerId")
+
+ @JvmField val MODEL_TYPES = of("modelTypes")
+
+ @JvmStatic fun of(value: String) = Property(JsonField.of(value))
+ }
+
+ /** An enum containing [Property]'s known values. */
+ enum class Known {
+ TASK_TYPE,
+ RISK_LEVEL,
+ RISK_TOTAL_SCORE,
+ NAME,
+ OWNER_ID,
+ MODEL_TYPES,
+ }
+
+ /**
+ * An enum containing [Property]'s known values, as well as an [_UNKNOWN] member.
+ *
+ * An instance of [Property] can contain an unknown value in a couple of cases:
+ * - It was deserialized from data that doesn't match any known member. For example,
+ * if the SDK is on an older version than the API, then the API may respond with
+ * new members that the SDK is unaware of.
+ * - It was constructed with an arbitrary value using the [of] method.
+ */
+ enum class Value {
+ TASK_TYPE,
+ RISK_LEVEL,
+ RISK_TOTAL_SCORE,
+ NAME,
+ OWNER_ID,
+ MODEL_TYPES,
+ /**
+ * An enum member indicating that [Property] was instantiated with an unknown
+ * value.
+ */
+ _UNKNOWN,
+ }
+
+ /**
+ * Returns an enum member corresponding to this class instance's value, or
+ * [Value._UNKNOWN] if the class was instantiated with an unknown value.
+ *
+ * Use the [known] method instead if you're certain the value is always known or if
+ * you want to throw for the unknown case.
+ */
+ fun value(): Value =
+ when (this) {
+ TASK_TYPE -> Value.TASK_TYPE
+ RISK_LEVEL -> Value.RISK_LEVEL
+ RISK_TOTAL_SCORE -> Value.RISK_TOTAL_SCORE
+ NAME -> Value.NAME
+ OWNER_ID -> Value.OWNER_ID
+ MODEL_TYPES -> Value.MODEL_TYPES
+ else -> Value._UNKNOWN
+ }
+
+ /**
+ * Returns an enum member corresponding to this class instance's value.
+ *
+ * Use the [value] method instead if you're uncertain the value is always known and
+ * don't want to throw for the unknown case.
+ *
+ * @throws OpenlayerInvalidDataException if this class instance's value is a not a
+ * known member.
+ */
+ fun known(): Known =
+ when (this) {
+ TASK_TYPE -> Known.TASK_TYPE
+ RISK_LEVEL -> Known.RISK_LEVEL
+ RISK_TOTAL_SCORE -> Known.RISK_TOTAL_SCORE
+ NAME -> Known.NAME
+ OWNER_ID -> Known.OWNER_ID
+ MODEL_TYPES -> Known.MODEL_TYPES
+ else -> throw OpenlayerInvalidDataException("Unknown Property: $value")
+ }
+
+ /**
+ * Returns this class instance's primitive wire representation.
+ *
+ * This differs from the [toString] method because that method is primarily for
+ * debugging and generally doesn't throw.
+ *
+ * @throws OpenlayerInvalidDataException if this class instance's value does not
+ * have the expected primitive type.
+ */
+ fun asString(): String =
+ _value().asString().orElseThrow {
+ OpenlayerInvalidDataException("Value is not a String")
+ }
+
+ private var validated: Boolean = false
+
+ /**
+ * Validates that the types of all values in this object match their expected types
+ * recursively.
+ *
+ * This method is _not_ forwards compatible with new types from the API for existing
+ * fields.
+ *
+ * @throws OpenlayerInvalidDataException if any value type in this object doesn't
+ * match its expected type.
+ */
+ fun validate(): Property = apply {
+ if (validated) {
+ return@apply
+ }
+
+ known()
+ validated = true
+ }
+
+ fun isValid(): Boolean =
+ try {
+ validate()
+ true
+ } catch (e: OpenlayerInvalidDataException) {
+ false
+ }
+
+ /**
+ * Returns a score indicating how many valid values are contained in this object
+ * recursively.
+ *
+ * Used for best match union deserialization.
+ */
+ @JvmSynthetic internal fun validity(): Int = if (value() == Value._UNKNOWN) 0 else 1
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) {
+ return true
+ }
+
+ return other is Property && value == other.value
+ }
+
+ override fun hashCode() = value.hashCode()
+
+ override fun toString() = value.toString()
+ }
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) {
+ return true
+ }
+
+ return other is Match &&
+ property == other.property &&
+ value == other.value &&
+ operator == other.operator &&
+ additionalProperties == other.additionalProperties
+ }
+
+ private val hashCode: Int by lazy {
+ Objects.hash(property, value, operator, additionalProperties)
+ }
+
+ override fun hashCode(): Int = hashCode
+
+ override fun toString() =
+ "Match{property=$property, value=$value, operator=$operator, additionalProperties=$additionalProperties}"
+ }
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) {
+ return true
+ }
+
+ return other is ProjectSelector &&
+ match == other.match &&
+ additionalProperties == other.additionalProperties
+ }
+
+ private val hashCode: Int by lazy { Objects.hash(match, additionalProperties) }
+
+ override fun hashCode(): Int = hashCode
+
+ override fun toString() =
+ "ProjectSelector{match=$match, additionalProperties=$additionalProperties}"
+ }
+
+ override fun equals(other: Any?): Boolean {
+ if (this === other) {
+ return true
+ }
+
+ return other is FrameworkCreateParams &&
+ workspaceId == other.workspaceId &&
+ body == other.body &&
+ additionalHeaders == other.additionalHeaders &&
+ additionalQueryParams == other.additionalQueryParams
+ }
+
+ override fun hashCode(): Int =
+ Objects.hash(workspaceId, body, additionalHeaders, additionalQueryParams)
+
+ override fun toString() =
+ "FrameworkCreateParams{workspaceId=$workspaceId, body=$body, additionalHeaders=$additionalHeaders, additionalQueryParams=$additionalQueryParams}"
+}
diff --git a/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/frameworks/FrameworkCreateResponse.kt b/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/frameworks/FrameworkCreateResponse.kt
new file mode 100644
index 00000000..96800cca
--- /dev/null
+++ b/openlayer-java-core/src/main/kotlin/com/openlayer/api/models/governance/frameworks/FrameworkCreateResponse.kt
@@ -0,0 +1,2923 @@
+// File generated from our OpenAPI spec by Stainless.
+
+package com.openlayer.api.models.governance.frameworks
+
+import com.fasterxml.jackson.annotation.JsonAnyGetter
+import com.fasterxml.jackson.annotation.JsonAnySetter
+import com.fasterxml.jackson.annotation.JsonCreator
+import com.fasterxml.jackson.annotation.JsonProperty
+import com.openlayer.api.core.Enum
+import com.openlayer.api.core.ExcludeMissing
+import com.openlayer.api.core.JsonField
+import com.openlayer.api.core.JsonMissing
+import com.openlayer.api.core.JsonValue
+import com.openlayer.api.core.checkKnown
+import com.openlayer.api.core.checkRequired
+import com.openlayer.api.core.toImmutable
+import com.openlayer.api.errors.OpenlayerInvalidDataException
+import java.time.OffsetDateTime
+import java.util.Collections
+import java.util.Objects
+import java.util.Optional
+import kotlin.jvm.optionals.getOrNull
+
+class FrameworkCreateResponse
+@JsonCreator(mode = JsonCreator.Mode.DISABLED)
+private constructor(
+ private val id: JsonField,
+ private val dateCreated: JsonField,
+ private val dateUpdated: JsonField,
+ private val enabled: JsonField,
+ private val name: JsonField,
+ private val tags: JsonField>,
+ private val workspaceId: JsonField,
+ private val avatar: JsonField,
+ private val builtInSlug: JsonField,
+ private val creatorId: JsonField,
+ private val description: JsonField,
+ private val extendedDescription: JsonField,
+ private val href: JsonField,
+ private val immutable: JsonField,
+ private val projectSelector: JsonField,
+ private val ruleStats: JsonField,
+ private val additionalProperties: MutableMap,
+) {
+
+ @JsonCreator
+ private constructor(
+ @JsonProperty("id") @ExcludeMissing id: JsonField = JsonMissing.of(),
+ @JsonProperty("dateCreated")
+ @ExcludeMissing
+ dateCreated: JsonField = JsonMissing.of(),
+ @JsonProperty("dateUpdated")
+ @ExcludeMissing
+ dateUpdated: JsonField = JsonMissing.of(),
+ @JsonProperty("enabled") @ExcludeMissing enabled: JsonField = JsonMissing.of(),
+ @JsonProperty("name") @ExcludeMissing name: JsonField = JsonMissing.of(),
+ @JsonProperty("tags") @ExcludeMissing tags: JsonField> = JsonMissing.of(),
+ @JsonProperty("workspaceId")
+ @ExcludeMissing
+ workspaceId: JsonField = JsonMissing.of(),
+ @JsonProperty("avatar") @ExcludeMissing avatar: JsonField = JsonMissing.of(),
+ @JsonProperty("builtInSlug")
+ @ExcludeMissing
+ builtInSlug: JsonField = JsonMissing.of(),
+ @JsonProperty("creatorId") @ExcludeMissing creatorId: JsonField = JsonMissing.of(),
+ @JsonProperty("description")
+ @ExcludeMissing
+ description: JsonField = JsonMissing.of(),
+ @JsonProperty("extendedDescription")
+ @ExcludeMissing
+ extendedDescription: JsonField = JsonMissing.of(),
+ @JsonProperty("href") @ExcludeMissing href: JsonField = JsonMissing.of(),
+ @JsonProperty("immutable") @ExcludeMissing immutable: JsonField = JsonMissing.of(),
+ @JsonProperty("projectSelector")
+ @ExcludeMissing
+ projectSelector: JsonField = JsonMissing.of(),
+ @JsonProperty("ruleStats")
+ @ExcludeMissing
+ ruleStats: JsonField = JsonMissing.of(),
+ ) : this(
+ id,
+ dateCreated,
+ dateUpdated,
+ enabled,
+ name,
+ tags,
+ workspaceId,
+ avatar,
+ builtInSlug,
+ creatorId,
+ description,
+ extendedDescription,
+ href,
+ immutable,
+ projectSelector,
+ ruleStats,
+ mutableMapOf(),
+ )
+
+ /**
+ * The framework id.
+ *
+ * @throws OpenlayerInvalidDataException if the JSON field has an unexpected type or is
+ * unexpectedly missing or null (e.g. if the server responded with an unexpected value).
+ */
+ fun id(): String = id.getRequired("id")
+
+ /**
+ * The creation date.
+ *
+ * @throws OpenlayerInvalidDataException if the JSON field has an unexpected type or is
+ * unexpectedly missing or null (e.g. if the server responded with an unexpected value).
+ */
+ fun dateCreated(): OffsetDateTime = dateCreated.getRequired("dateCreated")
+
+ /**
+ * The last update date.
+ *
+ * @throws OpenlayerInvalidDataException if the JSON field has an unexpected type or is
+ * unexpectedly missing or null (e.g. if the server responded with an unexpected value).
+ */
+ fun dateUpdated(): OffsetDateTime = dateUpdated.getRequired("dateUpdated")
+
+ /**
+ * Whether the framework is active. Rules of a disabled framework are not evaluated and do not
+ * count towards compliance.
+ *
+ * @throws OpenlayerInvalidDataException if the JSON field has an unexpected type or is
+ * unexpectedly missing or null (e.g. if the server responded with an unexpected value).
+ */
+ fun enabled(): Boolean = enabled.getRequired("enabled")
+
+ /**
+ * The framework name.
+ *
+ * @throws OpenlayerInvalidDataException if the JSON field has an unexpected type or is
+ * unexpectedly missing or null (e.g. if the server responded with an unexpected value).
+ */
+ fun name(): String = name.getRequired("name")
+
+ /**
+ * Free-form labels on the framework.
+ *
+ * @throws OpenlayerInvalidDataException if the JSON field has an unexpected type or is
+ * unexpectedly missing or null (e.g. if the server responded with an unexpected value).
+ */
+ fun tags(): List = tags.getRequired("tags")
+
+ /**
+ * The id of the workspace the framework belongs to.
+ *
+ * @throws OpenlayerInvalidDataException if the JSON field has an unexpected type or is
+ * unexpectedly missing or null (e.g. if the server responded with an unexpected value).
+ */
+ fun workspaceId(): String = workspaceId.getRequired("workspaceId")
+
+ /**
+ * The icon shown for the framework.
+ *
+ * @throws OpenlayerInvalidDataException if the JSON field has an unexpected type (e.g. if the
+ * server responded with an unexpected value).
+ */
+ fun avatar(): Optional = avatar.getOptional("avatar")
+
+ /**
+ * Identifies a framework that ships with Openlayer, for example `eu_ai_act`, `iso_42001`,
+ * `nist_ai_rmf`, or `traiga`. `null` for frameworks you create yourself.
+ *
+ * @throws OpenlayerInvalidDataException if the JSON field has an unexpected type (e.g. if the
+ * server responded with an unexpected value).
+ */
+ fun builtInSlug(): Optional = builtInSlug.getOptional("builtInSlug")
+
+ /**
+ * The user who created the framework. `null` for built-in frameworks.
+ *
+ * @throws OpenlayerInvalidDataException if the JSON field has an unexpected type (e.g. if the
+ * server responded with an unexpected value).
+ */
+ fun creatorId(): Optional = creatorId.getOptional("creatorId")
+
+ /**
+ * A short description of the framework.
+ *
+ * @throws OpenlayerInvalidDataException if the JSON field has an unexpected type (e.g. if the
+ * server responded with an unexpected value).
+ */
+ fun description(): Optional = description.getOptional("description")
+
+ /**
+ * A longer, rich-text description, as a TipTap JSON document.
+ *
+ * @throws OpenlayerInvalidDataException if the JSON field has an unexpected type (e.g. if the
+ * server responded with an unexpected value).
+ */
+ fun extendedDescription(): Optional =
+ extendedDescription.getOptional("extendedDescription")
+
+ /**
+ * A link to the external standard or regulation the framework is based on.
+ *
+ * @throws OpenlayerInvalidDataException if the JSON field has an unexpected type (e.g. if the
+ * server responded with an unexpected value).
+ */
+ fun href(): Optional = href.getOptional("href")
+
+ /**
+ * Whether the framework definition is managed by Openlayer and cannot be edited.
+ *
+ * @throws OpenlayerInvalidDataException if the JSON field has an unexpected type (e.g. if the
+ * server responded with an unexpected value).
+ */
+ fun immutable(): Optional = immutable.getOptional("immutable")
+
+ /**
+ * Determines which projects the framework applies to. An empty or `null` `match` array applies
+ * the framework to every project in the workspace.
+ *
+ * @throws OpenlayerInvalidDataException if the JSON field has an unexpected type (e.g. if the
+ * server responded with an unexpected value).
+ */
+ fun projectSelector(): Optional =
+ projectSelector.getOptional("projectSelector")
+
+ /**
+ * Compliance roll-up for the framework. Present only on `GET
+ * /workspaces/{workspaceId}/frameworks` when the request sets `includeRuleStats=true`.
+ *
+ * @throws OpenlayerInvalidDataException if the JSON field has an unexpected type (e.g. if the
+ * server responded with an unexpected value).
+ */
+ fun ruleStats(): Optional = ruleStats.getOptional("ruleStats")
+
+ /**
+ * Returns the raw JSON value of [id].
+ *
+ * Unlike [id], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("id") @ExcludeMissing fun _id(): JsonField = id
+
+ /**
+ * Returns the raw JSON value of [dateCreated].
+ *
+ * Unlike [dateCreated], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("dateCreated")
+ @ExcludeMissing
+ fun _dateCreated(): JsonField = dateCreated
+
+ /**
+ * Returns the raw JSON value of [dateUpdated].
+ *
+ * Unlike [dateUpdated], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("dateUpdated")
+ @ExcludeMissing
+ fun _dateUpdated(): JsonField = dateUpdated
+
+ /**
+ * Returns the raw JSON value of [enabled].
+ *
+ * Unlike [enabled], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("enabled") @ExcludeMissing fun _enabled(): JsonField = enabled
+
+ /**
+ * Returns the raw JSON value of [name].
+ *
+ * Unlike [name], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("name") @ExcludeMissing fun _name(): JsonField = name
+
+ /**
+ * Returns the raw JSON value of [tags].
+ *
+ * Unlike [tags], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("tags") @ExcludeMissing fun _tags(): JsonField> = tags
+
+ /**
+ * Returns the raw JSON value of [workspaceId].
+ *
+ * Unlike [workspaceId], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("workspaceId") @ExcludeMissing fun _workspaceId(): JsonField = workspaceId
+
+ /**
+ * Returns the raw JSON value of [avatar].
+ *
+ * Unlike [avatar], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("avatar") @ExcludeMissing fun _avatar(): JsonField = avatar
+
+ /**
+ * Returns the raw JSON value of [builtInSlug].
+ *
+ * Unlike [builtInSlug], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("builtInSlug") @ExcludeMissing fun _builtInSlug(): JsonField = builtInSlug
+
+ /**
+ * Returns the raw JSON value of [creatorId].
+ *
+ * Unlike [creatorId], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("creatorId") @ExcludeMissing fun _creatorId(): JsonField = creatorId
+
+ /**
+ * Returns the raw JSON value of [description].
+ *
+ * Unlike [description], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("description") @ExcludeMissing fun _description(): JsonField = description
+
+ /**
+ * Returns the raw JSON value of [extendedDescription].
+ *
+ * Unlike [extendedDescription], this method doesn't throw if the JSON field has an unexpected
+ * type.
+ */
+ @JsonProperty("extendedDescription")
+ @ExcludeMissing
+ fun _extendedDescription(): JsonField = extendedDescription
+
+ /**
+ * Returns the raw JSON value of [href].
+ *
+ * Unlike [href], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("href") @ExcludeMissing fun _href(): JsonField = href
+
+ /**
+ * Returns the raw JSON value of [immutable].
+ *
+ * Unlike [immutable], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("immutable") @ExcludeMissing fun _immutable(): JsonField = immutable
+
+ /**
+ * Returns the raw JSON value of [projectSelector].
+ *
+ * Unlike [projectSelector], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("projectSelector")
+ @ExcludeMissing
+ fun _projectSelector(): JsonField = projectSelector
+
+ /**
+ * Returns the raw JSON value of [ruleStats].
+ *
+ * Unlike [ruleStats], this method doesn't throw if the JSON field has an unexpected type.
+ */
+ @JsonProperty("ruleStats") @ExcludeMissing fun _ruleStats(): JsonField = ruleStats
+
+ @JsonAnySetter
+ private fun putAdditionalProperty(key: String, value: JsonValue) {
+ additionalProperties.put(key, value)
+ }
+
+ @JsonAnyGetter
+ @ExcludeMissing
+ fun _additionalProperties(): Map =
+ Collections.unmodifiableMap(additionalProperties)
+
+ fun toBuilder() = Builder().from(this)
+
+ companion object {
+
+ /**
+ * Returns a mutable builder for constructing an instance of [FrameworkCreateResponse].
+ *
+ * The following fields are required:
+ * ```java
+ * .id()
+ * .dateCreated()
+ * .dateUpdated()
+ * .enabled()
+ * .name()
+ * .tags()
+ * .workspaceId()
+ * ```
+ */
+ @JvmStatic fun builder() = Builder()
+ }
+
+ /** A builder for [FrameworkCreateResponse]. */
+ class Builder internal constructor() {
+
+ private var id: JsonField? = null
+ private var dateCreated: JsonField? = null
+ private var dateUpdated: JsonField? = null
+ private var enabled: JsonField? = null
+ private var name: JsonField? = null
+ private var tags: JsonField>? = null
+ private var workspaceId: JsonField? = null
+ private var avatar: JsonField